Yii2前後台分離及migrate使用(七)_php執行個體

來源:互聯網
上載者:User

最近一直忙其它的(其實是懶!),將《深入理解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

產生:

<?phpuse 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:

<?phpuse 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類型的驗證,而且整合了更多功能。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.