Backend Development 7 min read

Understanding Password Encryption Issues in ThinkPHP 5.0.9: Modifiers vs. Auto Completion

This article explains why password MD5 encryption in ThinkPHP 5.0.9 can produce incorrect results due to the interaction between model modifiers and the auto‑completion feature, demonstrates how to isolate and test each mechanism, and provides a clear fix to avoid double hashing.

php中文网 Courses
php中文网 Courses
php中文网 Courses
Understanding Password Encryption Issues in ThinkPHP 5.0.9: Modifiers vs. Auto Completion

The author encountered a problem where passwords encrypted with MD5 in ThinkPHP 5.0.9 did not match the expected hash, causing login failures. The issue stemmed from using both the model setPasswordAttr modifier and the auto‑completion $auto feature, which caused the password to be hashed twice.

Original model code with auto‑completion and modifier:

<code>class User extends Model {
    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('非法访问');
    }
}</code>

When registering with the password "wwwwww", the stored hash was b8d3c8f4db0c248ac242dd6e098bbf85 , while the correct MD5 hash should be d785c99d298a4e9e6e13fe99e602ef42 . The discrepancy was traced to the setPasswordAttr() method being invoked twice: once during attribute assignment and once again by the auto‑completion process.

Isolated testing of the modifier:

<code>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);
    }
}</code>

The output showed that the modifier encrypted the value once, without persisting it to the database.

Testing the auto‑completion (data completion) only:

<code>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->save([
            'username' => 'thinkphp',
            'password' => 'wwwwww',
            'create'   => '123456'
        ]);
    }
}</code>

Here the hash was applied twice: once during attribute assignment and again when the record was saved, resulting in a double‑hashed password.

Solution: Remove the password field from the $auto array (e.g., use protected $auto = ['create']; ) or ensure that hashing is performed only once, such as by applying md5(md5($value)) in the login logic.

After adjusting the configuration, the stored hash matches the expected MD5 value, and login works correctly.

In summary, modifiers run during attribute assignment, while auto‑completion runs both on assignment and on database write, so using both on the same field leads to double encryption.

PHPauto completionThinkPHPPassword EncryptionModifiers
php中文网 Courses
Written by

php中文网 Courses

php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.