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

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

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

定義修改器

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

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

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

原則上,每個(gè)修改器應(yīng)當(dāng)僅處理對(duì)應(yīng)字段的數(shù)據(jù),但在必要的情況下允許同時(shí)處理多個(gè)字段。

下面是一個(gè)例子

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方法是確保年齡賦值操作仍然可以走單獨(dú)的修改器。如果你沒有額外的修改器,那么也可以寫成

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;

因?yàn)樵谀P蛢?nèi)部進(jìn)行數(shù)據(jù)對(duì)象的賦值,會(huì)因?yàn)楹湍P蛢?nèi)部屬性混淆而導(dǎo)致不可預(yù)知的后果。

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

如何調(diào)用

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

   ·模型對(duì)象賦值;

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

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

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

   ·定義了該字段的自動(dòng)完成;

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

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

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

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

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

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

這個(gè)時(shí)候就不會(huì)經(jīng)過修改器處理。

避免沖突

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

protected $auto = ['password'];

這在V5.1.27版本之前是一個(gè)看似聰明卻非常致命的錯(cuò)誤,要盡量避免,因?yàn)楦鶕?jù)我們之前給出的修改器觸發(fā)條件,會(huì)導(dǎo)致該修改器被執(zhí)行兩次。這會(huì)是一個(gè)災(zāi)難性的錯(cuò)誤,將導(dǎo)致所有的用戶注冊(cè)后都無法正常登錄。

解決辦法取消password字段的自動(dòng)完成設(shè)置,因?yàn)樾薷钠鲿?huì)在每次賦值的時(shí)候自動(dòng)觸發(fā),如果沒有賦值說明密碼沒有被修改,也談不上自動(dòng)完成。

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

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

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

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

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

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

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

類型自動(dòng)轉(zhuǎn)化

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

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

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

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

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

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

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

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

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

廣告

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

網(wǎng)站托管運(yùn)營(yíng)