首頁 >php框架 >ThinkPHP >介紹thinkphp5.0修改器與資料完成的關係及使用方法

介紹thinkphp5.0修改器與資料完成的關係及使用方法

藏色散人
藏色散人轉載
2021-04-27 16:39:241794瀏覽

以下由thinkphp教學專欄為大家介紹thinkphp5.0修改器和資料完成的關係及使用方法,希望對需要的朋友有幫助!

thinkphp5.0修改器和資料完成的關係以及使用方法

密碼加密時遇到的問題

今天遇到密碼md5加密的問題,當時使用的是"thinkphp5.0.9->模型->資料完成" 實現的自動進行加密,但是在上面"thinkphp5.0.9->模型->修改器" 中發現修改器和資料完成功能一樣,看下方的評論說是資料完成和修改器配合使用,我就照著做,當時這樣寫的:
//模型层

class User extends Model{
//$auto包含新增$insert和更新操作$update,就是不管新增还是更新我就自动执行
    protected $auto = ['password','create'];
    public function setPasswordAttr($value)
    {
        return md5($value);
    }
    public function setCreateAttr()
    {
        return time();
    }
    
//注册用户
    public function register($data){
            $bool = $this->save($data);
            return $bool ? $this->id : 0;
    } 
}

//控制器层方法
public function register()
    {
        if(request()->isAjax()){
            $userModel=new \app\index\Model\User();
            $data=input('post.');
//注册
            $res = $userModel->register($data);
           echo $res;
        }else{
            $this->error('非法访问');
        }
    }

介紹thinkphp5.0修改器與資料完成的關係及使用方法

我輸入"wwwwww" 按照上面的代碼進行註冊後password加密結果是b8d3c8f4db0c248ac242dd6e098bbf85

正確的加密結果是d785c99d298a4e9e6e13fe99e602ef42,這個時候你可能沒發現,當你不登錄www你登陸的時候還是登陸不上去,只能懷疑加密出錯,再往上找到了"數據完成的setPasswordAttr()"

單獨拿出來測試

直接說答案吧,我當時看了多遍修改器和資料完成測試兩個小時終於知道原因了,新建的test表

介紹thinkphp5.0修改器與資料完成的關係及使用方法

//新建test模型层
namespace app\index\Model;
use think\Model;
class Test extends Model
{
    protected $auto = ['password'];
    protected function setPasswordAttr($value)
    {
        dump(md5(NULL));
        dump($value);
        dump(md5($value));
        return md5($value);

    }
    public function addPass(){
        echo "修改器";
        $this->password='wwwwww';
        dump($this->password);
        
        echo "数据完成";
        $this->save([
            'username'  => 'thinkphp',
            'password'  => 'wwwwww',
            'create'    => '123456'
        ]);
    }
}

//控制器中添加test方法
 public function test(){
        $user = model('Test');
        //调用model层函数
        $user->addPass();
    }

單獨測試修改器

先註解掉模型層中的「資料完成」 部分
namespace app\index\Model;
use think\Model;
class Test extends Model
{
    protected $auto = ['password'];
    protected function setPasswordAttr($value)
    {
        dump(md5(NULL));//把NULL加密
        dump($value);   //查看调用时传递过来的值
        dump(md5($value));//把该值加密
        return md5($value);//把该值加密返回

    }
    public function addPass(){
        echo "修改器:修改器的作用是可以在数据赋值的时候自动进行转换处理";
        $this->password='wwwwww';
        dump($this->password);//输出返回后的结果

//        echo "数据完成:在数据字段insert,update,auto时进行处理";
//        $this->save([
//            'username'  => 'thinkphp',
//            'password'  => 'wwwwww',
//            'create'    => '123456'
//        ]);
    }
}
執行後頁面顯示結果,透過結果發現修改器是在賦值的時候執行的自動加密,注意:此時並沒有存入資料庫!
修改器:修改器的作用是可以在数据赋值的时候自动进行转换处理

string(32) "d41d8cd98f00b204e9800998ecf8427e"【加密的NULL】

string(6) "wwwwww"【传过来的$value】

string(32) "d785c99d298a4e9e6e13fe99e602ef42"【加密$value】

string(32) "d785c99d298a4e9e6e13fe99e602ef42"【return返回的结果】

