Yii2前后台分离及migrate使用(七)

最近一直忙其它的(其实是懒!),将《深入理解Yii2》看了一遍,一些当初没明白的稍微明了了点,然后又看yii2的图片上传等处理、富文本、restful什么的,但由于没进行到这里,只看也不管用啊,所以还是按照步骤一步步来,先说说前后台分离。(其实普通的内容管理站点用不着下面所说的彻底分离什么的,看看也无妨)

个人感觉前后台的情况有这么几种,首先是前后台是否是用一个验证体系,其次是前后台是否共用一个数据表。

一般来说下面三种比较常用吧:

A、共用一个验证体系和一个数据表。

B、两个验证体系和共用一个数据表。

C、两个验证体系和两个数据表。

Yii2高级版里面默认是A类型,即数据表一样,且一边登录/登出了,另一边也同样登录/登出,感觉这种结构比较适用于论坛这种,管理员也需要有与会员一样发帖回帖等功能,表字段也基本一致,(个人这样认为,毕竟接触的不多,网上也搜过不同的后台构建的话题,但是很少有详细讨论的),这种可以通过字段、权限等来区分前后台。而我们将要做的是C类型,像是一些电商网站,后台的管理员和前台的会员功能就相差太大了,且表字段差别也大,所以验证体系不一样,而且放两个数据表比较好。至于B类型算是C类型的简化版,C如果会设置的话,B也同理。

那我们先建立一个admin表,用来存放管理员数据,而会员仍然用原有的user表,这里用yii的migrate来创建,在Yii2初始化章节中有提到过,这里稍微详细说下:

1、yii2版本2.07以前用命令,即可在console/migrations目录下创建一个php文件,然后在此文件下编写创建表语句等等就可以了。

yii migrate/create admin

2、yii2版本2.07后,增加了更细致的分类,例如我已经创建了admin表,但少了一个status字段,那我可以直接用下面命令便会生成只增加字段的文件

yii migrate/create add_column_to_admin --fields=status:int(10):nontNull

生成:

<?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后面的参数总共匹配这几种样式:

1、create_junction_表名_and_表名,用来创建联结表

2、add_xxx_to_表名,用来增加字段(可以用--fields样式指定一个字段,否则生成空的,需要自己写,当然也可以改模板添加个注释示例)

3、drop_xxx_from_表名,用来删除字段(同上)

4、create_表名,用来创建表

5、drop_表名,用来删除表

注:可以直接在控制台用yii help migrate来查看更多的用法

模板文件可以在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

好了,生成两个表后,我们就需要将前台登录和后台登陆彻底分开了:

1、前台修改:由于已经不公用了,所以先把公用的common/models中的User.php和LoginForm.php移动到frontend/models中去,顺便将这两个文件的命名空间改为以frontend开头,将整个前台文件看一遍,把所有涉及到这两个common文件命名空间的需要都改为前台自己的命名空间。

2、后台修改:同样需要在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什么的。

3、现在我们前后台都能按照自己数据库里的数据来登录了,但是由于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类型的验证,而且集成了更多功能。

(0)

