婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Yii2框架中一些折磨人的坑

Yii2框架中一些折磨人的坑

熱門標簽:青島語音外呼系統招商 百應電話機器人服務 山西回撥外呼系統 揚州地圖標注app 河南電銷卡外呼系統哪家強 山西探意電話機器人 岳陽外呼型呼叫中心系統在哪里 騰訊外呼管理系統 昭通辦理400電話

說點閑話

距離上次寫博客,已經有一年了。在動手寫之前,總是帶著深深的罪惡感。被它折磨許久,終于,還是,動手了。

值得慶祝的一件事:最近開始健身了。每天動感單車45分鐘,游泳45分鐘,真的是(生)爽(不)到(如)爆(死)。

好了,扯淡完畢,步入正題。

ActiveRecord被莫名寫入?

準備知識

ActiveRecord的基本用法。如果不理解,可參考這里。

代碼現場

/**
 * @property integer $id
 * @property string $name
 * @property string $detail
 * @property double $price
 * @property integer $area
 **/
class OcRoom extends ActivieRecord
{
 ...
}

$room = OcRoom::find()  //先取出一個對象。
 ->select(['id'])  //只取出'id'列
 ->where(['id'=>20])
 ->one();
$room->save();    //保存,會發現此行的其它字段都被寫成默認值了。

總結問題

這個例子的問題在于:

  1. 我從數據庫中取出了一行,也就是代碼中的$room,但是只取出了id字段,而其他字段自然就是默認值。
  2. 當我$room->save()的時候,那些是默認值的字段也被保存到數據庫里去了。what!?
  3. 也就是說,當你想節約資源,不取出所有字段的時候,一定要注意不能保存,否則,很多數據會被莫名修改為默認值。

解決方法

然而,我們有什么解決辦法呢?提供幾種思路:

  1. 自己時刻注意,避免未完全取出的ActiveRecord的保存。
  2. 修改或繼承ActiveRecord, 使得,當此對象由find()新建,且字段沒有完全取出,調用save()方法,拋出異常。
  3. 修改或繼承ActiveRecord,使得,當此對象由find()新建,且字段沒有完全取出,調用save()方法時,只保存取出過的字段,其他字段被忽略。

你的Transaction生效了嗎?

代碼現場

/**
 * @property integer $id
 * @property string $name
 **/
class OcRoom extends ActiveRecord
{
 public function rules()
 {
  return [['name','string','min'=>2,'max'=>10]];
 }
 ...
}
class OcHouse extends ActiveRecord
{
 public function rules()
 {
  return [['name','string','max'=>10]];
 }
 ...
}

$a = new OcRoom();
$a->name = '';    //name為空字符串,不滿足rules()條件。

$b = new OcHouse();
$b->name = '我的房間';   //name合法,可以保存。

$transaction = Yii::$app->db->beginTransaction();
try{
 $a->save();    //name字段不合法,無法驗證通過,在validate()階段已經返回false,不會進行數據庫存儲的步驟,所以也不會拋出異常。
 $b->save();    //name字段合法,可以正常保存。

 $transaction->commit(); //提交后,發現$a保存失敗,而$b保存成功。
}
catch (Exception $e) 
{
 Yii::error($e->getTraceAsString(),__METHOD__);
 $transaction->rollBack();
}

問題總結

這段代碼的問題在于:

  1. 大家知道$transaction的存在意義是保證整段數據庫存儲代碼要么全成功,要么全失敗。
  2. 顯然,在這個例子中,transaction并沒有達到我們想要的效果:$a因為validate()都沒過,所以$transation->commit()的時候并不會報錯。

解決方法

在$transation塊內,所有的save()都要判斷下返回值,如果為false,則直接拋出異常。

'Y-m-d'不被識別?

代碼現場

OcRenterBill extends ActiveRecord
{
 public function rules()
 {
  return [
   ['start_time','date','format'=>'Y-m-d'],
  ];
 }
}

$a = new OcRenterBill();
$a = '2015-09-12';
$a->save();     //會報錯,說格式不對

問題總結

如果一開始,Yii框架就報錯,這個還不算坑。坑的是我在Mac上開發時,這個可以完全正常的工作,而發布到線上環境(Ubuntu)后,就彈出“屬性start_time格式無效”的錯誤。而參考官方文檔,發現這種格式是允許的官方文檔。

