CentOS7安装ffmpeg以及第三方依赖

序、简介

FFmpeg

  • 一个完整的跨平台解决方案,用于记录、转换和流化传输音频和视频的工具
  • 文档:https://www.ffmpeg.org/documentation.html
  • 官方网站:https://www.ffmpeg.org

这里记录 CentOS7 系统结合部分第三方依赖来源码编译安装 FFMPEG

在私人目录下创建一个新目录,将所有源代码放入:

1mkdir ~/ffmpeg_sources

一、NASM

NASM(The Netwide Assembler),是一款基于 80×86 和 x86-64 平台的汇编语言编译程序,其设计初衷是为了实现编译器程序跨平台和模块化的特性。NASM支持大量文件格式,包括 Linux,*BSM,a.out,ELF,COFF,Mach-O,Microsoft 16-bit OBJ,Win32 以及 Win64,同时也支持简单的二进制文件生成。

有两种方法:源码编译安装 或者 系统安装

系统安装:

这种方法需要联网状态,但是安装的 NSAM 可能会显示版本太低

sudo yum install nsam -y

源码编译安装:

cd ~/ffmpeg_sources
curl -O -L https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.bz2
tar -xjvf nasm-2.14.02.tar.bz2
cd nasm-2.14.02
./autogen.sh
./configure –prefix=”$HOME/ffmpeg_build” –bindir=”$HOME/bin”
make
make install

二、YASM(基于NASM,故装这个最好先装NASM)

YASM 是一个完全重写的 NASM 汇编,基于 NASM 开发的,有较好的优化,对于 NASM 中一些不合理的地方进行了修改。目前,支持 x86 和 AMD64 指令集。

有两种方法:源码编译安装 或者 系统安装

系统安装:

同样必须要联网状态,但是安装的 YASM 可能会显示版本太低,也有一个好处,就是顺便将YASM的依赖也一起安装了

sudo yum install yasm -y

源码编译安装:

cd ~/ffmpeg_sources
curl -O -L http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
tar -zxvf yasm-1.3.0.tar.gz
cd yasm-1.3.0
./configure –prefix=”$HOME/ffmpeg_build” –bindir=”$HOME/bin”
make
make install

三、libx264

x264 是一款免费的用于编码 H.264/MPEG-4 AVC 格式的视音频码流库。

官方网站:https://www.videolan.org/developers/x264.html

源码安装:libx264

cd ~/ffmpeg_sources
 git clone –depth 1 http://git.videolan.org/git/x264cd x264 (or) wget http://download.videolan.org/pub/videolan/x264/snapshots/last_x264.tar.bz2
tar -jxf last_x264.tar.bz2
cd x264-snapshot-20190530-2245-stable PKG_CONFIG_PATH=”$HOME/ffmpeg_build/lib/pkgconfig”
./configure –prefix=”$HOME/ffmpeg_build” –bindir=”$HOME/bin” –enable-static
make
make install

四、libx265

x265 是一款免费的用于编码 H.265/MPEG-H HEVC 格式的视音频码流库。

官方网站:https://www.videolan.org/developers/x265.html

源码安装:libx265

cd ~/ffmpeg_sources
 hg clone https://bitbucket.org/multicoreware/x265cd x265/build/linux(or)wget http://download.videolan.org/pub/videolan/x265/x265_3.0.tar.gz
tar -xvf x265_3.0.tar.gzcd x265_3.0/build/linux 
cmake -G “Unix Makefiles” -DCMAKE_INSTALL_PREFIX=”$HOME/ffmpeg_build” -DENABLE_SHARED:bool=off ../../source(or)./make-Makefiles.bash[ press “enter” motidy params & press C and press G ] makemake install

五、libfdk_acc

Fraunhofer FDK AAC(libfdk_acc),是一款不会提供在已编译的 FFMPEG 可执行包中的第三方依赖库,用于 AAC-LC 编码 和 HE-AAC(v1/2) 编码。所以需要在FFMPEG中加入相关包重编译。

源码安装:libfdk_aac