相关推荐

  • Yii2使用swiftmailer发送邮件的方法

    本文实例讲述了Yii2使用swiftmailer发送邮件的方法.分享给大家供大家参考,具体如下: 'mail' => [ 'class' => 'yii\swiftmailer\Mailer', 'viewPath' => '@backend/mail', 'useFileTransport' => false,//set this property to false to send mails to real email addresses //comment the follo

  • Yii2 输出xml格式数据的方法

    php中对xml的处理,虽然说实际开发中目前用的少了,但是难免会用到,用到的时候呢,总结起来还是稍稍有那么一丁点的麻烦. 我们来看看yii2中是怎么对xml进行处理的.会超乎你想象的简单哦. 我们以输出xml格式的数据为例. 既然是输出,必然就涉及到web请求与响应了,不熟悉的可以先去了解下HTTP协议. yii2中支持以下几种返回格式,均可自定义配置. HTML: implemented by yii\web\HtmlResponseFormatter. XML: implemented by

  • Yii2超好用的日期和时间组件(值得收藏)

    日期组件,时间组件在平时开发中是必不可少的.今天我们就来谈谈在yii2中的超好用的时间组件,也省的大家各种找js插件了. 分享之前我们先预览下效果,看看到底怎么个好用法. 当然啦,好用不好用在于自我的感觉,光看上面的图片是感受不到的.再告诉你个好消息,这两款插件已经跟yii2整合了,使用起来也是灰常的简单哦. 关于日期组件跟时间组件,前者是date('Y-m-d')类型,后者是date('Y-m-d H:i:s')类型,自然不用多说. 我们先来看看时间组件扩展 既然是扩展组建,第一步当然是安装.

  • Yii2中如何使用modal弹窗(基本使用)

    Modal也即是模态窗,通俗的说就是弹窗.是一款bootstrap的js插件,使用效果也是非常好. 为什么要使用modal就不必多说了,一个网站,在开发过程中你说你没用过js弹窗我都不信!好的弹窗不仅仅给人以美感,也会让我们开发效率提高,甚至心情也会舒畅! 我们看看在yii2中如何使用modal. 比如我们之前添加数据的时候,通常情况下会点击按钮跳转到添加页面,保存后再跳转到列表页. 现在我们希望点击添加按钮的时候,在当前页面弹窗添加数据,看具体实现. 1.use yii\bootstrap\M

  • Yii2 rbac权限控制操作步骤实例教程

    本篇的主题是 rbac权限控制的详细操作步骤,注意是操作步骤哦,关于配置与rbac的搭建,我们在yii2搭建完美后台并实现rbac权限控制实例教程说的再清楚不过了. 但是,在很多人的反馈下,说是完全按照本主的步骤来的,丝毫不差,为啥菜单不显示,为啥不显示呢不显示?艾玛,最终在群里帮人调试的时候找到原因了,si分的不容易啊.原因就是你学会了搭建没学会操作啊,啊,啊,我们今天就来详细的说说这rbac的权限控制具体怎么操作!当然,大前提下是你已经按照我们上文成功搭建一套完美的后台并实现了rbac权限控

  • Yii2前后台分离及migrate使用(七)

    最近一直忙其它的(其实是懒!),将<深入理解Yii2>看了一遍,一些当初没明白的稍微明了了点,然后又看yii2的图片上传等处理.富文本.restful什么的,但由于没进行到这里,只看也不管用啊,所以还是按照步骤一步步来,先说说前后台分离.(其实普通的内容管理站点用不着下面所说的彻底分离什么的,看看也无妨) 个人感觉前后台的情况有这么几种,首先是前后台是否是用一个验证体系,其次是前后台是否共用一个数据表. 一般来说下面三种比较常用吧: A.共用一个验证体系和一个数据表. B.两个验证体系和共用一

  • Laravel 5.4前后台分离,通过不同的二级域名访问方法

    第一步:添加app\http\Controllers文件夹里面创建我们要存放前端和后端或者接口的文件夹 列如: Home(前端) Admin(后端) App(接口) 文件夹 第二步:修改app\http\providers\RouteServiceProvider.php <?php namespace App\Providers; use Illuminate\Support\Facades\Route; use Illuminate\Foundation\Support\Providers\

  • mysql主从复制读写分离的配置方法详解

    一.说明 前面我们说了mysql的安装配置,mysql语句使用以及备份恢复mysql数据;本次要介绍的是mysql的主从复制,读写分离;及高可用MHA; 环境如下: master:CentOS7_x64 mysql5.721 172.16.3.175 db1 slave1:CentOS7_x64 mysql5.7.21 172.16.3.235 db2 slave2:CentOS7_x64 mysql5.7.21 172.16.3.235 db3 proxysql/MHA:CentOS7_x64

  • Python django中如何使用restful框架

    在使用django进行前后台分离开发时通常会搭配django-rest-framework框架创建RESTful风格的接口API.框架介绍及版本要求可参考官方地址:https://www.django-rest-framework.org 本文以创建man包含name.sex字段的API为实例学习django-rest-framework框架的使用. 主要包含下面5个步骤: 1.创建Django项目 2.创建ORM模型 3.加载Django REST Framework 4.序列化模型 5.创建

  • Vue.js使用v-show和v-if的注意事项

    关于两者的区别,官网是这样说的: 在切换 v-if 块时,Vue.js 有一个局部编译/卸载过程,因为 v-if 之中的模板也可能包括数据绑定或子组件.v-if 是真实的条件渲染,因为它会确保条件块在切换当中合适地销毁与重建条件块内的事件监听器和子组件. v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做--在条件第一次变为真时才开始局部编译(编译会被缓存起来). 相比之下,v-show 简单得多--元素始终被编译并保留,只是简单地基于 CSS 切换. 一般来说,v-if 有更高的切换

  • vue 运用mock数据的示例代码

    本文介绍了vue 运用mock数据的示例代码,分享给大家,具体如下: 初始化你的项目 话不用啰嗦,首先初始化你的项目,最简单的就是使用vue-cli啦 vue init webpack 引入mock.js 安装 mockjs npm install --save-dev mockjs 引入到Vue原型上,方便使用 import mockjs from 'mockjs' Vue.prototype.$mock = Vue.$mock = mockjs.mock 以上引入到Vue原型上,可以使用 t

  • php中常用编辑器推荐

    eWebEditor除了具有前台的调用功能外,还具有很强的后台管理功能,能够对编辑器多种功能进行各种有效的自定义,具体如下: Excel工作表导入(V4.3)eWebEditor最新提供Excel工作表导入解决方案,支持Excel中图片.图表的导入并自动上传到服务器.并提供了是否使用VML格式的导入选项,如不使用VML格式,则在导入时图表将自动生成图片,并自动上传到服务器.大大方便了利用Excel办公文档发布的需要. Word文档导入及本地文件自动上传(V4.0)eWebEditor最新提供Wo

  • 使用nodejs中httpProxy代理时候出现404异常的解决方法

    在公司中使用nodejs构建代理服务器实现前后台分离,代码不能拿出来,然后出现httpProxy代理资源的时候老是出现404.明明被代理的接口是存在的.代码大概如下: var http = require('http'), httpProxy = require('http-proxy'); var proxy = httpProxy.createProxyServer({}); var server = http.createServer(function(req, res) { proxy.

  • 详解服务端预渲染之Nuxt(介绍篇)

    现在前端开发一般都是前后端分离,mvvm和mvc的开发框架,如Angular.React和Vue等,虽然写框架能够使我们快速的完成开发,但是由于前后台分离,给项目SEO带来很大的不便,搜索引擎在检索的时候是在网页中爬取数据,由于单页面应用读取到的页面是几乎空白的,无法爬取到任何数据信息. <!DOCTYPE html> <html> <head> <meta charset=utf-8> <meta name=viewport content=&quo

  • Linux脚本自动打包发服务

    适用于前后台分离的服务 一个jar包 一个前台工程 实现自动杀端口,复制文件,备份数据,发布新版本. 脚本复制到Linux中 [./jb.sh]按Enter运行即可 内容如下: #自定义存放的地方 #文件存放的根目录 latestDir=/home/xnj #jar包名字 jarName=swWeb.jar #前端压缩包文件名 qdZipName=Desktop.zip #前端tomcat的位置 qdTomcatPosition=/home/tomcat/apache-tomcat-8.5.43

随机推荐