类别:ThinkPHP / 日期:2019-12-17 / 浏览:187 / 评论:0

修正器是模子的三大利「器」之一,本篇我们来总结下修正器的用法,以及一些注重事项。

定义修正器

修正器的作用是在模子对象数据写入数据库之前举行一些必要的数据处置惩罚,修正器的范例定义以下:

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;

由于在模子内部举行数据对象的赋值,会由于和模子内部属性殽杂而致使不可预知的效果。

假如你在某个修正器中大概会对别的字段举行修正,务必记得你须要分外修正的字段修正器必需已经由赋值操纵(或许已触发过修正器)。

怎样挪用

修正器要领不须要手动挪用,根据定义范例定义好后,体系会在下面的情况下自动挪用:

·模子对象赋值;

·挪用模子的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字段的自动完成设置,由于修正器会在每次赋值的时刻自动触发,假如没有赋值申明暗码没有被修正,也谈不上自动完成。

自动完成的字段通常是不在表单内里的字段,平常是由体系自动处置惩罚的字段。

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',
];

假如你同时对一个字段定义了修正器和范例的话,修正器是优先的。

范例定义不仅能定义简朴的数据范例,另有一些分外的用处,比方:json 范例、array范例和object 范例会举行JSON序列化,serialize范例则会把数据举行serialize序列化。

ki4网,有大批免费的ThinkPHP入门教程,迎接人人进修!

本文转自:https://blog.thinkki4.cn/817548

以上就是ThinkPHP:模子三大利器之二(修正器)的细致内容,更多请关注ki4网别的相干文章!

打赏

感谢您的赞助~

打开支付宝扫一扫,即可进行扫码打赏哦~

版权声明 : 本文未使用任何知识共享协议授权,您可以任何形式自由转载或使用。

 可能感兴趣的文章