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

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

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

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

Member::find()->select('userid')->asArray()->all();
Array
(
    [0] => Array
        (
            [userid] => 1
        )     [1] => Array
        (
            [userid] => 2
        )     [2] => Array
        (
            [userid] => 3
        ) )

返回字段的一维数组

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

或者:

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

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

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

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

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

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

3、友好时间表示方法

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

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

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

有效的格式:

  • FORMAT_RAW

  • FORMAT_HTML

  • FORMAT_JSON

  • FORMAT_JSONP

  • FORMAT_XML

JSON响应

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

返回:

{
    "0": "some",
    "1": "array",
    "2": "of",
    "data": ["associative", "array"]
}

自定义响应格式

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

<?php
namespace app\components;
use yii\helpers\VarDumper;
use yii\web\ResponseFormatterInterface;
class PhpArrayFormatter implements ResponseFormatterInterface
{
    public function format($response)
    {
        $response->getHeaders()->set('Content-Type', 'text/php; charset=UTF-8');
        if ($response->data !== null) {
            $response->content = "<?php\nreturn " . VarDumper::export($response->data) . ";\n";
        }
    }
}

组件配置:

return [
    // ...
    'components' => [
        // ...
        'response' => [
            'formatters' => [
                'php' => 'app\components\PhpArrayFormatter',
            ],
        ],
    ],
];

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

public function actionTest()
{
    Yii::$app->response->format = 'php';
    return [
        'hello' => 'world!',
    ];
}

返回如下:

<?php
return [
    'hello' => 'world!',
];

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

如下:

public function behaviors()
{
    return [
        'timestamp' => [
            'class' => TimestampBehavior::className(),
            'attributes' => [
                ActiveRecord::EVENT_BEFORE_INSERT => 'creation_time',
                ActiveRecord::EVENT_BEFORE_UPDATE => 'update_time',
            ],
            'value' => function() { return date('U'); // unix timestamp },
        ],
    ];
}

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

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

7、 ActiveForm类不让生成label标签

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

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

div.required label:after {
    content: " *";
    color: red;
}

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

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

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

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

public function rules()
{
    return [
        [['telephone', 'mobile'], function ($attribute, $param) {//至少要一个
            if (empty($this->telephone) && empty($this->mobile)) {
                $this->addError($attribute, 'telephone/mobile至少要填一个');
            }
        }, 'skipOnEmpty' => false],
    ];
}

10、where多条件查询示例:

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

11、关于事务:

优雅的写法

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

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

$transaction = Yii::$app->db->beginTransaction();
try {
    $order = new Order($customer);
    $order->save();
    $transaction->commit();
} catch (\Exception $e) {
    $transaction->rollBack();
    throw $e;
}

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

// post
Yii::$app->request->bodyParams
// get
Yii::$app->request->queryParams;

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

方法一:

是经典的重写actions方法

  public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
            'captcha' => [
                'class' => 'yii\captcha\CaptchaAction',
                'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
            ],
        ];
    }

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

方法二:

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

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

MemberController控制器如下:

class MemberController extends Controller
{
    public function actionIndex($param = '456'){
     echo "second Controller".$param;
    }
}

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

输出:second Controller123

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

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

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

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

16、防止 SQL 和 Script 注入

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

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

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

public function validateAttribute($model, $attribute)
{
   $value = $model->$attribute;
   if (!Status::find()->where(['id' => $value])->exists()) {
       $model->addError($attribute, $this->message);
   }
}

18、批量查询

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

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

19、关于CSRF验证

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

public function init(){
    $this->enableCsrfValidation = false;
}

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

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

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

var csrfToken = $('meta[name="csrf-token"]').attr("content");
$.ajax({
  type: 'POST',
  url: url,
  data: {_csrf:csrfToken},
  success: success,
  dataType: dataType
});

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

自动列出可用的migrate文件

php yii migrate

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

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

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

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

21.关联查询

//客户表Model:CustomerModel 
//订单表Model:OrdersModel
//国家表Model:CountrysModel
//首先要建立表与表之间的关系 
//在CustomerModel中添加与订单的关系
      
Class CustomerModel extends \yii\db\ActiveRecord
{
    ...
    
    public function getOrders()
    {
        //客户和订单是一对多的关系所以用hasMany
        //此处OrdersModel在CustomerModel顶部别忘了加对应的命名空间
        //id对应的是OrdersModel的id字段,order_id对应CustomerModel的order_id字段
        return $this->hasMany(OrdersModel::className(), ['id'=>'order_id']);
    }
     
    public function getCountry()
    {
        //客户和国家是一对一的关系所以用hasOne
        return $this->hasOne(CountrysModel::className(), ['id'=>'Country_id']);
    }
    ....
}
      
// 查询客户与他们的订单和国家
CustomerModel::find()->with('orders', 'country')->all(); // 查询客户与他们的订单和订单的发货地址
CustomerModel::find()->with('orders.address')->all(); // 查询客户与他们的国家和状态为1的订单
CustomerModel::find()->with([
    'orders' => function ($query) {
        $query->andWhere('status = 1');
        },
        'country',
])->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. Spark MLib 数据类型

    1.  MLlib Apache Spark's scalable machine learning library, with APIs in Java, Scala and Python. 2. ...

  2. UVa 1328 Period

    数据范围较大,故用KMP求循环节 之后由小到大枚举长度范围,若该长度下有循环节就输出答案 还要注意输出格式.之前测试时候连着一串presentation error也是悲伤 #include<b ...

  3. linux文件系统简介

    文件系统是linux的一个十分基础的知识,同时也是学习linux的必备知识. 本文将站在一个较高的视图来了解linux的文件系统,主要包括了linux磁盘分区和目录.挂载基本原理.文件存储结构.软链接 ...

  4. Spring Cache 介绍

    Spring Cache 缓存是实际工作中非常常用的一种提高性能的方法, 我们会在许多场景下来使用缓存. 本文通过一个简单的例子进行展开,通过对比我们原来的自定义缓存和 spring 的基于注释的 c ...

  5. AC 自动机

    AC自动机(Aho-Corasick Automata)是经典的多模式匹配算法.从前我学过这个算法,但理解的不深刻,现在已经十分不明了了.现在发觉自己对大部分算法的掌握都有问题,决定重写一系列博客把学 ...

  6. python合并2个字典

    2种方式,update()和items()方式 In [14]: a Out[14]: {'a': 1, 'b': 2, 'c': 3} In [15]: c = {'d': 4} In [16]: ...

  7. POJ - 2253 Frogger(Dijkstra变形题)

    题意: 题目撰写者的英语真是艰难晦涩,看了别人题解,才知道这题题意. 两个forger 一个froger 要蹦到另外一个froger处,他们的最短距离是这样定义的 : The frog distanc ...

  8. XML学习笔记

    XML学习笔记 第一部分:XML简介 我们经常可以听到XML.HTML.XHTML这些语言,后两者比较清楚,一直不是很明白XML是什么,这里做一个总结. XML(eXtensible Markup L ...

  9. javascript中对象字面量的理解

    javascript中对象字面量与数组字面量 第一部分 我们知道JavaScript中的数据类型有基本数据类型和引用类型,其中Object类型就是非常常用的类型.那么如果创建一个Object类型的实例 ...

  10. BZOJ3082: Graph2

    经典问题.强制在线的话非常复杂. 考虑离线. 每条边的存在时间是一个区间,因此按时间建立一颗线段树,将每条边插入,拆成log条边.然后dfs线段树,每次并查集合并当前节点的所有边,到叶子节点时回答询问 ...