yii结构
用MVC设计模式来组织,模型(model)表示数据格式、业务逻辑、规则等,视图(view)输出展示模型,就是可以被用户在页面看到的东西,控制器(controller)负责接收用户从前端传来的请求,处理用户请求(比如从数据库读出数据并返回)等。
yii的其他部分
入口脚本:终端(服务所部署的地方)能直接访问的php脚本,负责启动一个请求处理。
应用:能全局范围内访问的对象,它由不同的应用组件组成,这些组件互相协调合作处理完成用户的请求。
应用组件:在应用中注册,提供不同的功能。
模块:包含完整的MVC结构的独立包,一个应用可以由多个模块组成,这个模块可以很容易地被复用。
过滤器:在控制器处理请求前或请求后会触发执行的代码,比如:在处理请求前验证一些非法参数。
入口脚本干的事
1、定义全局常量
YII_DEBUG:值true/false,true表示在调试模式下,日志信息比较详细,如果抛出异常,页面会报出详细的错误堆栈信息,在开发阶段开启,部署到线上环境后建议关闭。
YII_ENV:应用运行的环境,默认值prod,表示线上的环境。
YII_ENABLE_ERROR_HANDLER:标是否启用yii提供的错误处理,默认值true.
2、注册Compser自动加载器
使用composer可以很方便的自动加载我们依赖的第三方的文件。
3、加载Yii类文件
4、加载应用的配置
5、用刚加载的配置信息实例化一个应用
6、调用yii\base\Application::run() 方法处理请求
应用主体
负载管理yii应用系统的结构、生命周期,每个yii应用系统有且只有一个应用主体,它在入口脚本中创建并能通过表达式Yii::$app访问。
应用主体有两种,yii\web\Application 负责处理网页请求,配置文件是params.php,web.php等,yii\base\Application::basePath负责处理控制台请求,配置文件是console.php
应用组件
具有不同功能的应用组件组成一个应用主体,负载处理用户的请求。例如,urlManager组件负责处理网页请求路由到对应的控制器。db组件提供数据库相关服务等等。在同一个应用中,每个应用组件都有唯一的名称用来区分,可以用这种方式访问应用组件\Yii::$app->componentID,第一次使用这种表达式时会自动创建应用组件实例,后面再次访问时会返回已经创建好的实例。应用组件可以是任意对象,可以在应用主体配置中配置组件的属性,栗子:
<pre>
[
//注册的组件们
'components' => [
// 使用配置数组注册 "db" 组件
'db' => [
'class' => 'yii\db\Connection’, //组件的类
'dsn' => 'mysql:host=localhost;dbname=demo’, //数据库配置信息
'username' => 'root',
'password' => '',
],
]
</pre>
控制器
MVC中的controller部分,负责处理请求和生成响应。
具体过程:当有一个请求到来时,应用主体把请求分发给控制器,控制器分析请求数据并传送到模型,模型处理数据,并返回结果,控制器把模型返回的结果传送到视图,最后输出响应信息到页面。
控制器由多个操作(action)组成,这些action做不同的事,栗子:在一个xyy的controller中定义一个chifan的action,命名规则必须是action+操作名称,操作的第一个字母大写,所以访问xyy/chifan,就表示执行actionChifan,可以用get/post方法把参数传递到这个action,在action中用$_POST、$_GET数组接收参数。
另外一种接收参数的方法:在web.php中配置路由GET xyy//chifan' => ‘xyy/chifan,定义chifan的action为:actionChifan($id),访问url:xyy/1/chifan,这时候id=1这个参数就被传过来了。
模型
MVC中的model,代表业务数据、规则、逻辑。
在模型中定义属性:这些属性像普通类的属性、数组一样可以被访问,是业务数据。
模型的一些特性
属性标签:通过重写yii\base\Model的attributeLabels()方法,定义标签的别名,这样在给终端用户展示这些字段时可以展示定义的别名而不是原始的属性名称。栗子:
<pre>
public function attributeLabels()
{
return [
'name' => 'Your name',
'email' => 'Your email address',
'subject' => 'Subject',
'body' => 'Content',
];
}
</pre>
在给用户提示email字段不合法时,就会显示‘Your email address’。
场景:模型可能在多个场景下使用,不同的场景下可能会有不同的业务规则和逻辑。模型使用 yii\base\Model::scenario属性设置场景,默认情况下支持’default’场景。通过覆盖yii\base\Model::scenarios()来定义不同场景下的规则,栗子:
<pre>
public function scenarios()
{
return [
'login' => ['username', 'password'],
'register' => ['username', 'email', 'password'],
];
}
</pre>
表示在login场景下 username,password是必填项,但在register场景下username,email,password是必填项。
验证规则:模型接收到来自终端的数据,可以根据业务规则对数据做一些验证,如果没有通过验证,抛出相应的错误信息。
通过重写 yii\base\Model::rules() 方法指定模型属性的验证规则,栗子:
<pre>
public function rules()
{
return [
[['name', 'email', 'subject', 'body'], 'required'], // name, email, subject 和 body 属性必须有值
['email', 'email'], // email 属性必须是一个有效的电子邮箱地址
];
}
</pre>
通过调用 yii\base\Model::validate() 验证接收到的数据,这个方法使用yii\base\Model::rules() 中的规则进行验证,如果验证通过,返回true,否则错误信息保存在 yii\base\Model::errors 属性中并返回false,栗子:
<pre>
$params = [“name”=>”xyy”,”sex”=>”girl”,”age”=>”monkey”];//设置一些参数
$model->attributes = $params;//把参数传给model
if ($model->validate()) {
// 验证参数是否合法
} else {
// 验证失败:$errors 是一个包含错误信息的数组
$errors = $model->errors;
}
</pre>
块赋值:一次性把一个数组填充到一个模型,这个数组的key必须是模型中的属性名称,如果不是则会被忽略,栗子:
<pre>
$params = [“name”=>”xyy”,”sex”=>”girl”,”age”=>”monkey”];
$model->attributes = $params;//块赋值的方法
$model->name = “xyy”;
$model->sex=“girl”;
$model->age=>”monkey”;//一个一个赋值
</pre>
这两种填充方式效果是一样的。
安全属性:在使用块赋值时,被定义为安全属性的属性才可以被终端传过来的数据赋值。
非安全属性:想要给非安全属性赋值,必须显示地赋值,栗子:$model->name = ”xyy“;
数据导出:模型可能需要导出成不同的格式,例如把一个模型的集合转换成json或xml,分2步,1、转换成数组 2、把数组转成需要的格式。
用$array = $model->attributes方法可以把$model所有的属性保存在$array数组里。
字段:默认情况下,字段名对应属性名,可以通过覆盖yii\base\Model::fields() 和 yii\base\Model::extraFields()方法改变字段名,两个方法都返回一个字段列表,fields() 方法定义的字段是默认字段,当调用模型的toArray方法会返回一个数组,数组的key就是字段名,value是字段的值。extraFields()方法定义额外可用字段,通过toArray()方法指定$expand参数来返回这些额外可用字段。栗子:
<pre>
public function fields()
{
return [
// 字段名和属性名相同
'id',
// 字段名为 "email",对应属性名为 "email_address"
'email' => 'email_address',
// 字段名为 "name", 值通过PHP代码返回
'name' => function () {
return $this->first_name . ' ' . $this->last_name;
},
];
}
</pre>