測試資料完成

註解掉「修改器」部分的程式碼,只執行資料完成
namespace app\index\Model;
use think\Model;
class Test extends Model
{
    protected $auto = ['password'];
    protected function setPasswordAttr($value)
    {
        dump(md5(NULL));//把NULL加密
        dump($value);   //查看调用时传递过来的值
        dump(md5($value));//把该值加密
        return md5($value);//把该值加密返回

    }
    public function addPass(){
//        echo "修改器:修改器的作用是可以在数据赋值的时候自动进行转换处理";
//        $this->password='wwwwww';
//        dump($this->password);//输出返回后的结果

        echo "数据完成:在数据字段insert,update,auto时进行处理";
        $this->save([
            'username'  => 'thinkphp',
            'password'  => 'wwwwww',
            'create'    => '123456'
        ]);
    }
}

找到原因

執行後發現setPasswordAttr( )被執行了兩次,所以password也被加密了兩次;
数据完成:在数据字段insert,update,auto时进行处理

string(32) "d41d8cd98f00b204e9800998ecf8427e"【加密NULL】

string(6) "wwwwww"【传入的$value】

string(32) "d785c99d298a4e9e6e13fe99e602ef42"【加密$value="wwwwww"】

string(32) "d41d8cd98f00b204e9800998ecf8427e"【加密NULL】

string(32) "d785c99d298a4e9e6e13fe99e602ef42"【传入的$value】

string(32) "b8d3c8f4db0c248ac242dd6e098bbf85"【再次加密$value="d785c99...f42"】
加密兩次的原因是在賦值的時候加密一次,自動完成$auto時加密了一次
[
    'username'  => 'thinkphp',
    'password'  => 'wwwwww',
    'create'    => '123456'
]

解決開始的問題

如果想要加密一次就把protected $auto = ['password']; 註解掉,或是在登陸的程式碼中進行md5(md5("wwwwww")),註解掉後執行:
数据完成:在数据字段insert,update,auto时进行处理

string(32) "d41d8cd98f00b204e9800998ecf8427e"【加密NULL】

string(6) "wwwwww"【$value】

string(32) "d785c99d298a4e9e6e13fe99e602ef42"【加密结果】

介紹thinkphp5.0修改器與資料完成的關係及使用方法

如果是多個欄位protected $auto = ['password','create'];就把password去掉就可以了protected $auto = [ 'create'];,所以最開始的問題就解決了。

當只有資料完成但不賦值

在上面可能注意到我怎麼老是加密NULL 幹什麼,還有另一種情況就是protected $auto = ['password']; 定義了自動完成,但是我並沒有賦值:
namespace app\index\Model;
use think\Model;
class Test extends Model
{
    protected $auto = ['password'];
    protected function setPasswordAttr($value)
    {
        dump(md5(NULL));//把NULL加密
        dump($value);   //查看调用时传递过来的值
        dump(md5($value));//把该值加密
        return md5($value);//把该值加密返回

    }
    public function addPass(){
//        echo "修改器:修改器的作用是可以在数据赋值的时候自动进行转换处理";
//        $this->password='wwwwww';
//        dump($this->password);//输出返回后的结果

        echo "数据完成:在数据字段insert,update,auto时进行处理";
        $this->save([
            'username'  => 'thinkphp',
//注释掉,不赋值
 //           'password'  => 'wwwwww',
            'create'    => '123456'
        ]);
    }
}
執行後,加密的是NULL
数据完成:在数据字段insert,update,auto时进行处理

string(32) "d41d8cd98f00b204e9800998ecf8427e"【加密NULL】

NULL【没有传值,$value=NULL】

string(32) "d41d8cd98f00b204e9800998ecf8427e"【加密$value,刚好等于NULL加密结果】

介紹thinkphp5.0修改器與資料完成的關係及使用方法

剩下的$update和$insert使用方法同$auto一樣,$auto包含$update和$insert

總結

修改器會在賦值時執行;資料完成會被執行兩次,一次是賦值時,一次是寫入數據時
希望手冊能稍微詳細一點點,白白耽誤我開發時間,特此分享,大家少踩坑,如果理解的不對請指正,謝謝

以上是介紹thinkphp5.0修改器與資料完成的關係及使用方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除