前言:最近在用php写一个项目的接口,所以需要学习一下Yii的框架,也在这里记录一下。
ssets文件夹:assets的作用是方便模块化,插件化的,一般来说出于安全原因不允许通过url访问protected下面的文件 ,但是我们又希望将module单独出来,所以需要使用发布,即将一个目录下的文件复制一份到assets下面方便通过url访问。
commands文件夹:控制台脚本存放的地方,自动运行脚本
config文件夹:配置文件存放的文件夹
controller文件夹:MVC中C文件存放的文件夹
mail文件夹:邮件发送目录,具体干啥的我还在摸索中哈~
models文件夹:MVC中M文件存放的文件夹
runtime:日志文件
tests:测试脚本文件夹
vendor:第三方组件存放,composer下载的组件存放的文件夹,自动帮你autoload
views:MVC中V存放的文件夹
web:web主应用入口脚本存放的位置
以上是整个文件夹的布局,可以根据自己的项目灵活变化,我们公司的项目中就弱化了MVC里面的V,把V放在了前端。
官方文档【中文版】:http://www.yiichina.com/doc/guide/2.0
Yii 应用参照模型-视图-控制器 (MVC)设计模式来组织。当时听到MVC也是一脸懵逼,组长给我几个网址就让我自己去了解了。
M模型代表数据、业务逻辑和规则;V视图展示模型的输出;C控制器接受出入并将其转换为模型和视图命令。
这是官网上面的框架结构设计,MVC就是其中的控制器,视图和模型,他们的各自作用上面也讲了下,一般的后端应用,M表示从数据库、第三方链接、本地文件中获取的数据进行处理,整理,在交给到V端,V端的作用一般是在页面中反馈给用户的页面,如果是以数据的形式返回给用户,那这个V层就不用做过多的渲染。C层的话主要是连接两者的作用,C层获取到用户的请求,传给M层,M层处理好数据,反馈给C层,C层再将数据给到V层,V层展示给用户。MVC模型的便捷之处就是逻辑清晰,每个模块负责自己的事,有条有理,非常便于初学者理解,是一个入门的模型。
除此之外,Yii还包含其他逻辑处理块,比方说上面图中的入口脚本【调用应用一开始必被调用的脚本文件】,应用主体【Yii::$app全局可访问对象】,应用组件【全局通用的一些工具集】,模块【业务逻辑单元,每个业务逻辑一个模块,会让代码很清晰】,过滤器【规范行为的对象,在控制器执行之前或之后调用,定义一类特殊的行为】,前端资源和小部件我们先不讲,因为是涉及到前端的一些组件内容,后面我会单独开辟一个系列来讲前端知识,我出这一系列的目的主要是针对后台应用~
入口脚本
web文件夹下面的index.php就是入口脚本,每次web请求都必须经过它!
还有个入口脚本是啥呢,控制台脚本,下面的那个叫yii的php脚本,啥作用呢,你们想想啊,电商后台中,如果有很多人要调整库存,是不是调整一次就给改一次呀,肯定不会呀,库存操作如果调用数据库太频繁了,数据库肯定扛不住的,我们的做法就是先放到类似于Redis的缓存中,等到一定量的时候,或者有个1秒钟的时候我们给同步一次数据库,同步的方式就是调用控制台脚本啦,配合Linux的crontab,完美解决数据库调用过于频繁的问题。控制台脚本后面我们会介绍,一般业务线中用的还挺多的。
入口脚本主要完成以下工作:
- 定义全局常量;
- 注册 Composer 自动加载器;
- 包含 Yii 类文件;
- 加载应用配置;
- 创建一个应用实例并配置;
- 调用 yii\base\Application::run() 来处理请求。
<?php // comment out the following two lines when deployed to production defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_ENV') or define('YII_ENV', 'dev'); require(__DIR__ . '/../vendor/autoload.php'); require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php'); $config = require(__DIR__ . '/../config/web.php'); (new yii\web\Application($config))->run();
入口脚本是定义全局常量的最好地方,话虽如此,不建议在这里定义啥全局变量!Yii 支持以下三个常量:
YII_DEBUG:标识应用是否运行在调试模式。当在调试模式下,应用会保留更多日志信息,如果抛出异常,会显示详细的错误调用堆栈。因此,调试模式主要适合在开发阶段使用,YII_DEBUG 默认值为 false。
YII_ENV:标识应用运行的环境。YII_ENV 默认值为 'prod',表示应用运行在线上产品环境。
YII_ENABLE_ERROR_HANDLER:标识是否启用 Yii 提供的错误处理,默认为 true。
autoload.php:自动加载器,这个是注册composer自动加载器的。
Yii.php,包含Yii类的文件路径。
应用主体配置
应用主体在入口脚本中创建并能通过表达式 \Yii::$app 全局范围内访问。访问的变量定义在哪儿呢,由于应用主体配置比较复杂,就是刚刚提到的$config,config文件夹中的web.php文件。后面比较复杂的配置都可以放到单个文件中,这是个技巧,即减少了配置文件的代码行数,也将整个框架清晰很多。
这里定义了很多属性我们来分别看一下
<?php $params = require(__DIR__ . '/params.php'); $config = [
params这个参数里的所有变量就被定义在params.php这个文件夹里面
下面是我的项目中配置的一些文件在上方定义
<?php $params = require(__DIR__ . '/params.php'); $rules = require(__DIR__ . '/rules.php'); $aliases = require(__DIR__ . '/aliases.php'); $cacheConfig = require(__DIR__ . '/cache.php');
这里面主要是params参数,rules路由规则,aliases别名规则,cacheConfig缓存配置
为什么没有db,db是区分环境的,在index.php中会区分stable环境,pro环境还是测试环境
回到YII源码,配合文件上方配置了params所在的文件
$config = [ 'id' => 'basic', 'basePath' => dirname(__DIR__), 'bootstrap' => ['log'], 'components' => [ 'request' => [ // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation 'cookieValidationKey' => 'A9BMCrvbxuCEnE39rVpOUECgcBJTnzUH', ], 'cache' => [ 'class' => 'yii\caching\FileCache', ], 'user' => [ 'identityClass' => 'app\models\User', 'enableAutoLogin' => true, ], 'errorHandler' => [ 'errorAction' => 'site/error', ], 'mailer' => [ 'class' => 'yii\swiftmailer\Mailer', // send all mails to a file by default. You have to set // 'useFileTransport' to false and configure a transport // for the mailer to send real emails. 'useFileTransport' => true, ], 'log' => [ 'traceLevel' => YII_DEBUG ? 3 : 0, 'targets' => [ [ 'class' => 'yii\log\FileTarget', 'levels' => ['error', 'warning'], ], ], ], 'db' => require(__DIR__ . '/db.php'), /* 'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'rules' => [ ], ], */ ], 'params' => $params, ];
这里面有几个比较重要的属性:id、basePath、bootstrap、components
其他还有几个比较重要的属性:aliases、language、moudules
id:
yii\base\Application::id 属性用来区分其他应用的唯一标识ID。一般配置为程序名称。必要属性之一
basePath:
yii\base\Application::basePath 指定该应用的根目录,系统预定义@app代表这个路径。如果需要require目录被的文件,可以使用这个方式找到对应文件。另外一个必要属性,这个是必须得配置的。
bootstrap:
这个属性很实用,他允许你用数组启动阶段yii\base\Application::bootstrap()需要运行的组件,一般后端应用中配置这个'bootstrap' => ['log']即可
component:
这是最重要的属性,他允许你注册多个在其他地方使用的应用组件,比方说session、log、db和cache,都在这里配置的
aliases
该属性允许你用一个数组定义多个别名。数组的key为别名名称,值为对应的路径。
[ 'aliases' => [ '@name1' => 'path/to/path1', '@name2' => 'path/to/path2', ], ]
language
该属性指定应用展示给终端用户的语言,默认为 en 标识英文。如果需要之前其他语言可以配置该属性
'language' => 'zh-CN',
modules
该属性指定应用所包含的模块。还记得上面说的业务的分割吗,是的,就是在modules里面进行划分的,对应的目录就是根目录下的modules目录,也需要配置
[ 'modules' => [ // "booking" 模块以及对应的类 'booking' => 'app\modules\booking\BookingModule', // "comment" 模块以及对应的配置数组 'comment' => [ 'class' => 'app\modules\comment\CommentModule', 'db' => 'db', ], ], ]
这个配置对你代码的结构清晰性有很大的提升,后端应用必配属性。
defaultRoute
该属性指定未配置的请求的响应 路由规则,路由规则可能包含模块ID,控制器ID,动作ID。
例如
help, post/create, admin/post/create,如果动作ID没有指定,会使用yii\base\Controller::defaultAction中指定的默认值。
对于 yii\web\Application 网页应用,默认值为 'site' 对应 SiteController 控制器,并使用默认的动作。
对于 yii\console\Application 控制台应用, 默认值为 'help' 对应 yii\console\controllers\HelpController::actionIndex()。
应用组件
在同一个应用中,每个应用组件都有一个独一无二的 ID 用来区分其他应用组件,你可以通过如下表达式访问应用组件
\Yii::$app->componentID
官网给出的components示例如下
[ 'components' => [ // 使用类名注册 "cache" 组件 'cache' => 'yii\caching\ApcCache', // 使用配置数组注册 "db" 组件 'db' => [ 'class' => 'yii\db\Connection', 'dsn' => 'mysql:host=localhost;dbname=demo', 'username' => 'root', 'password' => '', ], // 使用函数注册"search" 组件 'search' => function () { return new app\components\SolrService; }, ], ]
这里定义了三个配置属性:cache、db、search,除此之外,比较重要的components属性还有如下几个:urlManager、user、session、errorHandler和log。
cache
代表代表各种缓存存储器,例如内存,文件,数据库。
db
代表一个可以执行数据库操作的数据库连接。
search
搜索组件入口配置,以后有机会和大家唠唠solr相关,切割关键字,切割,切割~
urlManager
支持URL地址解析和创建。
user
代表认证登录用户信息,仅在yii\web\Application 网页应用中可用。如果有后台用户权限认证管理,可去官网了解明细。
session
代表会话信息,仅在yii\web\Application 网页应用中可用,我们一般都是通过这个来控制用户属性的,
errorHandler
处理 PHP 错误和异常
log
全局日志配置入口
请谨慎注册太多应用组件,应用组件就像全局变量,使用太多可能加大测试和维护的难度。 一般情况下可以在需要时再创建本地组件。
大家可以着重关注几个配置:db、urlManager、log和cache,这些都是在日常工作中用的比较多的,必配的配置。
控制器
MVC里面的C,下面我们称它为controller,因为他是入口,我入口脚本一样,用户发来请求,首先到的就是控制器(这里的先到只是在后台应用中先到,如果包含前端资源,那么肯定是先接触到前端代码的)
Controller的主要职责是接受用户请求,分发处理用户请求,拿到结果数据,递交给V层展示给客户
首先继承yii\base\Controller类的对象
Controller由操作【action】组成,他是执行终端用户请求的最基础的单元,一个控制器可以有多个或一个操作
如下示例显示包含两个操作view和create的控制器post:
namespace app\controllers; use Yii; use app\models\Post; use yii\web\Controller; use yii\web\NotFoundHttpException; class PostController extends Controller { public function actionView($id) { $model = Post::findOne($id); if ($model === null) { throw new NotFoundHttpException; } return $this->render('view', [ 'model' => $model, ]); } public function actionCreate() { $model = new Post; if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect(['view', 'id' => $model->id]); } else { return $this->render('create', [ 'model' => $model, ]); } } }