yii2
前段时间学习了 yii2 这个 php MVC 框架。 向同事做了培训,搬运总结到blog上~~~
文档资源:
环境依赖
- Yii 2.0 需要 PHP 5.4.0 或以上版本支持
- 支持php7
Composer安装
win下的安装
- 下载并安装 Composer-Setup.exe
- 更新Composer
composer self-update
- composer global require “fxp/composer-asset-plugin:~1.1.1” 这里是 1.1.1,中文文档这里没更新,有坑,会影响后续yii2-smarty的安装
- composer create-project –prefer-dist yiisoft/yii2-app-basic basic
目录结构
basic/ 应用根目录
composer.json Composer 配置文件, 描述包信息
config/ 包含应用配置及其它配置
console.php 控制台应用配置信息
web.php Web 应用配置信息
commands/ 包含控制台命令类
controllers/ 包含控制器类
models/ 包含模型类
runtime/ 包含 Yii 在运行时生成的文件,例如日志和缓存文件
vendor/ 包含已经安装的 Composer 包,包括 Yii 框架自身
views/ 包含视图文件
//modules 可以设置自己的模块
web/ Web 应用根目录,包含 Web 入口文件
assets/ 包含 Yii 发布的资源文件(javascript 和 css)
// js css img 可以设置文件目录
index.php 应用入口文件
yii Yii 控制台命令执行脚本
gii
可以直接访问 gii, 生成 module controller models ==初始化文件
MVC
Models
数据模型,可用于数据的建立和逻辑运算, models/ 目录下,可以分为 AR(active record) 和 运算模型两种。
- AR 提供了一个面向对象的接口, 用以访问数据库中的数据。一个 AR 类关联一张数据表, 每个 AR 对象对应表中的一行,对象的属性(即 AR 的特性Attribute)映射到数据行的对应列
- 运算模型,承担业务逻辑的部分运算,解耦
用gii 生成AR models,可以关联表字段,表结构变化后,AR models 也需要变化
Controllers
驼峰命名,对应了控制器 ID
- UserController.php -> user
UserCenterController.php -> user-center
默认命名空间为 app]controllers;如果有多级目录,如backend/shop-manaer,namespace app\controllers\backend; 命名空间也要变化
use 全局引入class, yii\base*,是yii2框架基础类,文件地址为vendor/yiisoft/yii2/ 。
app\ 类, app是指安装地址。默认action为index,可以设置$defaultAction 进行改变。
- 通用方法 变量初始化
public function init(){}
,action前置和后置方法public function beforeAction($action){}
public function afterAction($action){}
。 - 方法驼峰命名, actionIndex -> index, actionIndexTest -> index-test
- public $enableCsrfValidation = false csrf防范关闭, 采用的 ===
,采用了yii2-smarty 模板, 关闭csrf;否则提交表单会被阻止 - render() renderPartial() 展现视图
- $layout 为默认layouts/main.php为公共视图
- 命名会与module的id 冲突, 与web/ 下的文件夹名称冲突
Views
- 文件目录对应controller ID及命名空间,文件名由render()确定
- {include ‘’} {include ‘app/views/*’} yii2-smarty的引用模版方法
- 默认的layouts为公共模版目录
- render(file) 方法将文件file返回结果为content,需要在$layout(main.php->main.tpl) 中输出,
<mainid="main" class="container"> {$content} </main>
- renderPartial 则是直接渲染file文件
执行过程
路由 解析 url, 默认 为 index.php?r=module/ctrl/act¶m
- index.php
- 整个app目录是一个默认的module,可以默认不写module。如果配置中有module,跳转到module中执行
- 寻找controller id, 如果controllers/ 下有多级目录,目录名不能和已有的module 命名冲突
- 最后在controlle中寻找action id
- 由于module参数很多时候默认不写, action id 默认为index,所以访问链接为r=ctrl/ ,根目录为web/, 会先查找web/ 下的文件夹, 注意和ctrl 命名冲突
请求与响应
请求
$request = Yii::$app->request;
$get = $request->get();
// 等价于: $get = $_GET;
$id = $request->get('id');
// 等价于: $id = isset($_GET['id']) ? $_GET['id'] : null;
$id = $request->get('id', 1);
// 等价于: $id = isset($_GET['id']) ? $_GET['id'] : 1;
$post = $request->post();
// 等价于: $post = $_POST;
$name = $request->post('name');
// 等价于: $name = isset($_POST['name']) ? $_POST['name'] : null;
$name = $request->post('name', '');
// 等价于: $name = isset($_POST['name']) ? $_POST['name'] : '';
- 可以直接用$_GET $_POST
- 封装了一个 request, 方便测试用例编写
- 客户端信息
- $userHost = Yii::$app->request->userHost;
- $userIP = Yii::$app->request->userIP;
- HTTP头信息 URLs信息
响应
$response = Yii::$app->response;
$response->format = \yii\web\Response::FORMAT_JSON;
$response->data = ['message' => 'hello world'];
也封装了一个response,多种返回类型
yii\web\Response::FORMAT_HTML: 通过 yii\web\HtmlResponseFormatter 来实现.
yii\web\Response::FORMAT_XML: 通过 yii\web\XmlResponseFormatter来实现.
yii\web\Response::FORMAT_JSON: 通过 yii\web\JsonResponseFormatter来实现.
yii\web\Response::FORMAT_JSONP: 通过 yii\web\JsonResponseFormatter来实现.
Sessions Cookies
session
$session = Yii::$app->session;
// 检查session是否开启
if ($session->isActive) ...
// 开启session
$session->open();
// 关闭session
$session->close();
// 销毁session中所有已注册的数据
$session->destroy();
//多次调用yii\web\Session::open() 和yii\web\Session::close() 方法并不会产生错误, 因为方法内部会先检查session是否已经开启。
$session = Yii::$app->session;
// 获取session中的变量值,以下用法是相同的:
$language = $session->get('language');
$language = $session['language'];
$language = isset($_SESSION['language']) ? $_SESSION['language'] : null;
// 设置一个session变量,以下用法是相同的:
$session->set('language', 'en-US');
$session['language'] = 'en-US';
$_SESSION['language'] = 'en-US';
// 删除一个session变量,以下用法是相同的:
$session->remove('language');
unset($session['language']);
unset($_SESSION['language']);
cookie
// 从 "request"组件中获取cookie集合(yii\web\CookieCollection)
$cookies = Yii::$app->request->cookies;
// 获取名为 "language" cookie 的值,如果不存在,返回默认值"en"
$language = $cookies->getValue('language', 'en');
// 另一种方式获取名为 "language" cookie 的值
if (($cookie = $cookies->get('language')) !== null) {
$language = $cookie->value;
}
// 可将 $cookies当作数组使用
if (isset($cookies['language'])) {
$language = $cookies['language']->value;
}
// 判断是否存在名为"language" 的 cookie
if ($cookies->has('language')) ...
if (isset($cookies['language'])) ...
数据库
数据库访问 (DAO)
$connection = new \yii\db\Connection([
'dsn' => $dsn,
'username' => $username,
'password' => $password,
]);
$connection->open();
返回多行
$command = $connection->createCommand('SELECT * FROM post');
$posts = $command->queryAll();
返回单行:
$command = $connection->createCommand('SELECT * FROM post WHERE id=1');
$post = $command->queryOne();
查询多行单值:
$command = $connection->createCommand('SELECT title FROM post');
$titles = $command->queryColumn();
查询标量值/计算值:
$command = $connection->createCommand('SELECT COUNT(*) FROM post');
$postCount = $command->queryScalar();
// insert,update,delete 需要调用execute
$command = $connection->createCommand('UPDATE post SET status=1 WHERE id=1');
$command->execute();
$connection->createCommand()->batchInsert('user', ['name', 'age'], [
['Tom', 30],
['Jane', 20],
['Linda', 25],
])->execute();
// UPDATE
$connection->createCommand()->update('user', ['status' => 1], 'age > 30')->execute();
// DELETE
$connection->createCommand()->delete('user', 'status = 0')->execute();
- 提供事务支持, 复制与读写分离, 修改模式
查询构建器
只用于查询
$rows = (new \yii\db\Query())
->select(['id', 'email'])
->from('user')
->where(['last_name' => 'Smith'])
->limit(10)
->all();
子查询
$subQuery = (new Query())->select('id')->from('user')->where('status=1');
// SELECT * FROM (SELECT `id` FROM `user` WHERE status=1) u
$query->from(['u' => $subQuery]);
操作符
- 符号>, <=, 或者其他包含两个操作数的合法 DB 操作符: 第一个操作数必须为字段的名称, 而第二个操作数则应为一个值。例如,[‘>’, ‘age’, 10] 将会生成 age>10。
- and: 操作数会被 AND 关键字串联起来。例如,[‘and’, ‘id=1’, ‘id=2’] 将会生成 id=1 AND id=2。如果操作数是一个数组,它也会按上述规则转换成 字符串。例如,[‘and’, ‘type=1’, [‘or’, ‘id=1’, ‘id=2’]] 将会生成 type=1 AND (id=1 OR id=2)。
- $query->leftJoin(‘post’, ‘post.user_id = user.id’);
查询结果
yii\db\Query::all(): 将返回一个由行组成的数组,每一行是一个由名称和值构成的关联数组(译者注:省略键的数组称为索引数组)。
yii\db\Query::one(): 返回结果集的第一行。
yii\db\Query::column(): 返回结果集的第一列。
yii\db\Query::scalar(): 返回结果集的第一行第一列的标量值。
yii\db\Query::exists(): 返回一个表示该查询是否包结果集的值。
yii\db\Query::count(): 返回 COUNT 查询的结果。
Active Record
$customer = new Customer();
$customer->name = 'Qiang';
$customer->save(); // 一行新数据插入 customer 表
- 声明class, 需要继承use yii\db\ActiveRecord;
- yii\db\ActiveRecord::find()
yii\db\ActiveRecord::findBySql() - findOne 和 findAll()
- 默认返回对象,asArray()返回数组
yii\db\ActiveRecord::save()
yii\db\ActiveRecord::insert()
yii\db\ActiveRecord::update()
yii\db\ActiveRecord::delete()yii\db\ActiveRecord::updateCounters()
yii\db\ActiveRecord::updateAll()
yii\db\ActiveRecord::updateAllCounters()
yii\db\ActiveRecord::deleteAll()
配置
'modules' => [
// 模块设置 id => class
'demo' => 'app\module\demo\Demo',
'admin'=> 'app\module\admin\Admin'
],
'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' => 'KdsIbTIrv6kIPFMV6tRfyk9JrPXe4nDB',
],
'cache' => [
'class' => 'yii\caching\FileCache',
],
'urlManager' => [
'enablePrettyUrl' => true, //启动美化
'showScriptName' => false, //禁用index.php
'rules' => [
"<controller:backend/shop-manaer>/<action:detail>/<shop_id:\d+>"=>"<controller>/<action>",
"<controller:backend/shop-manaer>/<action:check>/<is_check:-?\d>/<shop_id:\d+>"=>"<controller>/<action>",
"<controller:backend/shop-manaer>/<action:auth>/<is_auth:-?\d>/<shop_id:\d+>"=>"<controller>/<action>",
"<controller:\w+>/<action:\w+>"=>"<controller>/<action>",
]
],
'view' => [
'class' => 'yii\web\View',
'renderers' => [
'tpl' => [ //yii2-smarty模板
'class' => 'yii\smarty\ViewRenderer',
//'cachePath' => '@runtime/Smarty/cache',
],
]
],
urlManager
'enablePrettyUrl' => true, //启动美化
'showScriptName' => false, //禁用index.php
'rules' => [
"<controller:backend/shop-manaer>/<action:detail>/<shop_id:\d+>"=>"<controller>/<action>",
"<controller:backend/shop-manaer>/<action:check>/<is_check:-?\d>/<shop_id:\d+>"=>"<controller>/<action>",
"<controller:backend/shop-manaer>/<action:auth>/<is_auth:-?\d>/<shop_id:\d+>"=>"<controller>/<action>",
"<controller:\w+>/<action:\w+>"=>"<controller>/<action>",
- restful 风格, 简洁可自定义
- 可隐藏文件路径,自定义调整路径
- apache htaccess 不一样,启用后,不能用默认r=ctrl/act方法访问