yii結(jié)構(gòu)
用MVC設(shè)計(jì)模式來組織,模型(model)表示數(shù)據(jù)格式、業(yè)務(wù)邏輯、規(guī)則等,視圖(view)輸出展示模型,就是可以被用戶在頁面看到的東西,控制器(controller)負(fù)責(zé)接收用戶從前端傳來的請求,處理用戶請求(比如從數(shù)據(jù)庫讀出數(shù)據(jù)并返回)等。
yii的其他部分
入口腳本:終端(服務(wù)所部署的地方)能直接訪問的php腳本,負(fù)責(zé)啟動一個(gè)請求處理。
應(yīng)用:能全局范圍內(nèi)訪問的對象,它由不同的應(yīng)用組件組成,這些組件互相協(xié)調(diào)合作處理完成用戶的請求。
應(yīng)用組件:在應(yīng)用中注冊,提供不同的功能。
模塊:包含完整的MVC結(jié)構(gòu)的獨(dú)立包,一個(gè)應(yīng)用可以由多個(gè)模塊組成,這個(gè)模塊可以很容易地被復(fù)用。
過濾器:在控制器處理請求前或請求后會觸發(fā)執(zhí)行的代碼,比如:在處理請求前驗(yàn)證一些非法參數(shù)。
入口腳本干的事
1、定義全局常量
YII_DEBUG:值true/false,true表示在調(diào)試模式下,日志信息比較詳細(xì),如果拋出異常,頁面會報(bào)出詳細(xì)的錯(cuò)誤堆棧信息,在開發(fā)階段開啟,部署到線上環(huán)境后建議關(guān)閉。
YII_ENV:應(yīng)用運(yùn)行的環(huán)境,默認(rèn)值prod,表示線上的環(huán)境。
YII_ENABLE_ERROR_HANDLER:標(biāo)是否啟用yii提供的錯(cuò)誤處理,默認(rèn)值true.
2、注冊Compser自動加載器
使用composer可以很方便的自動加載我們依賴的第三方的文件。
3、加載Yii類文件
4、加載應(yīng)用的配置
5、用剛加載的配置信息實(shí)例化一個(gè)應(yīng)用
6、調(diào)用yii\base\Application::run() 方法處理請求
應(yīng)用主體
負(fù)載管理yii應(yīng)用系統(tǒng)的結(jié)構(gòu)、生命周期,每個(gè)yii應(yīng)用系統(tǒng)有且只有一個(gè)應(yīng)用主體,它在入口腳本中創(chuàng)建并能通過表達(dá)式Y(jié)ii::$app訪問。
應(yīng)用主體有兩種,yii\web\Application 負(fù)責(zé)處理網(wǎng)頁請求,配置文件是params.php,web.php等,yii\base\Application::basePath負(fù)責(zé)處理控制臺請求,配置文件是console.php
應(yīng)用組件
具有不同功能的應(yīng)用組件組成一個(gè)應(yīng)用主體,負(fù)載處理用戶的請求。例如,urlManager組件負(fù)責(zé)處理網(wǎng)頁請求路由到對應(yīng)的控制器。db組件提供數(shù)據(jù)庫相關(guān)服務(wù)等等。在同一個(gè)應(yīng)用中,每個(gè)應(yīng)用組件都有唯一的名稱用來區(qū)分,可以用這種方式訪問應(yīng)用組件\Yii::$app->componentID,第一次使用這種表達(dá)式時(shí)會自動創(chuàng)建應(yīng)用組件實(shí)例,后面再次訪問時(shí)會返回已經(jīng)創(chuàng)建好的實(shí)例。應(yīng)用組件可以是任意對象,可以在應(yīng)用主體配置中配置組件的屬性,栗子:
<pre>
[
//注冊的組件們
'components' => [
// 使用配置數(shù)組注冊 "db" 組件
'db' => [
'class' => 'yii\db\Connection’, //組件的類
'dsn' => 'mysql:host=localhost;dbname=demo’, //數(shù)據(jù)庫配置信息
'username' => 'root',
'password' => '',
],
]
</pre>
控制器
MVC中的controller部分,負(fù)責(zé)處理請求和生成響應(yīng)。
具體過程:當(dāng)有一個(gè)請求到來時(shí),應(yīng)用主體把請求分發(fā)給控制器,控制器分析請求數(shù)據(jù)并傳送到模型,模型處理數(shù)據(jù),并返回結(jié)果,控制器把模型返回的結(jié)果傳送到視圖,最后輸出響應(yīng)信息到頁面。
控制器由多個(gè)操作(action)組成,這些action做不同的事,栗子:在一個(gè)xyy的controller中定義一個(gè)chifan的action,命名規(guī)則必須是action+操作名稱,操作的第一個(gè)字母大寫,所以訪問xyy/chifan,就表示執(zhí)行actionChifan,可以用get/post方法把參數(shù)傳遞到這個(gè)action,在action中用$_POST、$_GET數(shù)組接收參數(shù)。
另外一種接收參數(shù)的方法:在web.php中配置路由GET xyy//chifan' => ‘xyy/chifan,定義chifan的action為:actionChifan($id),訪問url:xyy/1/chifan,這時(shí)候id=1這個(gè)參數(shù)就被傳過來了。
模型
MVC中的model,代表業(yè)務(wù)數(shù)據(jù)、規(guī)則、邏輯。
在模型中定義屬性:這些屬性像普通類的屬性、數(shù)組一樣可以被訪問,是業(yè)務(wù)數(shù)據(jù)。
模型的一些特性
屬性標(biāo)簽:通過重寫yii\base\Model的attributeLabels()方法,定義標(biāo)簽的別名,這樣在給終端用戶展示這些字段時(shí)可以展示定義的別名而不是原始的屬性名稱。栗子:
<pre>
public function attributeLabels()
{
return [
'name' => 'Your name',
'email' => 'Your email address',
'subject' => 'Subject',
'body' => 'Content',
];
}
</pre>
在給用戶提示email字段不合法時(shí),就會顯示‘Your email address’。
場景:模型可能在多個(gè)場景下使用,不同的場景下可能會有不同的業(yè)務(wù)規(guī)則和邏輯。模型使用 yii\base\Model::scenario屬性設(shè)置場景,默認(rèn)情況下支持’default’場景。通過覆蓋yii\base\Model::scenarios()來定義不同場景下的規(guī)則,栗子:
<pre>
public function scenarios()
{
return [
'login' => ['username', 'password'],
'register' => ['username', 'email', 'password'],
];
}
</pre>
表示在login場景下 username,password是必填項(xiàng),但在register場景下username,email,password是必填項(xiàng)。
驗(yàn)證規(guī)則:模型接收到來自終端的數(shù)據(jù),可以根據(jù)業(yè)務(wù)規(guī)則對數(shù)據(jù)做一些驗(yàn)證,如果沒有通過驗(yàn)證,拋出相應(yīng)的錯(cuò)誤信息。
通過重寫 yii\base\Model::rules() 方法指定模型屬性的驗(yàn)證規(guī)則,栗子:
<pre>
public function rules()
{
return [
[['name', 'email', 'subject', 'body'], 'required'], // name, email, subject 和 body 屬性必須有值
['email', 'email'], // email 屬性必須是一個(gè)有效的電子郵箱地址
];
}
</pre>
通過調(diào)用 yii\base\Model::validate() 驗(yàn)證接收到的數(shù)據(jù),這個(gè)方法使用yii\base\Model::rules() 中的規(guī)則進(jìn)行驗(yàn)證,如果驗(yàn)證通過,返回true,否則錯(cuò)誤信息保存在 yii\base\Model::errors 屬性中并返回false,栗子:
<pre>
$params = [“name”=>”xyy”,”sex”=>”girl”,”age”=>”monkey”];//設(shè)置一些參數(shù)
$model->attributes = $params;//把參數(shù)傳給model
if ($model->validate()) {
// 驗(yàn)證參數(shù)是否合法
} else {
// 驗(yàn)證失?。?errors 是一個(gè)包含錯(cuò)誤信息的數(shù)組
$errors = $model->errors;
}
</pre>
塊賦值:一次性把一個(gè)數(shù)組填充到一個(gè)模型,這個(gè)數(shù)組的key必須是模型中的屬性名稱,如果不是則會被忽略,栗子:
<pre>
$params = [“name”=>”xyy”,”sex”=>”girl”,”age”=>”monkey”];
$model->attributes = $params;//塊賦值的方法
$model->name = “xyy”;
$model->sex=“girl”;
$model->age=>”monkey”;//一個(gè)一個(gè)賦值
</pre>
這兩種填充方式效果是一樣的。
安全屬性:在使用塊賦值時(shí),被定義為安全屬性的屬性才可以被終端傳過來的數(shù)據(jù)賦值。
非安全屬性:想要給非安全屬性賦值,必須顯示地賦值,栗子:$model->name = ”xyy“;
數(shù)據(jù)導(dǎo)出:模型可能需要導(dǎo)出成不同的格式,例如把一個(gè)模型的集合轉(zhuǎn)換成json或xml,分2步,1、轉(zhuǎn)換成數(shù)組 2、把數(shù)組轉(zhuǎn)成需要的格式。
用$array = $model->attributes方法可以把$model所有的屬性保存在$array數(shù)組里。
字段:默認(rèn)情況下,字段名對應(yīng)屬性名,可以通過覆蓋yii\base\Model::fields() 和 yii\base\Model::extraFields()方法改變字段名,兩個(gè)方法都返回一個(gè)字段列表,fields() 方法定義的字段是默認(rèn)字段,當(dāng)調(diào)用模型的toArray方法會返回一個(gè)數(shù)組,數(shù)組的key就是字段名,value是字段的值。extraFields()方法定義額外可用字段,通過toArray()方法指定$expand參數(shù)來返回這些額外可用字段。栗子:
<pre>
public function fields()
{
return [
// 字段名和屬性名相同
'id',
// 字段名為 "email",對應(yīng)屬性名為 "email_address"
'email' => 'email_address',
// 字段名為 "name", 值通過PHP代碼返回
'name' => function () {
return $this->first_name . ' ' . $this->last_name;
},
];
}
</pre>