cd ~/ffmpeg_sources
git clone –depth 1 https://github.com/mstorsjo/fdk-aaccd fdk-aacautoreconf -fiv./configure –prefix=”$HOME/ffmpeg_build” –disable-sharedmakemake install

六、libmp3lame

LAME 是一款免费的+最好的 MP3 编码器,编码高品质 MP3 的最好也是唯一的选择。

源码安装:libmp3lame

cd ~/ffmpeg_sourcescurl -O -L http://downloads.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gztar -zxvf lame-3.100.tar.gzcd lame-3.100./configure –prefix=”$HOME/ffmpeg_build” –bindir=”$HOME/bin” –disable-shared –enable-nasmmakemake install

七、libopus

Opus 是一种声音编码格式。其前身是 celt 编码器。在当今的有损音频格式中,拥有众多不同编码器的 AAC 格式打败了颇有潜力的 Musepack、Vorbis 等格式。在低码率下 Opus 完胜 HE-AAC。

源码安装:libopus

cd ~/ffmpeg_sourcescurl -O -L https://ftp.osuosl.org/pub/xiph/releases/opus/opus-1.3.1.tar.gztar -zxvf opus-1.3.1.tar.gzcd opus-1.3.1./configure –prefix=”$HOME/ffmpeg_build” –disable-sharedmakemake install

八、libogg

Ogg(oggVorbis) 是一种音频压缩格式,类似于 MP3 等音乐格式。Ogg是完全免费、开放、没有专利限制的。其文件拓展名为”.ogg”。

源码安装:libogg

cd ~/ffmpeg_sourcescurl -O -L https://ftp.osuosl.org/pub/xiph/releases/ogg/libogg-1.3.3.tar.gzcd libogg-1.3.3./configure –prefix=”$HOME/ffmpeg_build” –disable-sharedmakemake install

九、libvorbis

同为为 FFMPEG 提供 oggVorbis 文件格式的压缩编码。

源码安装:libvorbis

cd ~/ffmpeg_sourcescurl -O -L https://ftp.osuosl.org/pub/xiph/releases/vorbis/libvorbis-1.3.6.tar.gztar -zxvf libvorbis-1.3.6.tar.gzcd libvorbis-1.3.6./configure –prefix=”$HOME/ffmpeg_build” –with-ogg=”$HOME/ffmpeg_build” –disable-sharedmakemake install

十、speex

Speex 是一款开源免费的、无专利保护的、针对语音设计的音频压缩格式。Speex 编解码器已经被 Opus 编解码器淘汰,但还是可以继续使用。虽然 Opus 比 Speex 好,但 Opus 只支持编码和解码,不支持噪音抑制、声学回音消除等其他处理功能。

(这里并没有将Speex加入FFMPEG编译中,但可以支持的)

cd ~/ffmpeg_sourcescurl -O -L https://ftp.osuosl.org/pub/xiph/releases/speex/speex-1.2.0.tar.gz

十一、libvpx

libvpx 是一款开源的 VP8 编码解码器。为 FFMPEG 提供 VP8 编码解码的支持。如编码YUV->VP8(On2 VP8)。

源码安装:libvpx

cd ~/ffmpeg_sourceswget https://github.com/webmproject/libvpx/archive/v1.7.0.tar.gztar -zxvf v1.7.0.tar.gzmv libvpx-1.7.0 libvpxcd libvpx./configure –prefix=”$HOME/ffmpeg_build” –with-ogg=”$HOME/ffmpeg_build” –disable-sharedmakemake install

十二、FFmpeg

cd ~/ffmpeg_sourcescurl -O -L https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2tar -xjvf ffmpeg-snapshot.tar.bz2cd ffmpegPATH=”$HOME/bin:$PATH” PKG_CONFIG_PATH=”$HOME/ffmpeg_build/lib/pkgconfig” ./configure \  –prefix=”$HOME/ffmpeg_build” \  –pkg-config-flags=”–static” \  –extra-cflags=”-I$HOME/ffmpeg_build/include” \  –extra-ldflags=”-L$HOME/ffmpeg_build/lib” \  –extra-libs=-lpthread \  –extra-libs=-lm \  –bindir=”$HOME/bin” \  –enable-gpl \  –enable-libfdk_aac \  –enable-libfreetype \  –enable-libmp3lame \  –enable-libopus \  –enable-libvorbis \  –enable-libvpx \  –enable-libx264 \  –enable-libx265 \  –enable-nonfreemake -j8make install

