ThinkPHP中如何定義修改器-創(chuàng)新互聯(lián)

這篇文章主要介紹ThinkPHP中如何定義修改器,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

成都創(chuàng)新互聯(lián)公司"三網(wǎng)合一"的企業(yè)建站思路。企業(yè)可建設擁有電腦版、微信版、手機版的企業(yè)網(wǎng)站。實現(xiàn)跨屏營銷,產(chǎn)品發(fā)布一步更新,電腦網(wǎng)絡+移動網(wǎng)絡一網(wǎng)打盡,滿足企業(yè)的營銷需求!成都創(chuàng)新互聯(lián)公司具備承接各種類型的網(wǎng)站設計制作、成都做網(wǎng)站項目的能力。經(jīng)過10多年的努力的開拓,為不同行業(yè)的企事業(yè)單位提供了優(yōu)質(zhì)的服務,并獲得了客戶的一致好評。

定義修改器

修改器的作用是在模型對象數(shù)據(jù)寫入數(shù)據(jù)庫之前進行一些必要的數(shù)據(jù)處理,修改器的標準定義如下:

public function setFieldNameAttr($value, $data)
{
    // 對value值進行處理 data參數(shù)是當前全部數(shù)據(jù)
    // 返回值就是實際要寫入數(shù)據(jù)庫的值
    return $value;
}

其中FieldName對應數(shù)據(jù)表的field_name字段(注意數(shù)據(jù)表字段的規(guī)范和修改器方法定義規(guī)范,否則會導致錯誤)。

原則上,每個修改器應當僅處理對應字段的數(shù)據(jù),但在必要的情況下允許同時處理多個字段。

下面是一個例子

public function setBirthdayAttr($value, $data)
{
    // 格式化生日數(shù)據(jù)
    $birthday = strtotime($value);
    // 根據(jù)生日判斷年齡
    $age = getAgeByBirthday($birthday);
    // 賦值年齡數(shù)據(jù)
    $this->setAttr('age', $age);
    return $birthday;
}
public function setAgeAttr($value,$data)
{
    return floor($value);
}

之所以使用setAttr方法是確保年齡賦值操作仍然可以走單獨的修改器。如果你沒有額外的修改器,那么也可以寫成

public function setBirthdayAttr($value, $data)
{
    // 格式化生日數(shù)據(jù)
    $birthday = strtotime($value);
    // 根據(jù)生日判斷年齡
    $age = getAgeByBirthday($birthday);
    // 賦值年齡數(shù)據(jù)
    $this->data['age'] = $age;
    return $birthday;
}

注意一定不能寫成

$this->age = $age;

因為在模型內(nèi)部進行數(shù)據(jù)對象的賦值,會因為和模型內(nèi)部屬性混淆而導致不可預知的后果。

如果你在某個修改器中可能會對其它字段進行修改,務必記得你需要額外修改的字段修改器必須已經(jīng)經(jīng)過賦值操作(或者已經(jīng)觸發(fā)過修改器)。

如何調(diào)用

修改器方法不需要手動調(diào)用,按照定義規(guī)范定義好后,系統(tǒng)會在下面的情況下自動調(diào)用:

   ·模型對象賦值;

   ·調(diào)用模型的data方法,并且第二個參數(shù)傳入true;

   ·調(diào)用模型的save方法,并且傳入數(shù)組數(shù)據(jù);

   ·顯式調(diào)用模型的setAttr方法;

   ·定義了該字段的自動完成;

例如User模型定義了setPasswordAttr修改器方法。

public function setPasswordAttr($value, $data)
{
    return md5($value);
}

當下面這樣使用的時候,保存到數(shù)據(jù)庫的password字段的值就會變成md5('think')后的值。

$user = User::get(1);
$user->password = 'think';
$user->save();

如果你在一些情況下,不希望使用修改器而是想要手動控制數(shù)據(jù),可以嘗試使用下面的方法。

$user = User::get(1);
$user->data('password', md5('think'));
$user->save();

這個時候就不會經(jīng)過修改器處理。

避免沖突

很多開發(fā)者喜歡給修改器定義自動完成auto(包括insert和update)。

protected $auto = ['password'];

這在V5.1.27版本之前是一個看似聰明卻非常致命的錯誤,要盡量避免,因為根據(jù)我們之前給出的修改器觸發(fā)條件,會導致該修改器被執(zhí)行兩次。這會是一個災難性的錯誤,將導致所有的用戶注冊后都無法正常登錄。

解決辦法取消password字段的自動完成設置,因為修改器會在每次賦值的時候自動觸發(fā),如果沒有賦值說明密碼沒有被修改,也談不上自動完成。

自動完成的字段通常是不在表單里面的字段,一般是由系統(tǒng)自動處理的字段。

V5.1.27版本改進了這個問題,所有的修改器只允許執(zhí)行一次,上面的問題就不復存在了。但好像又帶來了一個新的問題,很多時候,你也許想在模型的事件中對數(shù)據(jù)進行修改。

User::beforeUpdate(function($user) {
    $user->password = md5('think');
});

會發(fā)現(xiàn),在模型beforeUpdate事件中,數(shù)據(jù)的值怎么都修改不了,原因是模型的修改器之前在第一次賦值的時候已經(jīng)執(zhí)行了,第二次再賦值的時候已經(jīng)無效了(不會再執(zhí)行)。

解決辦法就是我前面提過的使用data方法不調(diào)用修改器進行數(shù)據(jù)賦值操作。

User::beforeUpdate(function($user) {
    $user->data('password', md5('think'));
});

當然,更好的建議是規(guī)劃好修改器、自動完成和模型事件的數(shù)據(jù)處理機制,不要對一個字段同時使用多重機制修改數(shù)據(jù),并且寫入數(shù)據(jù)庫的數(shù)據(jù)應該并且只有修改器這一個途徑進行數(shù)據(jù)修改操作。

類型自動轉(zhuǎn)化

如果你的修改器僅僅是對數(shù)據(jù)做類型轉(zhuǎn)換處理的話,可以無需定義修改器,而是直接定義字段類型就可以了。

public function setScoreAttr($value, $data)
{
    return (float) $score;
}

上面的修改器方法可以直接改成

protected $type = [
    'score'    =>    'float',
];

如果你同時對一個字段定義了修改器和類型的話,修改器是優(yōu)先的。

類型定義不僅能定義簡單的數(shù)據(jù)類型,還有一些額外的用途,例如:json 類型、array類型和object 類型會進行JSON序列化,serialize類型則會把數(shù)據(jù)進行serialize序列化。

以上是“ThinkPHP中如何定義修改器”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關知識,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

分享標題:ThinkPHP中如何定義修改器-創(chuàng)新互聯(lián)
本文URL:http://muchs.cn/article22/djhicc.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供手機網(wǎng)站建設、外貿(mào)建站、自適應網(wǎng)站小程序開發(fā)、用戶體驗、網(wǎng)站維護

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運營