1、不通过日志获取AR执行的原生SQL语句和打印变量数据

  1. $query = User::find() ->select(['username'])->where(['id'=>[1,2,3,4])
  2. // get the AR raw sql in YII2
  3. $commandQuery = clone $query;
  4. echo $commandQuery->createCommand()->getRawSql();$users = $query->all();
  1. 打印变量数据可以这样写:
  2. //引用命名空间
  3. use yii\helpers\VarDumper;
  4. //使用
  5. VarDumper::dump($var);
  6. //使用2  第二个参数是数组的深度  第三个参数是是否显示代码高亮(默认不显示)
  7. VarDumper::dump($var, 10 ,true);

2、从数据库二维数组中返回一维数组并配合rules验证规则实现分类数据过滤。

普通返回表记录的二维数组

  1. Member::find()->select('userid')->asArray()->all();
  1. Array
  2. (
  3.     [0] => Array
  4.         (
  5.             [userid] => 1
  6.         )
  7.     [1] => Array
  8.         (
  9.             [userid] => 2
  10.         )
  11.     [2] => Array
  12.         (
  13.             [userid] => 3
  14.         )
  15. )

返回字段的一维数组

  1. Member::find()->select('userid')->asArray()->column();

或者:

  1. \yii\helpers\ArrayHelper::getColumn(Member::find()->all(), 'userid')
  1. Array
  2. (
  3.     [0] => 1
  4.     [1] => 2
  5.     [2] => 3
  6. )

返回一维数组配合验证规则验证数据正确性,如分类catid正确分为只有1-4,但是在devTools打开修改catid为5,提交同样会到数据库,此时rules验证规则如下:

  1. ['catid', 'in', 'range' => category::find()->select('id')->asArray()->column()],

当然,这个也可以通过下面这样子写,一样的:

  1. ['catid', 'in', 'range' => \yii\helpers\ArrayHelper::getColumn(category::find()->all(), 'catid')],

这样就可以过滤不正确的分类数据了!

3、友好时间表示方法

之前一直使用自定义的友好时间函数。几天前发现万能的YII已经提供了友好时间访问,代码如下:

  1. Yii::$app->formatter->asRelativeTime('1447565922'); //2小时前

4、使用不同的响应类型或者自定义响应类型

有效的格式:

  • FORMAT_RAW

  • FORMAT_HTML

  • FORMAT_JSON

  • FORMAT_JSONP

  • FORMAT_XML

JSON响应

  1. public function actionIndex()
  2. {
  3.     \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
  4.     $items = ['some', 'array', 'of', 'data' => ['associative', 'array']];
  5.     return $items;
  6. }

返回:

  1. {
  2.     "0": "some",
  3.     "1": "array",
  4.     "2": "of",
  5.     "data": ["associative", "array"]
  6. }

自定义响应格式

让我们创建一个定制的响应格式。例子做点有趣和疯狂的事我返回PHP 数组。 首先,我们需要格式化程序本身。创建 components/PhpArrayFormatter.php:

  1. <?php
  2. namespace app\components;
  3. use yii\helpers\VarDumper;
  4. use yii\web\ResponseFormatterInterface;
  5. class PhpArrayFormatter implements ResponseFormatterInterface
  6. {
  7.     public function format($response)
  8.     {
  9.         $response->getHeaders()->set('Content-Type', 'text/php; charset=UTF-8');
  10.         if ($response->data !== null) {
  11.             $response->content = "<?php\nreturn " . VarDumper::export($response->data) . ";\n";
  12.         }
  13.     }
  14. }

组件配置:

  1. return [
  2.     // ...
  3.     'components' => [
  4.         // ...
  5.         'response' => [
  6.             'formatters' => [
  7.                 'php' => 'app\components\PhpArrayFormatter',
  8.             ],
  9.         ],
  10.     ],
  11. ];

现在是准备使用。在 controllers/SiteController 创建一个新的方法 actionTest:

  1. public function actionTest()
  2. {
  3.     Yii::$app->response->format = 'php';
  4.     return [
  5.         'hello' => 'world!',
  6.     ];
  7. }

返回如下:

  1. <?php
  2. return [
  3.     'hello' => 'world!',
  4. ];

5、AR入库前时间通过在模型重写behaviors方法实现优雅入库方式。

如下:

  1. public function behaviors()
  2. {
  3.     return [
  4.         'timestamp' => [
  5.             'class' => TimestampBehavior::className(),
  6.             'attributes' => [
  7.                 ActiveRecord::EVENT_BEFORE_INSERT => 'creation_time',
  8.                 ActiveRecord::EVENT_BEFORE_UPDATE => 'update_time',
  9.             ],
  10.             'value' => function() { return date('U'); // unix timestamp },
  11.         ],
  12.     ];
  13. }

6、除配置组件记录不同级别日志外,也可以自定义在某个地方记录LOG日志

  1. use yii\log\Logger;
  2. \Yii::getLogger()->log('User has been created', Logger::LEVEL_INFO);

7、 ActiveForm类不让生成label标签

  1. //方法一,通过ActiveForm类
  2. $form->field($model, '字段名')->passwordInput(['maxlength' => true])->label(false) ?>
  1. //方法二,通过 HTML类
  2. Html::activeInput($type,$model,'字段名')

Yii2给必填项加星,样式如下:

  1. div.required label:after {
  2.     content: " *";
  3.     color: red;
  4. }

8、Yii2 获取接口传过来的 JSON 数据:

接收get和post的数据很容易,那么接收json数据呢?!没关系,看这里:

  1. Yii::$app->request->rawBody;

9、座机和手机号码必须填写一个:

  1. public function rules()
  2. {
  3.     return [
  4.         [['telephone', 'mobile'], function ($attribute, $param) {//至少要一个
  5.             if (empty($this->telephone) && empty($this->mobile)) {
  6.                 $this->addError($attribute, 'telephone/mobile至少要填一个');
  7.             }
  8.         }, 'skipOnEmpty' => false],
  9.     ];
  10. }

10、where多条件查询示例:

  1. //and复杂示例:
  2. $time = time();
  3. Member::find()->where(['and', ['userid' => 1, 'company' =>'测试公司'], ['>', 'addtime', $time]]);
  4. //SELECT * FROM `member` WHERE ((`userid`=1) AND (`company`='测试公司')) AND (`addtime` > 1447587486)
  1. //and和or组合示例:
  2. $query = Member::find()->where(['and', ['>','userid',2], ['or', ['company' => '深圳市新民家具有限公司'], ['address' => '深圳']]]);
  3. //SELECT * FROM `member` WHERE (`userid` > 2) AND ((`company`='深圳市新民家具有限公司') OR (`address`='深圳'))

11、关于事务:

优雅的写法

  1. Yii::$app->db->transaction(function() {
  2.     $order = new Order($customer);
  3.     $order->save();
  4. });

这相当于下列冗长的代码:

  1. $transaction = Yii::$app->db->beginTransaction();
  2. try {
  3.     $order = new Order($customer);
  4.     $order->save();
  5.     $transaction->commit();
  6. } catch (\Exception $e) {
  7.     $transaction->rollBack();
  8.     throw $e;
  9. }

12、rest风格API获取客户端提交的get和post的数组

  1. // post
  2. Yii::$app->request->bodyParams
  3. // get
  4. Yii::$app->request->queryParams;

13、一个控制器调用其他控制器action的方法:

方法一:

是经典的重写actions方法

  1.   public function actions()
  2.     {
  3.         return [
  4.             'error' => [
  5.                 'class' => 'yii\web\ErrorAction',
  6.             ],
  7.             'captcha' => [
  8.                 'class' => 'yii\captcha\CaptchaAction',
  9.                 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
  10.             ],
  11.         ];
  12.     }

actions继承yii\base\Actions类,并重写父类的run方法。

方法二:

site控制器如下,访问MemberController控制器下面的index方法。

  1. class SiteController extends Controller
  2. {
  3.     public function actionIndex(){
  4.      Yii::$app->runAction('member/index', ['param'=>'123']);
  5.     }
  6. }

MemberController控制器如下:

  1. class MemberController extends Controller
  2. {
  3.     public function actionIndex($param = '456'){
  4.      echo "second Controller".$param;
  5.     }
  6. }

访问:http://www.yii.dev/site/index.html

输出:second Controller123

14、点击下载,如下载安卓APK文件。

  1. public function actionDownload(){
  2.     return \Yii::$app->response->setDownloadHeaders("http://xxx.com/apk/com.trade.activity.3.0.8.apk");
  3.     //return \Yii::$app->response->sendFile("./com.trade.activity.3.0.8.apk");
  4. }

15、YII模块IP白名单设置,增加安全性

  1. $config['modules']['gii'] = [
  2.      'class' => 'yii\gii\Module',
  3.      'allowedIPs' => ['127.0.0.1', '::1','10.10.1.*'], 
  4. ];
  1. $config['modules']['debug'] = [
  2.     'class' => 'yii\debug\Module',
  3.     'allowedIPs' => ['127.0.0.1', '::1', '192.168.0.*', '192.168.33.1'],
  4. ];

16、防止 SQL 和 Script 注入

  1. use yii\helpers\Html;
  2. use yii\helpers\HtmlPurifier;
  3. echo Html::encode($view_hello_str) //可以原样显示<script></script>代码  
  4. echo HtmlPurifier::process($view_hello_str)  //可以过滤掉<script></script>代码

17、验证某个ID值是否存在

//之前一直用$model->findOne($id);exists()方法,资源节约,有没有?!

  1. public function validateAttribute($model, $attribute)
  2. {
  3.    $value = $model->$attribute;
  4.    if (!Status::find()->where(['id' => $value])->exists()) {
  5.        $model->addError($attribute, $this->message);
  6.    }
  7. }

18、批量查询

如查询并循环10000条数据。一次性拿1万条内存会有压力,通过批量查询,每次拿1000条,那么内存始终只有1000条的占有量。

  1. foreach(Member::find()->batch(1000) as $value){
  2.     //do something
  3.     //print_r(count($value));
  4. }

19、关于CSRF验证

方法一:关闭Csrf,除非必要,否则不推荐

  1. public function init(){
  2.     $this->enableCsrfValidation = false;
  3. }

方法二:普通提交,form表单中加入隐藏域

  1. <input name="_csrf" type="hidden" id="_csrf" value="<?= Yii::$app->request->csrfToken ?>">

方法三:ajax异步提交,加入_csrf字段

  1. var csrfToken = $('meta[name="csrf-token"]').attr("content");
  2. $.ajax({
  3.   type: 'POST',
  4.   url: url,
  5.   data: {_csrf:csrfToken},
  6.   success: success,
  7.   dataType: dataType
  8. });

20、YII命令行生成数据库文件

自动列出可用的migrate文件

  1. php yii migrate

从vendor/callmez/wechat/migrations目录下生成数据表

  1. php yii migrate --migrationPath=@callmez/wechat/migrations

从当前应用/migrations/db1下初始化数据到db1表

  1. php yii migrate --migrationPath=@app/migrations/db1 --db=db1

21.关联查询

  1. //客户表Model:CustomerModel 
  2. //订单表Model:OrdersModel
  3. //国家表Model:CountrysModel
  4. //首先要建立表与表之间的关系 
  5. //在CustomerModel中添加与订单的关系
  6.       
  7. Class CustomerModel extends \yii\db\ActiveRecord
  8. {
  9.     ...
  10.     
  11.     public function getOrders()
  12.     {
  13.         //客户和订单是一对多的关系所以用hasMany
  14.         //此处OrdersModel在CustomerModel顶部别忘了加对应的命名空间
  15.         //id对应的是OrdersModel的id字段,order_id对应CustomerModel的order_id字段
  16.         return $this->hasMany(OrdersModel::className(), ['id'=>'order_id']);
  17.     }
  18.      
  19.     public function getCountry()
  20.     {
  21.         //客户和国家是一对一的关系所以用hasOne
  22.         return $this->hasOne(CountrysModel::className(), ['id'=>'Country_id']);
  23.     }
  24.     ....
  25. }
  26.       
  27. // 查询客户与他们的订单和国家
  28. CustomerModel::find()->with('orders', 'country')->all();
  29. // 查询客户与他们的订单和订单的发货地址
  30. CustomerModel::find()->with('orders.address')->all();
  31. // 查询客户与他们的国家和状态为1的订单
  32. CustomerModel::find()->with([
  33.     'orders' => function ($query) {
  34.         $query->andWhere('status = 1');
  35.         },
  36.         'country',
  37. ])->all();

22、yii2中关闭debug后return $this->redirect($url);不能跳转,服务器报500错误。

问题分析:

1.必须 return 才能让$this->redirect($url);立马跳转, 而不执行后续代码;

2.redirect() 中指定了响应的 http status code,默认是302;

3.当执行$this->redirect($url)时,不管是否在后面加return false 、return true都没有用,还是继续执行完代码。使用header("Location:$url");exit;可以解决此问题,但是,这不是yii2的逻辑,并不完美。

解决办法:

【本文由php_sir的博客 http://blog.sina.com.cn/phpsir原创,未经授权禁止转载】

1.在正常情况下,使用 return $this->redirect($url);

2.在解决方案1不生效时,用$this->redirect($url);Yii::$app->response->send();

3.在解决方案2不生效时,用$this->redirect($url);Yii::$app->end();

总结:

用Yii::$app->end();、Yii::$app->response->send();不管在actionXXX还是init方法都能终止代码,而return只能在action终止代码,是因为在init()里仅仅是代码的执行,return只是代码返回。

YII2项目常用技能知识总结的更多相关文章

  1. atitit 商业项目常用模块技术知识点 v3 qc29

    atitit 商业项目常用模块技术知识点 v3 qc29 条码二维码barcodebarcode 条码二维码qrcodeqrcode 条码二维码dm码生成与识别 条码二维码pdf147码 条码二维码z ...

  2. IDEA第五章----Git常用技能

    前几篇已经介绍了idea的环境搭建及基础配置常用模板等,这一章我们介绍下idea中git的一些常用技能,包括提交文件,排除提交文件,合并分支,解决冲突,还原代码等等等. 第一节:Git常用技能 Git ...

  3. java项目常用 BaseDao BaseService

    java项目常用 BaseDao BaseService IBaseDao 1 package com.glht.sim.dao; 2 3  import java.util.List; 4 5 6 ...

  4. 项目常用jquery/easyui函数小结

    #项目常用jquery/easyui函数小结 ##背景 项目中经常需要使用到一些功能,封装.重构.整理后形成代码沉淀,在此进行分享 ##代码 ```javascript /** * @author g ...

  5. Git应用于Android项目的入门知识:我的理解

    Git应用于Android项目的基本知识.     常常将git,repo和gerrit三种工具配合起来使用,使Android开发中的部分工作自动化.并适应敏捷项目管理的需要.     repo是Go ...

  6. Word常用实用知识1

    Word常用实用知识1 纯手打,可能有错别字,使用的版本是office Word 2013 转载请注明出处,谢谢. 快速输入日期(含格式) [插入]--[日期]   快速输入日期和时间(快捷键) 快速 ...

  7. yii2项目实战-路由美化以及如何正确的生成链接

    yii2项目实战-路由美化以及如何正确的生成链接 更新于 2016年12月17日 by 白狼 被浏览了 705 次 美化路由 何为美化路由呢?美化嘛,无外乎就是给路由化化妆,让她好看点.我虽没化过妆, ...

  8. 在 Yii2 项目中使用 Composer 添加 FontAwesome 字体资源

    2014-06-21 19:05 原文 简体 繁體 2,123 次围观 前天帮同事改个十年前的网站 bug,页面上一堆 include require 不禁让人抱头痛哭.看到 V2EX 上的讨论说,写 ...

  9. React Native 项目常用第三方组件汇总

    React Native 项目常用第三方组件汇总 https://www.jianshu.com/p/d9cd9a868764?utm_campaign=maleskine&utm_conte ...

随机推荐

  1. ps还能用脚本切片?

    最近在慕课网上看有关于ps切图的视频,发现ps 切片的水还挺深的.这相当于我的一篇学习笔记吧.对于ps的基本切图我觉得对于前端人员来说就是a piece of cake.但是对于ps的精准切图,我不知 ...

  2. tarjan求桥、割顶

    若low[v]>dfn[u],则(u,v)为割边.但是实际处理时我们并不这样判断,因为有的图上可能有重边,这样不好处理.我们记录每条边的标号(一条无向边拆成的两条有向边标号相同),记录每个点的父 ...

  3. 【poj2699】 The Maximum Number of Strong Kings

    http://poj.org/problem?id=2699 (题目链接) 题意 给出1张有向完全图.U->V表示U可以打败V并得一分.如果一个人的得分最高,或者他打败所有比自己得分高的人,那么 ...

  4. cmd执行命令返回执行信息

    /// <summary> /// 执行CMD语句 /// </summary> /// <param name="cmd">要执行的CMD命令 ...

  5. 代理IP收集

    做系统攻击和防守时都有用! http://www.xicidaili.com/ http://www.data5u.com/ http://ip.zdaye.com/ http://www.youda ...

  6. ECMall /app/buyer_groupbuy.app.php SQL Injection Vul

    catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 Relevant Link: 2. 漏洞触发条件 0x1: POC ht ...

  7. dedecms /plus/stow.php Twice SQL Injection

    catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 收藏文章功能$title变量未过滤,造成二次注入 Relevant Li ...

  8. windows核心编程读后感(待续)

    自从大一读那本超厚的C程序设计以后,从来没有像这样慢慢地读一本书了.windows核心这本书足足看了2个多星期.一张张慢慢看,做笔记.感觉学到了很多基础的知识,关于内核方面的没有啥可以做实验的,都在看 ...

  9. C#的委托和事件(delegate)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Dele ...

  10. AngularJs $rootScope.Scope 作用域操作

    这里讲的是一些scope的操作,如创建/注销/各种监听及scope间的通信等等. $rootScope.Scope 可以使用$injector通过$rootScope关键字检索的一个根作用域. 可以通 ...