<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ### 2018 年 10 月 27 日 發布 修改器是模型的三大利「器」之一,本篇我們來總結下修改器的用法,以及一些注意事項。 ## 定義修改器 修改器的作用是在模型對象數據寫入數據庫之前進行一些必要的數據處理,修改器的標準定義如下: ``` public function setFieldNameAttr($value, $data) { // 對value值進行處理 data參數是當前全部數據 // 返回值就是實際要寫入數據庫的值 return $value; } ``` 其中`FieldName`對應數據表的`field_name`字段(注意數據表字段的規范和修改器方法定義規范,否則會導致錯誤)。 原則上,每個修改器應當僅處理對應字段的數據,但在必要的情況下允許同時處理多個字段。 下面是一個例子 ``` public function setBirthdayAttr($value, $data) { // 格式化生日數據 $birthday = strtotime($value); // 根據生日判斷年齡 $age = getAgeByBirthday($birthday); // 賦值年齡數據 $this->setAttr('age', $age); return $birthday; } public function setAgeAttr($value,$data) { return floor($value); } ``` 之所以使用`setAttr`方法是確保年齡賦值操作仍然可以走單獨的修改器。如果你沒有額外的修改器,那么也可以寫成 ``` public function setBirthdayAttr($value, $data) { // 格式化生日數據 $birthday = strtotime($value); // 根據生日判斷年齡 $age = getAgeByBirthday($birthday); // 賦值年齡數據 $this->data['age'] = $age; return $birthday; } ``` 注意一定不能寫成 ``` $this->age = $age; ``` 因為在模型內部進行數據對象的賦值,會因為和模型內部屬性混淆而導致不可預知的后果。 >[danger] 如果你在某個修改器中可能會對其它字段進行修改,務必記得你需要額外修改的字段修改器必須已經經過賦值操作(或者已經觸發過修改器)。 ## 如何調用 修改器方法不需要手動調用,按照定義規范定義好后,系統會在下面的情況下自動調用: * 模型對象賦值; * 調用模型的`data`方法,并且第二個參數傳入true; * 調用模型的`save`方法,并且傳入數組數據; * 顯式調用模型的`setAttr`方法; * 定義了該字段的自動完成; 例如`User`模型定義了`setPasswordAttr`修改器方法。 ``` public function setPasswordAttr($value, $data) { return md5($value); } ``` 當下面這樣使用的時候,保存到數據庫的`password`字段的值就會變成`md5('think')`后的值。 ``` $user = User::get(1); $user->password = 'think'; $user->save(); ``` 如果你在一些情況下,不希望使用修改器而是想要手動控制數據,可以嘗試使用下面的方法。 ``` $user = User::get(1); $user->data('password', md5('think')); $user->save(); ``` 這個時候就不會經過修改器處理。 ## 避免沖突 很多開發者喜歡給修改器定義自動完成`auto`(包括`insert`和`update`)。 ``` protected $auto = ['password']; ``` 這在`V5.1.27`版本之前是一個看似聰明卻非常致命的錯誤,要盡量避免,因為根據我們之前給出的修改器觸發條件,會導致該修改器被執行兩次。這會是一個災難性的錯誤,將導致所有的用戶注冊后都無法正常登錄。 解決辦法取消`password`字段的自動完成設置,因為修改器會在每次賦值的時候自動觸發,如果沒有賦值說明密碼沒有被修改,也談不上自動完成。 >[danger] 自動完成的字段通常是不在表單里面的字段,一般是由系統自動處理的字段。 `V5.1.27`版本改進了這個問題,所有的修改器只允許執行一次,上面的問題就不復存在了。但好像又帶來了一個新的問題,很多時候,你也許想在模型的事件中對數據進行修改。 ``` User::beforeUpdate(function($user) { $user->password = md5('think'); }); ``` 會發現,在模型`beforeUpdate`事件中,數據的值怎么都修改不了,原因是模型的修改器之前在第一次賦值的時候已經執行了,第二次再賦值的時候已經無效了(不會再執行)。 解決辦法就是我前面提過的使用`data`方法不調用修改器進行數據賦值操作。 ``` User::beforeUpdate(function($user) { $user->data('password', md5('think')); }); ``` 當然,更好的建議是規劃好修改器、自動完成和模型事件的數據處理機制,不要對一個字段同時使用多重機制修改數據,并且寫入數據庫的數據**應該并且只有**修改器這一個途徑進行數據**修改**操作。 ## 類型自動轉化 如果你的修改器僅僅是對數據做類型轉換處理的話,可以無需定義修改器,而是直接定義字段類型就可以了。 ``` public function setScoreAttr($value, $data) { return (float) $score; } ``` 上面的修改器方法可以直接改成 ``` protected $type = [ 'score' => 'float', ]; ``` 如果你同時對一個字段定義了修改器和類型的話,修改器是優先的。 >[info] 類型定義不僅能定義簡單的數據類型,還有一些額外的用途,例如:`json` 類型、`array`類型和`object` 類型會進行`JSON`序列化,`serialize`類型則會把數據進行`serialize`序列化。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看