参考地址:http://www.cnblogs.com/sandea/p/5714830.html

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. Yii2开发小技巧

    工作中或多或少会用到的关于 Yii2 的小技巧的一个总结,包括model.controller.view或者配置文件的一些写法. 模型相关 获取查询SQL $query = User::find()- ...

  2. PHP开发者该知道的5个Composer小技巧

    Composer 是新一代的PHP依赖管理工具.本文介绍使用Composer的五个小技巧,希望能给你的PHP开发带来方便. 1. 仅更新单个库 只想更新某个特定的库,不想更新它的所有依赖,很简单 co ...

  3. 前端网络、JavaScript优化以及开发小技巧

    一.网络优化 YSlow有23条规则,中文可以参考这里.这几十条规则最主要是在做消除或减少不必要的网络延迟,将需要传输的数据压缩至最少. 1)合并压缩CSS.JavaScript.图片,静态资源CDN ...

  4. Git小技巧 - 指令别名及使用Beyond Compare作为差异比较工具

    前言 本文主要写给使用命令行来操作Git的用户,用于提高Git使用的效率.至于使用命令还是GUI(Tortoise Git或VS的Git插件)就不在此讨论了,大家根据自己的的喜好选择就好.我个人是比较 ...

  5. 分享两个BPM配置小技巧

    1.小技巧 流程图修改后发布的话版本号会+1,修改次数多了之后可能会导致版本号很高,这个时候可以将流程导出,然后删除对应的流程包再导入,发布数据模型和流程图之后,版本清零 2.小技巧 有的同事入职后使 ...

  6. linux系统维护时的一些小技巧,包括系统挂载新磁盘的方法!可收藏!

    这里发布一些平时所用到的小技巧,不多,不过会持续更新.... 1.需要将history创建硬链接ln 全盘需要备份硬链接 ln /etc/xxx /home/xxx 2.root用户不可以远程 /et ...

  7. JS处理事件小技巧

    今天,就分享一下我自己总结的一些JS的小技巧: ①防止鼠标选中事件 <div class="mask" onselectstart="return false&qu ...

  8. iOS:小技巧(不断更新)

    记录下一些不常用技巧,以防忘记,复制用. 1.获取当前的View在Window的frame: UIWindow * window=[[[UIApplication sharedApplication] ...

  9. css小技巧(1)

    1.-webkit-overflow-scrolling: touch; 解决ios滑动时无缓冲问题 2.::-webkit-scrollbar 设置ios滑动时是否显示滚动条 3.::selecti ...

随机推荐

  1. 【收藏】Android AutoLayout全新的适配方式, 堪称适配终结者

    来源:http://blog.csdn.net/lmj623565791/article/details/49990941 更多:Android屏幕适配全攻略(最权威的Google官方适配指导) 一. ...

  2. 给<tr>标签添加边框

    今天做网站时发现给<tr>添加border无效.起初还以为tr不支持这个属性,百度,原来只要给<table>添加一句代码就可以了,代码如下: table{border-coll ...

  3. struct和typedef struct用法

    参考:http://www.cnblogs.com/qyaizs/articles/2039101.html C语言: typedef struct Student{ int score; }Stu; ...

  4. Linux下执行.sh文件

    Linux下执行.sh文件有两种情况: 一.直接./加上文件名.sh,如运行hello.sh为./hello.sh[hello.sh必须有x权限] 二.直接sh 加上文件名.sh,如运行hello.s ...

  5. c# 文件转换成base64

    private static void ReadFromFile() { FileStream fsForRead = new FileStream("c9a78c8a-29b0-410d- ...

  6. SQL Server发布订阅功能研究

    前提: 发布订阅只能是同一个内网的机器上才能使用,其实这个可以用配置管理器的别名功能设置之后就可以了,外网的也能通过这样的方式来搞. 配置过程参考老D的文章:http://www.cnblogs.co ...

  7. SqlServerException:拒绝对表对象的select,insert权限解决(新建账号导致的问题)

    继上一篇文章所述的问题,这次又出现了不能插入的问题.经过定位,也是由于我多选择了一个数据库用户角色的权限导致的,下面是详细的操作步骤 SqlServerException:拒绝了对对象 '...'(数 ...

  8. Android知识体系图

    网上看到,不知哪位大神总结的,存个档(需要放大网页才能看清)

  9. GridView控件RowDataBound事件的一个实例

    实现点击两个按钮,跳转到同一个界面,HyperLink显示不同的东西,主要代码段如下 前台代码: <asp:TemplateField HeaderText="操作"> ...

  10. HDU 2544 单源最短路

    题目链接: 传送门 最短路 Time Limit: 1000MS     Memory Limit: 65536K 题目描述 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是 ...