啊啊啊。各種試錯,最后發現如果改成php:Y-m-d,世界就清凈了。所以,如果你遇到這種問題,感激我吧。

內存泄露

代碼現場

public static function actionTest() {
  $total = 10;
  var_dump('開始內存'.memory_get_usage());
  while($total){
   $ret=User::findOne(['id'=>910002]);
   var_dump('end內存'.memory_get_usage());
   unset($ret);
   $total--;
  }
 }

上面代碼的內存一直在增長, 按照原本想法來看, 變量被釋放了,內存就算增長也不會一直增長。因為每循環一次內存都會被釋放。

分析問題 上面這段代碼涉及到了數據庫的操作,而我們知道,數據庫的很多地方都能引起內存泄漏。 所以先屏蔽數據庫相關操作, 我手寫了一個原生的數據庫查詢操作, 發現內存正常,沒有問題。

$dsn = "mysql:dbname=test;host=localhost";
$db_user = 'root';
$db_pass = 'admin';
//查詢
$sql = "select * from buyer";
$res = $pdo->query($sql);
foreach($res as $row) {
 echo $row['username'].'br/>';
}

這時候答案呼之欲出--- 是yii2框架搞了鬼

定位問題 既然知道了是yii2 框架的問題那就可以進一步縮小問題。

public static function actionTest() {
  $total = 10;
  var_dump('開始內存'.memory_get_usage());
  while($total){
   $ret= new User();
   var_dump('end內存'.memory_get_usage());
   unset($ret);
   $total--;
  }
 }

內存還是一直增長。 這時候我測試了一個其他的yii2類 發覺內存不增長了。 這就可以聯想到是在new 對象的時候yii2內部自己執行了什么操作,然后導致內存泄漏。 什么方法是new 的時候就執行的呢。。。 對的 構造方法 __construct 。 然后 我一步一步的從model 查到object 發覺都沒有能引起泄漏的地方。

這個時候我們不妨換個思路, 既然是yii2框架下出現的泄漏, 那肯定就是yii2獨有的功能, 那什么功能是yii2獨有的,又是在new 對象的時候就會執行的呢?

行為(Behavior) 發覺我的模型類里面果然有用了行為

public function behaviors()
 {
  return [
   TimestampBehavior::class,
  ];
 }

最普通不過的代碼。 我們知道 行為最后調用的地方是 yii\base\Component->attachBehaviors 最后定位到

private function attachBehaviorInternal($name, $behavior)
 {
  if (!($behavior instanceof Behavior)) {
   $behavior = Yii::createObject($behavior);
  }
  if (is_int($name)) {
   $behavior->attach($this);
   $this->_behaviors[] = $behavior;
  } else {
   if (isset($this->_behaviors[$name])) {
    $this->_behaviors[$name]->detach();
   }
   $behavior->attach($this);
   $this->_behaviors[$name] = $behavior;
  }
 
  return $behavior;
 }

我們觀察這段代碼,發覺他把自己傳進去了$behavior->attach($this); 最后調用的是 yii\base\Behavior->attach

public function attach($owner)
 {
  $this->owner = $owner;
  foreach ($this->events() as $event => $handler) {
   $owner->on($event, is_string($handler) ? [$this, $handler] : $handler);
  }
 }

問題總結

這個時候答案已經呼之欲出, Yii2為了實現行為這一功能, 把自身this傳進去,以便能注冊事件、觸發事件、解除事件。 這就導致了一個循環引用的問題。 所以導致對象refcount一直不為0 一直回收不了。

接下來就好辦了。將查詢換成原始的連接試試。果然,內存上升的非常慢了,可以說這才是正常現象?,F在的內存也就是50m左右,cpu也穩定在7%左右。

代碼優化后,再跑腳本,1分鐘左右吧,腳本就跑完了。重點是不會再報出內存錯誤了。所以,以后考慮問題還是要深入。敢于質疑。以后如果遇到這種內存錯誤,一定要先檢查自己的代碼是不是有內存泄漏的地方。不要想著先設置php的內存。這樣只會治標不治本。

總結

