## Yii2开发小技巧
[TOC]
工作中或多或少会用到的关于 Yii2 的小技巧的一个总结,包括model、controller、view或者配置文件的一些写法。
### 模型相关
#### 获取查询SQL
```php
$query = User::find()->where(['LIKE', 'name', 'ad%', false]);
$commandQuery = clone $query;
echo $commandQuery->createCommand()->getRawSql(); // SELECT * FROM `user` WHERE `name` LIKE 'ad%'
```
#### 查询数据表中具体列
```php
return \yii\helpers\ArrayHelper::getColumn(User::find()->all(), 'name');
return User::find()->select('name')->asArray()->column();
```
#### `Expression()`函数
* 使用`find_in_set()`等函数,需要用到`Expression()` 表达式。
```php
User::find()
->where(new yii\db\Expression('FIND_IN_SET(:status, status)'))
->addParams([':status' => 1])
->all();
```
* 避免select里的子查询被识别成字段
```php
$quert = User::find()
->select([
new Expression('count(*) as count , count(distinct mobile) as mnumber')
])->asArray()
->all();
```
#### 模型中事务编写
```php
Yii::$app->db->transaction(function() {
$order = new Order($customer);
$order->save();
$order->addItems($items);
});
// 这相当于下列冗长的代码:
$transaction = Yii::$app->db->beginTransaction();
try {
$order = new Order($customer);
$order->save();
$order->addItems($items);
$transaction->commit();
} catch (\Exception $e) {
$transaction->rollBack();
throw $e;
}
```
#### Model 里 rules 联合唯一规则
即建立了联合唯一索引的字段,验证时保证数据的完整。
```php
[['store_id', 'member_name'], 'unique', 'targetAttribute' => ['store_id', 'member_name'], 'message' => 'The combination of Store ID and Member Name has already been taken.'],
```
#### 是否存在的规则
校验 `country_id` 在 `Country` 中是否存在,一般用于一些外键关联的数据表之间的数据约束。
```php
public function rules()
{
return [
[['country_id'], 'exist', 'skipOnError' => true, 'targetClass' => Country::className(), 'targetAttribute' => ['country_id' => 'id'],'message' => '此{attribute}不存在。'],
];
}
```
#### 表单验证两个字段选取一个
```php
public function rules()
{
return [
[['card_id', 'card_code'], function ($attribute, $param) { //至少要一个
if (empty($this->card_code) && empty($this->card_id)) {
$this->addError($attribute, 'card_id/card_code至少要填一个');
}
}, 'skipOnEmpty' => false],
];
}
```
#### Like 模糊查询
```php
$query = User::find()->where(['LIKE', 'name', 'ad%', false]); // SELECT * FROM `user` WHERE `name` LIKE 'ad%'
```
#### 执行SQL查询并缓存结果
调用`yii\db\Connection`的cache方法,写入回调函数执行SQL查询并缓存结果。
```php
$id = Yii::$app->request->get('id');
$collection = Yii::$app->db->cache(function (Connection $db) use($id){
return self::findOne(['id'=>$id]);
},10); // 缓存10秒
var_dump($collection);
```
#### `and`和`or`共用
在查询时,`and`和`or`条件共用。
```php
Topic::updateAll(
['last_comment_time' => new Expression('created_at')],
// ['or', ['type' => Topic::TYPE, 'last_comment_username' => ''], ['type' => Topic::TYPE, 'last_comment_username' => null]]
['and', ['type' => Topic::TYPE], ['or', ['last_comment_username' => ''], ['last_comment_username' => null]]]
);
```
#### 嵌套查询
```
$subQuery = new Query();
$subQuery->from(PostComment::tableName())->where(['status' => PostComment::STATUS_ACTIVE])->orderBy(['created_at' => SORT_DESC]);
$comment = PostComment::find()->from(['tmpA' => $subQuery])
->groupBy('post_id')
->all();
```
> 生成如下语句:`SELECT * FROM (SELECT * FROM `post_comment` WHERE `status`=1 ORDER BY `created_at` DESC) `tmpA` GROUP BY `post_id``
* * * * *
### 控制器相关
#### 获取模块/控制器/动作的id
```
$this->module->id
$this->id
$this->action->id
```
#### 表单提交失败调试
```php
echo array_values($model->getFirstErrors())[0];exit;
```
#### 文件下载
存在一个文件地址,关于一些下载需要的header头信息Yii2已经帮我们完成,如下操作即可。
```
public function actionDownload($id)
{
$model = $this->findModel($id);
if ($model) {
// do something
}
return \Yii::$app->response->setDownloadHeaders($model->downurl);
}
```
> 模型的`downurl`属性可以通过 `extraFields()`进行设置。
#### 打印数据
```php
\yii\helpers\VarDumper::dump($var);
\yii\helpers\VarDumper::dump($var, 10 ,true);die; // 使用2 第二个参数是数组的深度 第三个参数是是否显示代码高亮(默认不显示)
```
#### 控制器调用其他控制器方法
```php
Yii::$app->runAction('new_controller/new_action', $params);
// 或者
return (new SecondController('second', Yii::$app->module))->runAction('index', $data);
```
#### 获取GET数据
```php
Yii::$app->getRequest()->get('id');
```
* * * * *
### 视图相关
#### 视图中获取当前模块/控制器/方法id
```php
Yii::$app->controller->module->id;
Yii::$app->controller->id
Yii::$app->controller->action->id
```
### 防止SQL注入或者XSS攻击
```php
echo yii\helpers\Html::encode($view_hello_str) // 可以原样显示<script></script>代码,但不解析
echo yii\helpers\HtmlPurifier::process($view_hello_str) // 可以过滤掉<script></script>代码
```
* * * * *
### 配置相关
#### 用户组件登录修改
修改登陆状态超时时间(到期后自动退出登陆) `config/web.php`中的**components**组件数组中。
```
'user' => [
'class'=>'yii\web\User',
'identityClass' => 'common\models\User',
'loginUrl'=>['/user/sign-in/login'],
'authTimeout' => 1800, // 登陆有效时间
'as afterLogin' => 'common\behaviors\LoginTimestampBehavior'
],
```
#### 配置文件IP白名单
通过下面的IP地址方式配置debug的显示,便于调试代码。
```
$config['modules']['debug'] = [
'class' => 'yii\debug\Module',
'allowedIPs' => ['127.0.0.1', '192.168.0.*', '192.168.33.1'],
];
```
- 开始
- Yii2开发小技巧
- Yii2使用不同的方式进行邮件发送逻辑处理
- Yii2 Serialization of 'Closure' is not allowed 错误
- Yii创建应用
- Yii应用结构和流程
- Yii的路径别名
- Yii的请求
- Yii的响应
- Sessions 和 Cookies
- Yii自定义全局工具函数
- Yii2模型
- Yii2视图
- Yii2控制器
- 大数据节省内存处理
- 关联查询hasMany、hasOne
- Yii2 URL地址美化
- Yii2整合AdminLTE后台主题
- Yii2模型中的场景
- Yii2中的RBAC
- Yii2项目后台整合yii2-admin模块
- RBAC集成AdminLTE后台主题对菜单进行控制
- Yii2自定义Gii模板
- 修复AdminLTE引用外部字体文件导致访问变慢的情况
- Yii2事件简单使用
- Yii2模型事件
- Yii2使用GridView新增操作按钮
- Yii2向loyout模板文件中传值
- Yii2数据缓存
- Yii2缓存
- Yii2数据缓存之增删改查
- Yii2拓展
- Yii2日期时间插件-datetimepicker
- kartik-v/yii2-widget-fileinput上传插件