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_RAWFORMAT_HTMLFORMAT_JSONFORMAT_JSONPFORMAT_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...

输入: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' = [

 'class' => 'yii\gii\Module', 'allowedIPs' => ['127.0.0.1', '::1','10.10.1.*'], 

];

$config'modules' = [

'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/phpsi...

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只是代码返回。