1、從開發速度方面,借助于gii腳手架,可以快速生成代碼,也就是說搭建一個可以增刪改查的系統可能一行代碼都不用寫,而且集成了jquery和bootstrap,特效和樣式基本也不需要寫了,這對于設計和審美能力普遍較差的后端程序員來說簡直是一大福利。不過在前后端完全的分離的趨勢下,Yii2前后端的耦合的還是有些重了。

2、從代碼的可讀性方面,Yii不會為了刻板地遵照某種設計模式而對代碼進行過度的設計?;旧项愒贗DE里不借助第三方組件是可以跳轉閱讀源碼的。這點上Yii要比Laravel略勝一籌。

3、從開源生態圈方面,Yii因為人少,稍微偏門一點的資料就很少,需要強大的谷歌能力和閱讀英文文檔的能力。

不可否認,Yii是一個優秀的開發框架,值得PHP開發者上手學習,踩坑的過程也是一種成長與積累。最后祝愿PHP小伙伴們都健健康康,事業有成。

您可能感興趣的文章:
  • 從零開始學YII2框架(一)通過Composer安裝Yii2框架
  • 從零開始學YII2框架(五)快速生成代碼工具 Gii 的使用
  • 從零開始學YII2框架(六)高級應用程序模板
  • 從零開始學YII2框架(三)擴展插件yii2-gird
  • 從零開始學YII2框架(二)通過 Composer 安裝擴展插件
  • 從零開始學YII2框架(四)擴展插件yii2-kartikgii

標簽:銅川 南陽 宜賓 黃南 婁底 寶雞 湛江 鎮江

