• Yii2开发小技巧


    工作中或多或少会用到的关于 Yii2 的小技巧的一个总结,包括model、controller、view或者配置文件的一些写法。

    模型相关

    获取查询SQL

    $query = User::find()->where(['LIKE', 'name', 'ad%', false]);
    
    $commandQuery = clone $query;
    echo $commandQuery->createCommand()->getRawSql(); // SELECT * FROM `user` WHERE `name` LIKE 'ad%'

    查询数据表中具体列

    return yiihelpersArrayHelper::getColumn(User::find()->all(), 'name');
    
    return User::find()->select('name')->asArray()->column();

    Expression()函数

    • 使用find_in_set()等函数,需要用到Expression() 表达式。
    User::find()
        ->where(new yiidbExpression('FIND_IN_SET(:status, status)'))
        ->addParams([':status' => 1])
        ->all();
    • 避免select里的子查询被识别成字段
    $quert = User::find()
        ->select([
              new Expression('count(*) as count , count(distinct mobile) as mnumber')
         ])->asArray()
        ->all();

    模型中事务编写

    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 联合唯一规则

      即建立了联合唯一索引的字段,验证时保证数据的完整。

    [['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 中是否存在,一般用于一些外键关联的数据表之间的数据约束。

    public function rules()
    {
        return [
            [['country_id'], 'exist', 'skipOnError' => true, 'targetClass' => Country::className(), 'targetAttribute' => ['country_id' => 'id'],'message' => '此{attribute}不存在。'],
        ];
    }

    表单验证两个字段选取一个

    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 模糊查询

    $query = User::find()->where(['LIKE', 'name', 'ad%', false]); // SELECT * FROM `user` WHERE `name` LIKE 'ad%'

    执行SQL查询并缓存结果

    调用yiidbConnection的cache方法,写入回调函数执行SQL查询并缓存结果。

    $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);

    andor共用

    在查询时,andor条件共用。

    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 * FROMpost_commentWHEREstatus=1 ORDER BYcreated_atDESC)tmpAGROUP BYpost_id``


    控制器相关

    获取模块/控制器/动作的id

    $this->module->id
    
    $this->id
    
    $this->action->id

    表单提交失败调试

    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()进行设置。

    打印数据

    yiihelpersVarDumper::dump($var);
    
    yiihelpersVarDumper::dump($var, 10 ,true);die; //  使用2  第二个参数是数组的深度  第三个参数是是否显示代码高亮(默认不显示)

    控制器调用其他控制器方法

    Yii::$app->runAction('new_controller/new_action', $params);
    // 或者
    return (new SecondController('second', Yii::$app->module))->runAction('index', $data);

    获取GET数据

    Yii::$app->getRequest()->get('id');

    视图相关

    视图中获取当前模块/控制器/方法id

    Yii::$app->controller->module->id;
    
    Yii::$app->controller->id
    
    Yii::$app->controller->action->id

    防止SQL注入或者XSS攻击

    echo yiihelpersHtml::encode($view_hello_str) // 可以原样显示<script></script>代码,但不解析 
    echo yiihelpersHtmlPurifier::process($view_hello_str)  // 可以过滤掉<script></script>代码 

    配置相关

    用户组件登录修改

    修改登陆状态超时时间(到期后自动退出登陆) config/web.php中的components组件数组中。

    'user' => [
        'class'=>'yiiwebUser',
         'identityClass' => 'commonmodelsUser',
         'loginUrl'=>['/user/sign-in/login'],
         'authTimeout' => 1800, // 登陆有效时间
         'as afterLogin' => 'commonehaviorsLoginTimestampBehavior'
    ],

    配置文件IP白名单

    通过下面的IP地址方式配置debug的显示,便于调试代码。

    $config['modules']['debug'] = [
        'class' => 'yiidebugModule',
        'allowedIPs' => ['127.0.0.1', '192.168.0.*', '192.168.33.1'],
    ];
  • 相关阅读:
    oo第四次总结
    oo第三次总结
    补给站总结
    OO第四次单元总结
    OO第三次单元总结
    OO第二次单元总结
    OO第一次单元总结
    提问回顾与个人总结
    软件工程结对作业博客
    OO第一次单元总结
  • 原文地址:https://www.cnblogs.com/xiong63/p/6781146.html
Copyright © 2020-2023  润新知