CENTOS7 GNOME 安装中文支持

网上的文章都是互相抄的,很多都不适用。这个亲测成功了。

先安装字体

yum  groupinstall  “fonts”

然后按照以下步骤:

1、查看当前显示格式及编码

echo $LANG	//一般默认显示为en_US.UTF-8

2、查看是否安装中文字体

locale -a | grep 'zh_CN*' //查看是否有zh_CN.UTF-8

3、安装中文字体(如果没有)

yum install kde-l10n-Chinese

4、修改配置文件

vi /etc/locale.conf	//修改配置文件

内容为:

LANG=“ZH_CN.utf-8”

保存

5、修改启动文件

由于系统重启后会自动加载该文件,会覆盖掉配置文件

vi /etc /etc/profile.d/lang.sh

内容为:

修改为:

这样重启后不会失效

6、重启linux

reboot

Yii2 basic, authorization and registration via the database

A simple example of fine-tuning Yii2 basic for authorization via the database, adding registration and resetting the password.

原文地址: https://devreadwrite.com/posts/yii2-basic-authorization-and-registration-via-the-database

To begin with, yii2 basic must already be installed. How to do this is described here: Short instruction. How to install Yii 2 basic.

Configure the connection to the database in the file /config/db.php and proceed.

Add authorization on the site in Yii2 basic

Open the console and add the migration to create the User table

yii migrate/create create_user_table

Open the file with the migration /migration/m000000_000000_create_user_table.php and add the code for creating the migration, we will not reinvent the wheel, and we will do the same as in the version advanced:

<?php use yii\db\Migration; class m000000_000000_create_user_table extends Migration{     public function up()    {        $tableOptions = null;         if ($this->db->driverName === 'mysql') {            $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE=InnoDB';        }         $this->createTable('user', [            'id' => $this->primaryKey(),            'username' => $this->string()->notNull()->unique(),            'auth_key' => $this->string(32)->notNull(),            'password_hash' => $this->string()->notNull(),            'password_reset_token' => $this->string()->unique(),            'email' => $this->string()->notNull()->unique(),            'status' => $this->smallInteger()->notNull()->defaultValue(10),            'created_at' => $this->integer()->notNull(),            'updated_at' => $this->integer()->notNull(),        ], $tableOptions);    }     public function down()    {        $this->dropTable('user');    } }

After saving the edits in the migration file (copy only the methods code up() and down()), execute it in the console:

yii migrate

Edit model /models/User.php:

<?php namespace app\models; use Yii;use yii\base\NotSupportedException;use yii\behaviors\TimestampBehavior;use yii\db\ActiveRecord;use yii\web\IdentityInterface; /** * User model * * @property integer $id * @property string $username * @property string $password_hash * @property string $password_reset_token * @property string $email * @property string $auth_key * @property integer $status * @property integer $created_at * @property integer $updated_at * @property string $password write-only password */class User extends ActiveRecord implements IdentityInterface{    const STATUS_DELETED = 0;    const STATUS_ACTIVE = 10;     /**     * @inheritdoc     */    public static function tableName()    {        return '{{%user}}';    }     /**     * @inheritdoc     */    public function behaviors()    {        return [            TimestampBehavior::className(),        ];    }     /**     * @inheritdoc     */    public function rules()    {        return [            ['status', 'default', 'value' => self::STATUS_ACTIVE],            ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],        ];    }     /**     * @inheritdoc     */    public static function findIdentity($id)    {        return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);    }     /**     * @inheritdoc     */    public static function findIdentityByAccessToken($token, $type = null)    {        throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');    }     /**     * Finds user by username     *     * @param string $username     * @return static|null     */    public static function findByUsername($username)    {        return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);    }     /**     * @inheritdoc     */    public function getId()    {        return $this->getPrimaryKey();    }     /**     * @inheritdoc     */    public function getAuthKey()    {        return $this->auth_key;    }     /**     * @inheritdoc     */    public function validateAuthKey($authKey)    {        return $this->getAuthKey() === $authKey;    }     /**     * Validates password     *     * @param string $password password to validate     * @return bool if password provided is valid for current user     */    public function validatePassword($password)    {        return Yii::$app->security->validatePassword($password, $this->password_hash);    }     /**     * Generates password hash from password and sets it to the model     *     * @param string $password     */    public function setPassword($password)    {        $this->password_hash = Yii::$app->security->generatePasswordHash($password);    }     /**     * Generates "remember me" authentication key     */    public function generateAuthKey()    {        $this->auth_key = Yii::$app->security->generateRandomString();    } }

Authorization is ready, now we will add a user to check authorization. Open the controller /controllers/SiteController.php and add the action to the end of the controller which will help us add the user:

public function actionAddAdmin() {    $model = User::find()->where(['username' => 'admin'])->one();    if (empty($model)) {        $user = new User();        $user->username = 'admin';        $user->email = 'admin@devreadwrite.com';        $user->setPassword('admin');        $user->generateAuthKey();        if ($user->save()) {            echo 'good';        }    }}

Run the action: site.com/web/index.php?r=site/add-admin and check the authorization site.com/web/index.php?r=site/login

After successful authorization, the AddAdmin action can be deleted as a useless item.

If you only need authorization via a database in Yii2 basic, then you can end this. If in addition to authorizing through the database on the site you need to add registration and password recovery, then continue.

Add registration to the site in Yii2 basic

First, create a model for the registration forms, for this you need to create a file /models/SignupForm.php with the following content:

<?ph namespace app\models; use Yii;use yii\base\Model; /** * Signup form */class SignupForm extends Model{     public $username;    public $email;    public $password;     /**     * @inheritdoc     */    public function rules()    {        return [            ['username', 'trim'],            ['username', 'required'],            ['username', 'unique', 'targetClass' => '\app\models\User', 'message' => 'This username has already been taken.'],            ['username', 'string', 'min' => 2, 'max' => 255],            ['email', 'trim'],            ['email', 'required'],            ['email', 'email'],            ['email', 'string', 'max' => 255],            ['email', 'unique', 'targetClass' => '\app\models\User', 'message' => 'This email address has already been taken.'],            ['password', 'required'],            ['password', 'string', 'min' => 6],        ];    }     /**     * Signs user up.     *     * @return User|null the saved model or null if saving fails     */    public function signup()    {         if (!$this->validate()) {            return null;        }         $user = new User();        $user->username = $this->username;        $user->email = $this->email;        $user->setPassword($this->password);        $user->generateAuthKey();        return $user->save() ? $user : null;    } }

Next, in /controllers/SiteController.php in use, add registration model SignupForm and action signup:

<?php namespace app\controllers; //... use app\models\LoginForm;use app\models\ContactForm;use app\models\SignupForm; class SiteController extends Controller{     //...     public function actionSignup()    {        $model = new SignupForm();         if ($model->load(Yii::$app->request->post())) {            if ($user = $model->signup()) {                if (Yii::$app->getUser()->login($user)) {                    return $this->goHome();                }            }        }         return $this->render('signup', [            'model' => $model,        ]);    } }

Next, you need to add a view for registration, add a file /views/site/signup.php with the following content:

<?php use yii\helpers\Html;use yii\bootstrap\ActiveForm; $this->title = 'Signup';$this->params['breadcrumbs'][] = $this->title;?><div class="site-signup">    <h1><?= Html::encode($this->title) ?></h1>    <p>Please fill out the following fields to signup:</p>    <div class="row">        <div class="col-lg-5">             <?php $form = ActiveForm::begin(['id' => 'form-signup']); ?>                <?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>                <?= $form->field($model, 'email') ?>                <?= $form->field($model, 'password')->passwordInput() ?>                <div class="form-group">                    <?= Html::submitButton('Signup', ['class' => 'btn btn-primary', 'name' => 'signup-button']) ?>                </div>            <?php ActiveForm::end(); ?>         </div>    </div></div>

And the last thing you need to do is add registration to the menu. Open the file /views/layouts/main.php find the menu widget and add the registration item, after which the widget with the following form:

<?php NavBar::begin([    'brandLabel' => 'My Company',    'brandUrl' => Yii::$app->homeUrl,    'options' => [        'class' => 'navbar-inverse navbar-fixed-top',    ],]); echo Nav::widget([    'options' => ['class' => 'navbar-nav navbar-right'],    'items' => [        ['label' => 'Home', 'url' => ['/site/index']],        ['label' => 'About', 'url' => ['/site/about']],        ['label' => 'Contact', 'url' => ['/site/contact']],        Yii::$app->user->isGuest ? (            ['label' => 'Login', 'url' => ['/site/login']]        ) : (            '<li>'            . Html::beginForm(['/site/logout'], 'post')            . Html::submitButton(                'Logout (' . Yii::$app->user->identity->username . ')',                ['class' => 'btn btn-link logout']            )            . Html::endForm()            . '</li>'        )    ],]); NavBar::end();?>

Full code:

<?php NavBar::begin([    'brandLabel' => 'My Company',    'brandUrl' => Yii::$app->homeUrl,    'options' => [        'class' => 'navbar-inverse navbar-fixed-top',    ],]); $menuItems = [    ['label' => 'Home', 'url' => ['/site/index']],    ['label' => 'About', 'url' => ['/site/about']],    ['label' => 'Contact', 'url' => ['/site/contact']],]; if (Yii::$app->user->isGuest) {    $menuItems[] = ['label' => 'Signup', 'url' => ['/site/signup']];    $menuItems[] = ['label' => 'Login', 'url' => ['/site/login']];} else {    $menuItems[] = '<li>'        . Html::beginForm(['/site/logout'], 'post')        . Html::submitButton(            'Logout (' . Yii::$app->user->identity->username . ')',            ['class' => 'btn btn-link logout']        )        . Html::endForm()        . '</li>';} echo Nav::widget([    'options' => ['class' => 'navbar-nav navbar-right'],    'items' => $menuItems,]); NavBar::end();?>

Now we have registration and authorization in Yii2 basic.

For full functionality only need to do reset and password recovery.

Add password recovery on the site in Yii2 basic

First, you need to modify the /models/User.php model and add several methods to create and reset the token of password:

public static function findByPasswordResetToken($token){    if (!static::isPasswordResetTokenValid($token)) {        return null;    }    return static::findOne([        'password_reset_token' => $token,        'status' => self::STATUS_ACTIVE,    ]);}public static function isPasswordResetTokenValid($token){    if (empty($token)) {        return false;    }    $timestamp = (int) substr($token, strrpos($token, '_') + 1);    $expire = Yii::$app->params['user.passwordResetTokenExpire'];    return $timestamp + $expire >= time();}public function generatePasswordResetToken(){    $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();}public function removePasswordResetToken(){    $this->password_reset_token = null;}

As a result, the model /models/User.php will look like this:

<?php namespace app\models; use Yii;use yii\base\NotSupportedException;use yii\behaviors\TimestampBehavior;use yii\db\ActiveRecord;use yii\web\IdentityInterface; class User extends ActiveRecord implements IdentityInterface{    const STATUS_DELETED = 0;    const STATUS_ACTIVE = 10;     public static function tableName()    {        return '{{%user}}';    }     public function behaviors()    {        return [            TimestampBehavior::className(),        ];    }     public function rules()    {        return [            ['status', 'default', 'value' => self::STATUS_ACTIVE],            ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],        ];    }     public static function findIdentity($id)    {        return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);    }     public static function findIdentityByAccessToken($token, $type = null)    {        throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');    }     public static function findByUsername($username)    {        return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);    }     public static function findByPasswordResetToken($token)    {         if (!static::isPasswordResetTokenValid($token)) {            return null;        }         return static::findOne([            'password_reset_token' => $token,            'status' => self::STATUS_ACTIVE,        ]);    }     public static function isPasswordResetTokenValid($token)    {         if (empty($token)) {            return false;        }         $timestamp = (int) substr($token, strrpos($token, '_') + 1);        $expire = Yii::$app->params['user.passwordResetTokenExpire'];        return $timestamp + $expire >= time();    }     public function getId()    {        return $this->getPrimaryKey();    }     public function getAuthKey()    {        return $this->auth_key;    }     public function validateAuthKey($authKey)    {        return $this->getAuthKey() === $authKey;    }     public function validatePassword($password)    {        return Yii::$app->security->validatePassword($password, $this->password_hash);    }     public function setPassword($password)    {        $this->password_hash = Yii::$app->security->generatePasswordHash($password);    }     public function generateAuthKey()    {        $this->auth_key = Yii::$app->security->generateRandomString();    }     public function generatePasswordResetToken()    {        $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();    }     public function removePasswordResetToken()    {        $this->password_reset_token = null;    } }

The method of checking token of password reset isPasswordResetTokenValid uses the variable user.passwordResetTokenExpire to reset password token, it must be specified in the file /congif/params.php:

<?phpreturn [    'adminEmail' => 'admin@example.com',    'user.passwordResetTokenExpire' => 3600,];

Next, you must add the request form model to change the password and the password change form model. Total 2 models. First, we’ll add the model of the request form to change the password /models/PasswordResetRequestForm.php with the following content:

<?php namespace app\models; use Yii;use yii\base\Model; /** * Password reset request form */class PasswordResetRequestForm extends Model{    public $email;     /**     * @inheritdoc     */    public function rules()    {        return [            ['email', 'trim'],            ['email', 'required'],            ['email', 'email'],            ['email', 'exist',                'targetClass' => '\app\models\User',                'filter' => ['status' => User::STATUS_ACTIVE],                'message' => 'There is no user with such email.'            ],        ];    }     /**     * Sends an email with a link, for resetting the password.     *     * @return bool whether the email was send     */    public function sendEmail()    {        /* @var $user User */        $user = User::findOne([            'status' => User::STATUS_ACTIVE,            'email' => $this->email,        ]);         if (!$user) {            return false;        }         if (!User::isPasswordResetTokenValid($user->password_reset_token)) {            $user->generatePasswordResetToken();            if (!$user->save()) {                return false;            }        }         return Yii::$app            ->mailer            ->compose(                ['html' => 'passwordResetToken-html', 'text' => 'passwordResetToken-text'],                ['user' => $user]            )            ->setFrom([Yii::$app->params['supportEmail'] => Yii::$app->name . ' robot'])            ->setTo($this->email)            ->setSubject('Password reset for ' . Yii::$app->name)            ->send();    } }

The model will send a confirmation to email for the password change. For this, it uses 2 layouts (html and text), we already have html, we need to add text. To do this, create a file /mail/layouts/text.php With the following content:

<?phpuse yii\helpers\Html;?><?php $this->beginPage() ?><?php $this->beginBody() ?><?= $content ?><?php $this->endBody() ?><?php $this->endPage() ?>

Also it is necessary to create 2 representations of the letter (html and text version). We will create an html version of the mail view, for this we create a file /mail/passwordResetToken-html.php with the following content:

<?php use yii\helpers\Html; $resetLink = Yii::$app->urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]);?> <div class="password-reset">    <p>Hello <?= Html::encode($user->username) ?>,</p>    <p>Follow the link below to reset your password:</p>    <p><?= Html::a(Html::encode($resetLink), $resetLink) ?></p></div>

And the view for text version /mail/passwordResetToken-text.php:

<?php$resetLink = Yii::$app->urlManager->createAbsoluteUrl(['site/reset-password', 'token' => $user->password_reset_token]);?>Hello <?= $user->username ?>,Follow the link below to reset your password:<?= $resetLink ?>

Model indicate as sender of e-mail from the parameter supportEmail, it must also be added. To do this, open the file /config/params.php for editing and add the element supportEmail to the array, you will end up with the following:

<?php return [    'adminEmail' => 'admin@devreadwrite.com',    'user.passwordResetTokenExpire' => 3600,    'supportEmail' => 'robot@devreadwrite.com'];

Next, the model for the form of password change /models/ResetPasswordForm.php with the following content:

<?php namespace app\models; use yii\base\Model;use yii\base\InvalidParamException; /** * Password reset form */class ResetPasswordForm extends Model{     public $password;     /**     * @var \app\models\User     */    private $_user;     /**     * Creates a form model given a token.     *     * @param string $token     * @param array $config name-value pairs that will be used to initialize the object properties     * @throws \yii\base\InvalidParamException if token is empty or not valid     */    public function __construct($token, $config = [])    {        if (empty($token) || !is_string($token)) {            throw new InvalidParamException('Password reset token cannot be blank.');        }         $this->_user = User::findByPasswordResetToken($token);         if (!$this->_user) {            throw new InvalidParamException('Wrong password reset token.');        }         parent::__construct($config);    }     /**     * @inheritdoc     */    public function rules()    {        return [            ['password', 'required'],            ['password', 'string', 'min' => 6],        ];    }     /**     * Resets password.     *     * @return bool if password was reset.     */    public function resetPassword()    {        $user = $this->_user;        $user->setPassword($this->password);        $user->removePasswordResetToken();        return $user->save(false);    } }

Now we add actions to work with the models described above. Open the controller /controllers/SiteController.php in use add the created models and 2 actions (actionRequestPasswordReset and actionResetPassword):

<?php namespace app\controllers; //... use app\models\SignupForm;use app\models\PasswordResetRequestForm;use app\models\ResetPasswordForm; class SiteController extends Controller{     //...     /**     * Requests password reset.     *     * @return mixed     */    public function actionRequestPasswordReset()    {        $model = new PasswordResetRequestForm();         if ($model->load(Yii::$app->request->post()) && $model->validate()) {             if ($model->sendEmail()) {                Yii::$app->session->setFlash('success', 'Check your email for further instructions.');                return $this->goHome();            } else {                Yii::$app->session->setFlash('error', 'Sorry, we are unable to reset password for email provided.');            }         }         return $this->render('requestPasswordResetToken', [            'model' => $model,        ]);    }     /**     * Resets password.     *     * @param string $token     * @return mixed     * @throws BadRequestHttpException     */    public function actionResetPassword($token)    {        try {            $model = new ResetPasswordForm($token);        } catch (InvalidParamException $e) {            throw new BadRequestHttpException($e->getMessage());        }         if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) {            Yii::$app->session->setFlash('success', 'New password was saved.');            return $this->goHome();        }         return $this->render('resetPassword', [            'model' => $model,      } }

Next, for these two actions, you need to add views, start with the request form to change the password /views/site/passwordResetRequestForm.php:

<?php use yii\helpers\Html;use yii\bootstrap\ActiveForm; $this->title = 'Request password reset';$this->params['breadcrumbs'][] = $this->title;?> <div class="site-request-password-reset">    <h1><?= Html::encode($this->title) ?></h1>    <p>Please fill out your email. A link to reset password will be sent there.</p>    <div class="row">        <div class="col-lg-5">             <?php $form = ActiveForm::begin(['id' => 'request-password-reset-form']); ?>                <?= $form->field($model, 'email')->textInput(['autofocus' => true]) ?>                <div class="form-group">                    <?= Html::submitButton('Send', ['class' => 'btn btn-primary']) ?>                </div>            <?php ActiveForm::end(); ?>         </div>    </div></div>

And the view for the password change form /views/site/resetPasswordForm.php:

<?php use yii\helpers\Html;use yii\bootstrap\ActiveForm; $this->title = 'Reset password';$this->params['breadcrumbs'][] = $this->title;?> <div class="site-reset-password">    <h1><?= Html::encode($this->title) ?></h1>    <p>Please choose your new password:</p>    <div class="row">        <div class="col-lg-5">             <?php $form = ActiveForm::begin(['id' => 'reset-password-form']); ?>                <?= $form->field($model, 'password')->passwordInput(['autofocus' => true]) ?>                <div class="form-group">                    <?= Html::submitButton('Save', ['class' => 'btn btn-primary']) ?>                </div>            <?php ActiveForm::end(); ?>         </div>    </div></div>

The final touch, add a link to reset the password in the authorization form view, to do this, open the file /views/site/login.php add a link to reset password:

<div>    If you forgot your password you can <?= Html::a('reset it', ['site/request-password-reset']) ?>.</div>

As a result, the view of authorization on the site will look like this:

<?php use yii\helpers\Html;use yii\bootstrap\ActiveForm; $this->title = 'Login';$this->params['breadcrumbs'][] = $this->title;?> <div class="site-login">    <h1><?= Html::encode($this->title) ?></h1>    <p>Please fill out the following fields to login:</p>     <?php $form = ActiveForm::begin([        'id' => 'login-form',        'layout' => 'horizontal',        'fieldConfig' => [            'template' => "{label}\n<div class=\"col-lg-3\">{input}</div>\n<div class=\"col-lg-8\">{error}</div>",            'labelOptions' => ['class' => 'col-lg-1 control-label'],        ],    ]); ?>        <?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?>        <?= $form->field($model, 'password')->passwordInput() ?>        <?= $form->field($model, 'rememberMe')->checkbox([            'template' => "<div class=\"col-lg-offset-1 col-lg-3\">{input} {label}</div>\n<div class=\"col-lg-8\">{error}</div>",        ]) ?>        <div style="color:#999;margin:1em 0">            If you forgot your password you can <?= Html::a('reset it', ['site/request-password-reset']) ?>.        </div>        <div class="form-group">            <div class="col-lg-offset-1 col-lg-11">                <?= Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?>            </div>        </div>    <?php ActiveForm::end(); ?> </div>

As a result, we got a full functionality of authorization through the database, registration and reset of password in Yii2 basic using the functionality of the template of Yii2 advanced.

Authorization in Yii2 by e-mail instead of username

For authorization on the site, I prefer using the user’s e-mail as a login instead of a nickname, by default, yii2 uses a nickname as the login. To fix this is quite simple.

Let’s start with the /models/User.php model and add the findByEmail method to search for the user by e-mail:

public static function findByEmail($email){    return static::findOne(['email' => $email, 'status' => self::STATUS_ACTIVE]);}

Next, in the model /models/LoginForm.php change the $username property to $email in the rules method, add e-mail handling of rule [[’email’], ’email’] and in the getUser () method, change the User::findByUsername($this->username) to User::findByEmail($this->email), this is what you get:

<?php namespace app\models; use Yii;use yii\base\Model; /** * LoginForm is the model behind the login form. * * @property User|null $user This property is read-only. * */class LoginForm extends Model{    public $email;    public $password;    public $rememberMe = true;    private $_user = false;     /**     * @return array the validation rules.     */    public function rules()    {        return [            // username and password are both required            [['email', 'password'], 'required'],            [['email'], 'email'],            // rememberMe must be a boolean value            ['rememberMe', 'boolean'],            // password is validated by validatePassword()            ['password', 'validatePassword'],        ];    }     /**     * Validates the password.     * This method serves as the inline validation for password.     *     * @param string $attribute the attribute currently being validated     * @param array $params the additional name-value pairs given in the rule     */    public function validatePassword($attribute, $params)    {         if (!$this->hasErrors()) {             $user = $this->getUser();             if (!$user || !$user->validatePassword($this->password)) {                $this->addError($attribute, 'Incorrect username or password.');            }         }     }     /**     * Logs in a user using the provided username and password.     * @return bool whether the user is logged in successfully     */    public function login()    {        if ($this->validate()) {            return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0);        }        return false;    }     /**     * Finds user by [[email]]     *     * @return User|null     */    public function getUser()    {        if ($this->_user === false) {            $this->_user = User::findByEmail($this->email);        }        return $this->_user;    } }

Finally, in the /views/site/login.php view, change the username field to email:

<?= $form->field($model, 'email')->textInput(['autofocus' => true]) ?>

All source code is available on github: https://github.com/egor/yii2-basic-auth-through-db.

Article source: https://кодер.укр/записи/yii2-basic-авторизация-и-регистрация-через-бд.