巨人網絡通訊聲明:本文標題《Yii2框架中一些折磨人的坑》,本文關鍵詞  Yii2,框架,中,一些,折磨,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Yii2框架中一些折磨人的坑》相關的同類信息!
  • 本頁收集關于Yii2框架中一些折磨人的坑的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    欧美高清一级片在线观看| 亚洲一区二区三区四区中文字幕| 91精品国产品国语在线不卡| 久久丁香综合五月国产三级网站| 国产精品一区二区三区99| 欧美一区二区日韩| 久久新电视剧免费观看| 精品视频123区在线观看| 亚洲精品乱码久久久久久久久| 精品999在线播放| 久99久精品视频免费观看| 日韩av电影免费观看高清完整版在线观看| 国产精品美女久久久久av爽李琼 | 91精品国产一区二区| 亚洲国产人成综合网站| 秋霞午夜av一区二区三区| 婷婷六月综合亚洲| 欧美日韩精品免费观看视频| 粉嫩蜜臀av国产精品网站| 欧美日韩激情一区二区| 欧美成人vr18sexvr| 国产一二三精品| 亚洲精品中文在线| 在线观看成人小视频| 奇米一区二区三区| 亚洲色图一区二区三区| 欧美丰满少妇xxxbbb| 国产真实乱偷精品视频免| 中文字幕综合网| 欧美一区二区精品| 91精彩视频在线观看| 国产尤物一区二区| 五月天视频一区| 国产精品你懂的| 欧美一区二区久久| 91影视在线播放| 国产乱国产乱300精品| 婷婷久久综合九色国产成人| √…a在线天堂一区| www精品美女久久久tv| 欧美妇女性影城| 色偷偷成人一区二区三区91| 日韩欧美国产精品一区| 93久久精品日日躁夜夜躁欧美| 亚洲成av人片一区二区梦乃| 91麻豆精品国产91久久久资源速度| 国产精品你懂的在线| 日韩视频中午一区| 午夜国产精品一区| 中文字幕免费一区| 欧美色精品天天在线观看视频| 亚洲国产另类精品专区| 8x8x8国产精品| 高清不卡一区二区| 免费看欧美女人艹b| 亚洲成人免费视频| 国产精品家庭影院| 精品精品国产高清a毛片牛牛 | 国产精品天美传媒沈樵| 成人毛片在线观看| 韩国av一区二区三区| 日本视频免费一区| 日韩av高清在线观看| 日韩经典一区二区| 韩国v欧美v日本v亚洲v| 老司机午夜精品| 精彩视频一区二区三区| 精品在线一区二区三区| 国内精品不卡在线| 丰满少妇久久久久久久| 久久午夜电影网| 欧美国产一区视频在线观看| 自拍av一区二区三区| 亚洲一区在线观看免费观看电影高清| 亚洲一区中文日韩| 九一久久久久久| 成人在线视频首页| 99re成人精品视频| 在线观看欧美精品| 2017欧美狠狠色| 亚洲精品va在线观看| 韩国视频一区二区| 国产福利91精品| 成人激情动漫在线观看| 色素色在线综合| 日韩一区二区电影| 国产精品美女久久久久av爽李琼 | 久久夜色精品一区| 国产精品久久久爽爽爽麻豆色哟哟 | 亚洲激情av在线| 午夜伊人狠狠久久| 国产精品1024| 欧美日韩在线直播| 国产一区二区在线观看视频| 成人av资源站| 欧美xfplay| 免费观看一级欧美片| 欧美一区二区三区在线视频| 丝袜亚洲另类欧美综合| 日韩一区二区三区免费看 | 亚洲永久精品大片| 九色综合国产一区二区三区| 在线免费观看日本欧美| 国内精品免费**视频| 欧美日韩午夜影院| 亚洲精品国产一区二区三区四区在线 | 7777精品伊人久久久大香线蕉完整版 | 欧美激情综合五月色丁香| 免费欧美在线视频| 制服丝袜国产精品| 免费精品99久久国产综合精品| 69久久夜色精品国产69蝌蚪网| 午夜成人免费视频| 欧美一级理论性理论a| 日韩国产欧美在线视频| 91精品欧美综合在线观看最新| 五月天一区二区三区| 欧美v日韩v国产v| 国产精品第四页| 一区二区三区在线视频观看58| 日本特黄久久久高潮| 日韩免费观看高清完整版 | 亚洲va欧美va国产va天堂影院| 国产呦萝稀缺另类资源| 国产精品久久久久影院亚瑟| 精品视频一区二区不卡| 国产精品一区在线观看你懂的| 亚洲精品国产精华液| 久久婷婷成人综合色| 欧美日韩免费视频| 99视频精品免费视频| 免费成人在线播放| 一区二区三区视频在线观看| 337p日本欧洲亚洲大胆色噜噜| 91九色02白丝porn| eeuss鲁片一区二区三区在线看| 美腿丝袜亚洲综合| 午夜精品福利在线| 亚洲精品国产成人久久av盗摄| 久久人人爽人人爽| 中日韩免费视频中文字幕| 亚洲制服丝袜av| 日本中文在线一区| 成人性生交大片免费看中文| 不卡av在线免费观看| 中文字幕av一区二区三区| 国产精品资源站在线| 九九精品一区二区| 精品人在线二区三区| 91丨九色丨尤物| 七七婷婷婷婷精品国产| 中文字幕一区不卡| 国产一区二区在线观看视频| 欧美一区2区视频在线观看| 亚洲欧洲美洲综合色网| 丰满岳乱妇一区二区三区| 久久免费精品国产久精品久久久久| 亚洲一区二区三区三| 色菇凉天天综合网| 亚洲色图都市小说| 91丝袜高跟美女视频| 亚洲欧洲日本在线| 91色婷婷久久久久合中文| 1000精品久久久久久久久| 成人免费高清视频在线观看| 久久久精品天堂| 国产精品资源在线| 国产亚洲综合性久久久影院| 国产黄人亚洲片| 国产欧美一区二区精品秋霞影院| 国产精品乡下勾搭老头1| 久久夜色精品国产噜噜av| 国产成人精品亚洲777人妖| 国产欧美精品区一区二区三区 | 欧美性猛交xxxxxx富婆| 亚洲免费观看高清在线观看| 欧美综合亚洲图片综合区| 亚洲国产色一区| 欧美一区二区三区小说| 久久国产日韩欧美精品| 久久久精品免费免费| 成人免费视频视频在线观看免费| 国产精品婷婷午夜在线观看| 91在线码无精品| 亚洲风情在线资源站| 日韩一区二区三区视频| 国产精品亚洲第一区在线暖暖韩国| 国产精品麻豆网站| 在线亚洲免费视频| 麻豆精品在线观看| 国产亚洲欧美日韩在线一区| 99精品视频免费在线观看| 中文字幕欧美日本乱码一线二线| 亚洲国产人成综合网站| 亚洲电影第三页| 精品一区二区精品| 中文字幕高清一区| 精品免费一区二区三区| 欧美综合欧美视频| 欧美伊人精品成人久久综合97|