最近一直忙其它的(实际上是懒!),将《深刻理解Yii2》看了一遍,一些当初没明白的稍微明了了点,而后又看yii2的图片上传等处理、富文本、restful什么的,但因为没进行到这里,只看也无论用啊,因此仍是按照步骤一步步来,先说说先后台分离。(其实普通的内容管理站点用不着下面所说的完全分离什么的,看看也无妨)php
我的感受先后台的状况有这么几种,首先是先后台是不是用一个验证体系,其次是先后台是否共用一个数据表。通常来讲下面三种比较经常使用吧:html
A、共用一个验证体系和一个数据表。mysql
B、两个验证体系和共用一个数据表。linux
C、两个验证体系和两个数据表。web
Yii2高级版里面默认是A类型,即数据表同样,且一边登陆/登出了,另外一边也一样登陆/登出,感受这种结构比较适用于论坛这种,管理员也须要有与会员同样发帖回帖等功能,表字段也基本一致,(我的这样认为,毕竟接触的很少,网上也搜过不一样的后台构建的话题,可是不多有详细讨论的),这种能够经过字段、权限等来区分先后台。而咱们将要作的是C类型,像是一些电商网站,后台的管理员和前台的会员功能就相差太大了,且表字段差异也大,因此验证体系不同,并且放两个数据表比较好。至于B类型算是C类型的简化版,C若是会设置的话,B也同理。sql
那咱们先创建一个admin表,用来存放管理员数据,而会员仍然用原有的user表,这里用yii的migrate来建立,在Yii2初始化章节中有提到过,这里稍微详细说下:数据库
一、yii2版本2.07之前用命令,便可在console/migrations目录下建立一个php文件,而后在此文件下编写建立表语句等等就能够了。windows
yii migrate/create admin
二、yii2版本2.07后,增长了更细致的分类,例如我已经建立了admin表,但少了一个status字段,那我能够直接用下面命令便会生成只增长字段的文件api
yii migrate/create add_column_to_admin --fields=status:int(10):nontNull
生成:restful
<?php use yii\db\Migration; class m160501_053640_add_column_to_admin extends Migration { public function up() { $this->addColumn('admin', 'status', $this->int(10)->nontNull()); } public function down() { $this->dropColumn('admin', 'status'); } }
具体为何会这样,咱们看下原代码,在vendor/yiisoft/yii2/console/BaseMigrateController.php文件的actionCreate方法中:
... } elseif (preg_match('/^add_(.+)_to_(.+)$/', $name, $matches)) { $content = $this->renderFile(Yii::getAlias($this->generatorTemplateFiles['add_column']), [ 'className' => $className, 'table' => mb_strtolower($matches[2], Yii::$app->charset), 'fields' => $this->fields ]); } ...
咱们能够看到,这里是正则匹配add_xxx_to_xxx来肯定具体是指向哪一个模板,从而生成不一样的样式。因此根据migrate/create后面的参数总共匹配这几种样式:
一、create_junction_表名_and_表名,用来建立联结表
二、add_xxx_to_表名,用来增长字段(能够用--fields样式指定一个字段,不然生成空的,须要本身写,固然也能够改模板添加个注释示例)
三、drop_xxx_from_表名,用来删除字段(同上)
四、create_表名,用来建立表
五、drop_表名,用来删除表
注:能够直接在控制台用yii help migrate来查看更多的用法
2.09版本这里又有改动,全部的都要以"_table"结尾才能被正确匹配,例如原先是"yii migrate/create create_category",如今必须是"yii migrate/create create_category_table"这样,这里说明下,上面就不一一修改了,
模板文件能够在vendor/yiisoft/yii2/views中找到对应的,若是想更改模板,让其更适合本身的操做,能够这样:
在console文件中新建views文件夹,将上方的你想修改的模板复制到这里来修改,而后再console/config/main.php中修改
return [ //修改migration模板 'controllerMap' => [ 'migrate' => [ 'class' => 'yii\console\controllers\MigrateController', 'templateFile'=>'@yii/views/migration.php',//默认模板,2.07后应该不多用了 'generatorTemplateFiles' => [ 'create_table' => '@console/views/createTableMigration.php',//修改的 'drop_table' => '@yii/views/dropTableMigration.php',//未修改的 'add_column' => '@console/views/addColumnMigration.php',//修改的 'drop_column' => '@console/views/dropColumnMigration.php',//修改的 'create_junction' => '@yii/views/createJunctionMigration.php'//未修改的 ], ], ], ];
值得注意的是generatorTemplateFiles配置中,必须将这5个都写全了,若是不修改,则写原来的路径,原来的路径可在vendor/yiisoft/yii2/console/MigrateController.php中查看,不然你用到没写的那个命令模板的时候就会报错。
至于如何写具体的建立表、添加字段等语句,其实也有版本不一样(2.06新写法)的两种写法,这里就不要看中文版的没有更新的yii2指南了,直接看英文更新的,点这里,里面包含上面说的内容加具体的写法。当初费了不少时间google搜索、顺着源码看才搞明白上面说的原理,后来一看,在人家英文版里都写了,悲剧,并且最近我在Yii英文官网api文档搜索任何关键字都不出现结果了,不知道是这边的问题仍是官网问题,只能对照着中文指南和英文指南看究竟是对应的哪一块。因此说若是英语更好点就行了,直接看英文文档。
目前本身修改了create_table时加表注释、段注释(这个搜索及查源码没找到相似->comment的写法,多是为了兼容其它数据库,因此只能拼接,而写段注释的好处是,gii 生成model时attributeLabels方法能够直接根据注释来显示对应的中文名字),add_column和drop_column模板增长一个示例注释,方便忘了用法时参照注释的示例来写,并且这样就不用加--fileds参数了。呃,这里贴一下本身的模板和最终应该创建的admin表的语句吧:
模板createTableMigration.php:
<?php /** * This view is used by console/controllers/MigrateController.php * The following variables are available in this view: */ /* @var $className string the new migration class name */ /* @var $table string the name table */ /* @var $fields array the fields */ echo "<?php\n"; ?> use yii\db\Migration; class <?= $className ?> extends Migration { const TBL_NAME = '{{%<?=$table?>}}'; public function up() { $tableOptions = null; if ($this->db->driverName === 'mysql') { $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB COMMENT="填写表注释"'; } $this->createTable(self::TBL_NAME, [ <?php foreach ($fields as $field): ?> <?php if ($field == end($fields)): ?> '<?= $field['property'] ?>' => $this-><?= $field['decorators'].".\" COMMENT '填写段注释'\"" . "\n"?> <?php else: ?> '<?= $field['property'] ?>' => $this-><?= $field['decorators'].".\" COMMENT '填写段注释'\"" . ",\n"?> <?php endif; ?> <?php endforeach; ?> ],$tableOptions); } public function down() { $this->dropTable(self::TBL_NAME); } }
具体语句m160326_133655_create_admin.php:
<?php use yii\db\Migration; class m160427_133556_create_admin extends Migration { const TBL_NAME = '{{%admin}}'; public function up() { $tableOptions = null; if ($this->db->driverName === 'mysql') { $tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB COMMENT="后台管理员表"'; } $this->createTable(self::TBL_NAME, [ 'id' => $this->primaryKey(), 'username'=>$this->string()->notNull()->unique()." COMMENT '用户名'", 'auth_key'=>$this->string(32)->notNull()." COMMENT '认证Key'", 'password_hash'=>$this->string()->notNull()." COMMENT '密码'", 'password_reset_token'=>$this->string()->unique()." COMMENT '密码重置Token'", 'email'=>$this->string()->notNull()->unique()." COMMENT '邮箱'", 'status'=>$this->smallInteger()->notNull()->defaultValue(10)." COMMENT '状态'", 'created_at' => $this->integer()->notNull()." COMMENT '建立时间'", 'updated_at' => $this->integer()->notNull()." COMMENT '更新时间'", ],$tableOptions); } public function down() { $this->dropTable(self::TBL_NAME); } }
继续运行下述命令行代码,便可生成admin表,因为只是作演示,因此admin和user表基本同样,不要在乎这些细节。
yii migrate
好了,生成两个表后,咱们就须要将前台登陆和后台登录完全分开了:
一、前台修改:因为已经不公用了,因此先把公用的common/models中的User.php和LoginForm.php移动到frontend/models中去,顺便将这两个文件的命名空间改成以frontend开头,将整个前台文件看一遍,把全部涉及到这两个common文件命名空间的须要都改成前台本身的命名空间。
二、后台修改:一样须要在backend/models中有这两个文件Admin.php和LoginForm.php,可使用Gii生成(须要注意要继承IdentityInterface,实现此接口内的方法以及参照User.php来实现相关登陆注册方法),也能够直接复制一样上面的两个文件(须要将User.php更名为Admin.php,且注意user表和admin表字段名称或个数是否一致,不一致则须要在Admin.php中修改)。因为咱们原先建立事后台的GRUD,因此这里改动挺多的(searchModel,controller,view都须要改为admin的),建议对照着Gii生成的文件预览来改。哎,若是实际要先后台分离,本章应该放在第五章节的前面,那后台就不须要改这么多了。
如今能够登陆先后台试试,等等,咱们后台表虽然建立好了,可是尚未添加管理员,如今因为后台已经登录不进去了,因此在后台内也没法建立了,而且注册功能也没有(这种分离下,后台通常不必有注册功能),因此这里继续用console的功能来建立一个用户,控制台的功能挺多的,不只仅是数据库管理,能够点这里了解下。
在console/controllers中新建InitController,而后以下代码:
<?php /** * Application initialization * 参照深刻理解Yii2.0视频教程 */ namespace console\controllers; use backend\models\Admin; class InitController extends \yii\console\Controller { /** * Create init admin */ public function actionAdmin() { echo "Create init admin ...\n"; // 提示当前操做 $username = $this->prompt('Admin Name:'); // 接收用户名 $email = $this->prompt('Email:'); // 接收Email $password = $this->prompt('Password:'); // 接收密码 $model = new Admin(); // 建立一个新用户 $model->username = $username; // 完成赋值 $model->email = $email; $model->password = $password;//注意这个地方,用了Admin模型中的setPassword方法(魔术方法__set) if (!$model->save()) // 保存新的用户 { foreach ($model->getErrors() as $error) // 若是保存失败,说明有错误,那就输出错误信息。 { foreach ($error as $e) { echo "$e\n"; } } return 1; // 命令行返回1表示有异常 } return 0; // 返回0表示一切OK } } InitController.php
而后再命令行中运行:
yii init/admin
按照提示来填写用户名密码等,即可以产生一条数据了,当咱们查看这条记录时,发现咱们填写的明文密码变成加密的了,而建立时间和更新和更新时间咱们没填写也自动给填写了,前者是因为用了__set魔术方法,后者是用了“行为”,若是不是很理解请看《深刻理解Yii2.0》,里面讲的比较详细。还有就是,可能在window下cmd运行中文乱码,大致搜了下没找到好的解决方法,不过能够试下Cygwin这个windows下能够运行linux命令的软件,挺好用的,设置成utf-8就不会乱码了,并且能够用gcc什么的。
三、如今咱们先后台都能按照本身数据库里的数据来登陆了,可是因为session等公用一个,因此仍是退出时,先后台一块儿退出,须要进一步操做:能够参照这篇wiki。
后台,在backend/config/main.php或者main-local.php中
'components' => [ 'user' => [ 'identityClass' => 'backend\models\Admin', 'enableAutoLogin' => true, 'identityCookie' => [ 'name' => '_backendUser', // unique for backend ], ], 'session' => [ 'name' => 'PHPBACKSESSID', 'savePath' => sys_get_temp_dir(), ], 'request' => [ 'cookieValidationKey' => 'orGkZNZvZe3-4WicYHyGMS-EyI6Tp8yi',//random string 'csrfParam' => '_backendCSRF', ], ...
一样在前台,在frontend/config/main.php或者main-local.php中
'components' => [ 'user' => [ 'identityClass' => 'frontend\models\User', 'enableAutoLogin' => true, 'identityCookie' => [ 'name' => '_frontendUser', // unique for frontend ] ], 'session' => [ 'name' => 'PHPFRONTSESSID', 'savePath' => sys_get_temp_dir(), ], 'request' => [ 'cookieValidationKey' => '8rqO22WJ9yiAx_KuJ8SFnbKctqGDWi9J', 'csrfParam' => '_frontendCSRF', ], ...
这样再登录试下,就会发现先后台彻底没关联了。能够调用Yii::$app的功能,例如Yii::$app->user->id,若是是在后台的目录中,会显示后台的用户id,若是是在前台的目录中则会显示前台的用户id。可能有些强迫症患者想同Yii1那样用Yii::$app->admin->id来访问后台用户id,这个不太好实现,Yii2和Yii1相比,用户验证这块改动挺大的,web/User在Yii2框架中做为核心组件,若是要修改的话应该还要关联修改web/Application中的变量方法等,我的感受不必。
以上,就是所说的,其实还有不少已经集成好的yii2-user、带权限控制等的插件能够直接从composer中搜索使用。例如点击率最高的这个,能够配置B类型的验证,并且集成了更多功能。(我的只是大致看了下,没下载使用呢还)