表單驗證
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 ],];
}
public
function rules ()
{
return [[title', 'content'],'trim']] ;
}
校驗 user_id 在User表中是否存在,并自定義錯誤信息。
public
function rules()
{
return [
... [[
'user_id' ],
'exist' ,
'targetClass' => User::className(),
'targetAttribute' =>
'id' ,
'message' =>
'此{attribute}不存在。' ],
... ];
}
[[
'store_id' ,
'member_name' ],
'unique' ,
'targetAttribute' => [
'store_id' ,
'member_name' ],
'message' =>
'The combination of Store ID and Member Name has already been taken.' ],
echo array_values(
$model ->getFirstErrors())[
0 ];
exit ;
var_dump(
$model ->getErrors());
die ;
新建一個Behavior
use Yii ;
use yii \
base \
Behavior ;
use yii \
web \
Controller ;
class NoCsrf extends Behavior
{public $actions = [];
public $controller ;
public function events () {return [Controller::EVENT_BEFORE_ACTION =>
'beforeAction' ];}
public function beforeAction ($event ) {$action =
$event ->action->id;
if (in_array(
$action ,
$this ->actions)){
$this ->controller->enableCsrfValidation =
false ;}}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
然后在Controller中添加Behavior
public function behaviors ()
{return [
'csrf' => [
'class' => NoCsrf::className(),
'controller' =>
$this ,
'actions' => [
'action-name' ]]];
}
數據查詢
User ::find
() ->where([
'and' , [
'xxx' => 0 ,
'yyy' => 2 ], [
'>' ,
'zzz' , $time]]);
查詢的時候 where 的 OR 和 AND 一起用
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 * FROM `post_comment` WHERE `status` =1 ORDER BY `created_at` DESC ) `tmpA` GROUP BY `post_id`
$query =
static ::find
() ->select
(['package_uuid' , 'count(*) AS count' , 'cost' , 'package_shop_id' ]) ->groupBy(
'package_uuid' );
-> orderBy
('count DESC' ) ->limit(
10 );
$quert =
User ::find
() ->select([
new Expression(
'count(*) as count , count(distinct mobile) as mnumber' )])
-> asArray
() ->all();
[
'like' ,
'name' ,
'tester' ] 會生成 name LIKE
'%tester%' 。[
'like' ,
'name' ,
'%tester' ,
false ]
=> name LIKE
'%tester' $query =
User ::find
() ->where([
'LIKE' ,
'name' , $id.
'%' ,
false ]);
$query =
new Query;
$query->select
('ID, City,State,StudentName' ) ->from
('student' ) ->where
(['IsActive' => 1 ]) ->andWhere
(['not' , ['State' => null ]]) ->orderBy
(['rand()' => SORT_DESC]) ->limit(
10 );
yii2 多表聯查 where條件里 A表字段=B表字段怎么表示?
$res =
self ::find
()
->select
(['a.id' ,'a.name' ])
->join
('LEFT JOIN' ,'b' ,'b.qid=a.id' )
->join
('LEFT JOIN' ,'c' ,'c.uid=b.uid' )
->where
(['a.state' =>0 , 'b.state' =>0 , 'c.state' =>0 , 'c.uid' =>123456 ])
->asArray
() ->all();
$query->andWhere(
new \yii\db\Expression(
'c.type = b.type' ));
$query->andWhere
(['<' , '`updated_at` + `duration`' , time()]) ->all();
$query = Weibo::find()->joinWith(
'account' )->where([
'and' ,[
'is_forward' =>
0 ],[
'status' => Weibo::STATUS_NORMAL_WITH_STAT],[
'account_open_id' =>
$account_list ],[
'read_limit_time' =>
null ],
])->andWhere(
"`posted_at` BETWEEN {$now}-`account`.`scrape_time`*60 AND {$now}-`account`.`scrape_time`*60+60" );
$commandQuery =
clone $query ;
echo $commandQuery ->createCommand()->getRawSql();
$weibo =
$query ->all();
輸出語句:
SELECT
`w eibo
`. * FROM
`w eibo
`
LEFT JOIN
`a ccount
`
ON
`w eibo
`. `a ccount_open_id
` =
`a ccount
`. `o pen_id
`
WHERE ((
`i s_forward
`= 0 )
AND (
`s tatus
`= 1 )
AND (
`a ccount_open_id
` IN ('
123456789 ', '
987654321 ', '
098765432 ', '
234123455 '))
AND (
`r ead_limit_time
` IS NULL))
AND (
`p osted_at
` BETWEEN
1474946053 -
`a ccount
`. `s crape_time
`* 60 AND 1474946053 -
`a ccount
`. `s crape_time
`* 60 +
60 )
$dataProvider =
$searchModel ->search(Yii::
$app ->request->queryParams);
$dataProvider ->query->andWhere([
'pid' =>
0 ]);
如果要用 find_in_set 需要使用到 Expression 表達式:
User ::find
() ->where
(new Expression('FIND_IN_SET(:status, status)' )) ->addParams
([':status' => 1 ]) ->all();
MySQL 數據處理
yii2 給mysql數據庫表添加字段后,立即使用這個字段時會出現未定義的情況(Getting unknown property)
原因:yii 對數據表結構進行了緩存。
方法1. 清理掉runtime下的cache緩存之后也可以正常使用這個字段。
方法2. 修改完表字段后執行
# 清理指定表結構緩存數據
Yii ::$app->db->getSchema()->refreshTableSchema($tableName);或
# 清理所有表結構緩存數據
Yii ::$app->db->getSchema()->refresh();
建議將以上代碼添加到修改數據表結構的migration中。
static ::find
()
->where([
'user_id' => $user_id,
])
-> groupBy
('uuid' )
->all();
static ::find
()
->select
(['uuid' ])
->where([
'user_id' => $user_id,
])
-> distinct
()
->count();
static ::find
() ->where([
'user_id' => $user_id,
])
-> count(
'distinct uuid' );
$transaction = Yii::$app->db->beginTransaction();
try {//
... SQL executions$transaction->commit();
} catch (Exception $e) {$transaction->rollBack();
}
關于事務:
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 ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
查找 auth_times 表 type=1 并且 不存在 auth_item 表里面的數據
// AuthItem.php 關鍵是 onCondition 方法
public
function getAuthTimes()
{
return $
this ->hasOne
(AuthTimes::className(), ['name' => 'name' , ]) ->onCondition([
AuthTimes ::tableName() .
'.type' => 1 ]);
}
// AuthTimes.php 文件
// ......
AuthItem ::find
() ->joinWith
('authTimes' ) ->where
([self::tableName() . '.name' => null ]) ->all();
生成SQL:
SELECT
`a uth_item
`. * FROM
`a uth_item
` LEFT JOIN
`a uth_times
` ON
`a uth_item
`. `n ame
` =
`a uth_times
`. `n ame
` AND `a uth_times
`. `t ype
` =
1 WHERE
`a uth_times
`. `n ame
` IS NULL
$styleId = Yii::
$app ->request->get(
'style' );
$collection = Yii::
$app ->db->cache(
function ($db ) use ($styleId ) {return Collection::findOne([
'style_id' =>
$styleId ]);
},
self ::SECONDS_IN_MINITUE *
10 );
$model =
new User();
foreach (
$data as $attributes )
{
$_model =
clone $model ;
$_model ->setAttributes(
$attributes );
$_model ->save();
}
第二種方法
$model = new User();
foreach(
$data as
$attributes )
{
$model -> isNewRecord
= true ;
$model -> setAttributes(
$attributes );
$model -> save()
&& $model -> id
= 0 ;
}
URL
假設我們當前頁面的訪問地址是:http://localhost/public/index.php?r=news&id=1
# http://localhost
Yii ::$app->request->getHostInfo()
Yii ::$app->request->getPathInfo()
# /public/index.php?r=news&id=1
Yii ::$app->request->url
或者
Yii ::$app->request->requestUri
Yii ::$app->request->getHostInfo
() . Yii ::app () ->request->url
Yii ::$app->getRequest
() ->queryString
Yii ::$app->getRequest
() ->getQuery(
'id' );
//g et parameter
'id'
Yii::
$app ->user->
return Url;
Yii ::$
app -> request -> headers [
'Referer' ]
或者
Yii ::$
app -> getRequest ()
-> getReferrer ()
前端顯示
當GridView和DetailView列表中的某一條內容為連續的英文或數字(比如網站鏈接等)時,該內容會不換行,導致該列寬度被頂的特別長,甚至超出div的寬度。
在全局Css中添加以下樣式:
word-break:break-all; //只對英文起作用,以字母作為換行依據
eg:
html ,
body {height : 100 % ;font-family : "Microsoft YaHei" ;word-break : break-all ;
}
css :
div .required label :after {content : " *" ;color : red ;
}
控制器獲取當前Module name,Controller name和action name
#在控制器里面使用
$
this -> module -> id ;
$
this -> id ;
$
this -> action -> id ;#其他位置使用
\
Yii ::$
app -> controller -> module -> id ;
\
Yii ::$
app -> controller -> id ;
\
Yii ::$
app -> controller -> action -> id ;
use yii
\ log \ Logger;
\ Yii
::getLogger ()
-> log (
'User has been created' , Logger
::LEVEL_INFO );
\
Yii ::$app->request->rawBody;
有兩種方式獲取查詢出來的 name 為數組的集合 [name1, name2, name3]:
方式一:
return \yii\helpers\
ArrayHelper ::getColumn
(User::find()->all(), 'name' ) ;
方式二:
return User ::find
() ->select
('name' ) ->asArray
() ->column();
use yii \
helpers \
Html ;
use yii \
helpers \
HtmlPurifier ;
echo Html::encode(
$view_hello_str )
echo HtmlPurifier::process(
$view_hello_str )
use yii \
helpers \
VarDumper ;
VarDumper::dump(
$var );
VarDumper::dump(
$var ,
10 ,
true );
die ;
restful 獲取 GET 和 POST 過來的數據(得到結果是數組):
Yii::
$app ->request->bodyParams
Yii::
$app ->request->queryParams;
Html::a(
"鏈接1" , \yii\helpers\Url::toRoute([
'product/view' ,
'id' =>
42 ]);
Html::a(
"鏈接2" , Yii::
$app ->urlManager->createUrl([
'mysql/chart' ,
'id' =>
43 ,
'time_interval' =>
'1800' ,
'end' =>
'0' ]));
Yii::
$app ->runAction(
'new_controller/new_action' ,
$params );
return (
new SecondController(
'second' , Yii::
$app ->module))->runAction(
'index' ,
$data );
public function actionDownload ($id )
{$model =
$this ->findModel(
$id );
if (
$model ) {}
return \Yii::
$app ->response->setDownloadHeaders(
$model ->downurl);}
發送郵件? a.config/config.php中的components配置
'mailer' => [
'class' =>
'yii\swiftmailer\Mailer' ,
'useFileTransport' =>
false ,
'transport' => [
'class' =>
'Swift_SmtpTransport' ,
'host' =>
'smtp.gmail.com' ,
'username' =>
'admin@gmail.com' ,
'password' =>
'password12345678' ,
'port' =>
587 ,
'encryption' =>
'tls' ,]
],
b.使用
Yii ::$app->mailer->compose
() ->setFrom
(['admin@gmail.com' => Yii::$app->name]) ->setTo
('admin@gmail.com' ) ->setSubject
('test subject' ) ->setTextBody
('test body' ) ->send();
修改登陸狀態超時時間(到期后自動退出登陸) config/web.php中的components
‘user’ => [? ‘class’=>’yii\web\User’,? ‘identityClass’ => ‘common\models\User’,? ‘loginUrl’=>[‘/user/sign-in/login’],? ‘authTimeout’ => 1800,//登陸有效時間? ‘as afterLogin’ => ‘common\behaviors\LoginTimestampBehavior’? ],
修改返回的數據格式(詳見Response::FORMAT_XXXX)
$result =
array (
'code' =>
$code ,
'msg' =>
$msg ,
'data' =>
$data );
$callback = Yii::
$app ->request->get(
'callback' ,
null );
$format =
$callback ? Response::FORMAT_JSONP : Response::FORMAT_JSON;
Yii::
$app ->response->format =
$format ;
if (
$callback ){
return array (
'callback' =>
$callback ,
'data' =>
$result );
}
return $result ;
場景: 數據庫有user表有個avatar_path字段用來保存用戶頭像路徑
需求: 頭像url需要通過域名http://b.com/作為基本url
目標: 提高代碼復用
此處http:
示例:
User.php
class User extends \yii \db \ActiveRecord
{...
public function extraFields () {$fields =
parent ::extraFields();
$fields [
'avatar_url' ] =
function () {return empty (
$this ->avatar_path) ?
'可以設置一個默認的頭像地址' :
'http://b.com/' .
$this ->avatar_path;};
return $fields ;}...
}ExampleController.php
class ExampleController extends \yii \web \Controller
{public function actionIndex () {$userModel = User::find()->one();
$userData =
$userModel ->toArray([], [
'avatar_url' ]);
echo $userData [
'avatar_url' ]; }
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
Yii2-GridView 中讓關聯字段帶搜索和排序功能? 情境要求:? 要在訂單(Order)視圖的gridview中顯示出客戶(Customer)姓名,并使其具有與其它字段相同的排序和搜索功能。
數據庫結構? 訂單表order含有字段customer_id 與 客戶表customer的id字段關聯
首先確保在Order Model中包含以下代碼:
public function getCustomer ()
{return $this ->hasOne(Customer::className(), [
'id' =>
'customer_id' ]);
}
用gii會自動生成此代碼;
第一步:? 在OrderSearch添加一個$customer_name變量
class OrderSearch extends Order
{public $customer_name ;
}
第二步:? 修改OrderSearch中的search函數
public function search ($params )
{$query = Order::find();
$query ->joinWith([
'customer' ]);<=====加入這句
$dataProvider =
new ActiveDataProvider([
'query' =>
$query ,]);
$dataProvider ->setSort([
'attributes' => [
'customer_name' => [
'asc' => [
'customer.customer_name' => SORT_ASC],
'desc' => [
'customer.customer_name' => SORT_DESC],
'label' =>
'Customer Name' ],]]);
if (!(
$this ->load(
$params ) &&
$this ->validate())) {
return $dataProvider ;}
$query ->andFilterWhere([
'id' =>
$this ->id,
'user_id' =>
$this ->user_id,
'customer_id' =>
$this ->customer_id,
'order_time' =>
$this ->order_time,
'pay_time' =>
$this ->pay_time,]);
$query ->andFilterWhere([
'like' ,
'status' ,
$this ->status]);
$query ->andFilterWhere([
'like' ,
'customer.customer_name' ,
$this ->customer_name]) ;
return $dataProvider ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
第三步:? 修改order/index視圖的gridview
<? = GridView::widget(['dataProvider' => $dataProvider ,'filterModel' => $searchModel ,'columns' => [['class' => 'yii\grid\SerialColumn' ],'id' ,'customer_id' , 'status' ,['label' =>'客戶' , 'attribute' => 'customer_name' , 'value' => 'customer.customer_name' ],['class' => 'yii\grid\ActionColumn' ],],
]); ?>
[
'attribute' =>
'source' ,
'format' =>
'raw' ,
'value' =>
function ($model ) {return '<pre>' . Json::encode(Json::decode(
$model ->source), JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT) .
'</pre>' ;}
],
郵件發送
注意,使用郵件發送前發送郵件的郵箱必須開啟 POP3/SMTP/IMAP 服務,請在郵箱賬號設置中自行開啟
'mailer' => [
'class' => 'yii\swiftmailer\Mailer' ,
// 'viewPath' => '@common/mail' ,
// 默認把所有郵件發送到一個文件里,若需要發送真郵件,你需要把userFileTransport設置為
false ,并且添加郵件的配置
'useFileTransport' => false ,
'transport' => [
'class' => 'Swift_SmtpTransport' ,
'host' => 'smtp.126.com' ,
'username' => 'xxx@126.com' ,
'password' => '<your passwd>' ],
'messageConfig' => [
'charset' => 'UTF-8' ,
'from' => [
'xxx@126.com' => '發件人名稱' ]],
],
$mail=
Yii ::$app->mailer->compose
() ->setTo
('<target_email@qq.com>' ) ->setSubject
('郵件標題' ) ->setHtmlBody(
'郵件內容' );
if ($mail->send()) {echo
'發送成功' ;
}
else {echo
'發送失敗' ;
} 參考文獻:https://blog.csdn.net/qq_16885135/article/details/52642952
總結
以上是生活随笔 為你收集整理的Yii2一些方法技巧小记 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。