Php 如何对模型的任何请求应用加密?

Php 如何对模型的任何请求应用加密?,php,laravel,encryption,Php,Laravel,Encryption,我有密码,可以用这种方式解密密码: use ProjectName\Models\Some; Some::find(1)->pass; 它会自动解密在我的数据库中加密的密码。 但如果我对我的模型提出不同的要求,例如: Some::find(1); 这不管用。请有人解释一下我要做什么 这是完整的代码: trait Encryptable { public function getAttribute($key) { $value = parent::g

我有密码,可以用这种方式解密密码:

use ProjectName\Models\Some; 

Some::find(1)->pass; 
它会自动解密在我的数据库中加密的密码。 但如果我对我的模型提出不同的要求,例如:

Some::find(1);
这不管用。请有人解释一下我要做什么

这是完整的代码:

trait Encryptable
{
    public function getAttribute($key)
    {
        $value = parent::getAttribute($key);

        if (in_array($key, $this->encryptable)) {
            return Crypt::decrypt($value);
        }

        return parent::getAttribute($key);
    }

    public function setAttribute($key, $value)
    {
        if (in_array($key, $this->encryptable)) {
            parent::setAttribute($key, Crypt::encrypt($value));
            return;
        }

        parent::setAttribute($key, $value);
    }
}

这是更新后的答案

为了获得预期的行为,您可以重写
illighted\Database\Eloquent\Model
hydrate()
方法,以便在检索数据库后解密模型

最初的方法是:

/**
 * Create a collection of models from plain arrays.
 *
 * @param  array  $items
 * @param  string|null  $connection
 * @return \Illuminate\Database\Eloquent\Collection
 */
public static function hydrate(array $items, $connection = null)
{
    $instance = (new static)->setConnection($connection);

    $items = array_map(function ($item) use ($instance)
    {
        return $instance->newFromBuilder($item);
    }, $items);

    return $instance->newCollection($items);
}
您可以通过添加解密内容覆盖它,如下所示:

/**
 * Create a collection of models from plain arrays.
 *
 * @param  array  $items
 * @param  string|null  $connection
 * @return \Illuminate\Database\Eloquent\Collection
 */
public static function hydrate(array $items, $connection = null)
{
    $instance = (new static)->setConnection($connection);

    $items = array_map(function ($item) use ($instance)
    {
        foreach ($instance->encryptable as $attribute) {
            // Remember to do any aditional check here, like check if is_null
            // and catch any exceptions also.
            $item->$attribute = \Crypt::decrypt($item->$attribute);
        }

        return $instance->newFromBuilder($item);
    }, $items);

    return $instance->newCollection($items);
}
这里我们解决了模型加载的解密部分,很好

要解决保存时加密问题,可以使用
保存
事件加密属性,然后在
保存
事件中,将属性还原为非加密值


这样,在您的应用程序中,模型总是简单的,但在数据库中,它将被加密。

这是更新的答案。

为了获得预期的行为,您可以重写
illighted\Database\Eloquent\Model
hydrate()
方法,以便在检索数据库后解密模型

最初的方法是:

/**
 * Create a collection of models from plain arrays.
 *
 * @param  array  $items
 * @param  string|null  $connection
 * @return \Illuminate\Database\Eloquent\Collection
 */
public static function hydrate(array $items, $connection = null)
{
    $instance = (new static)->setConnection($connection);

    $items = array_map(function ($item) use ($instance)
    {
        return $instance->newFromBuilder($item);
    }, $items);

    return $instance->newCollection($items);
}
您可以通过添加解密内容覆盖它,如下所示:

/**
 * Create a collection of models from plain arrays.
 *
 * @param  array  $items
 * @param  string|null  $connection
 * @return \Illuminate\Database\Eloquent\Collection
 */
public static function hydrate(array $items, $connection = null)
{
    $instance = (new static)->setConnection($connection);

    $items = array_map(function ($item) use ($instance)
    {
        foreach ($instance->encryptable as $attribute) {
            // Remember to do any aditional check here, like check if is_null
            // and catch any exceptions also.
            $item->$attribute = \Crypt::decrypt($item->$attribute);
        }

        return $instance->newFromBuilder($item);
    }, $items);

    return $instance->newCollection($items);
}
这里我们解决了模型加载的解密部分,很好

要解决保存时加密问题,可以使用
保存
事件加密属性,然后在
保存
事件中,将属性还原为非加密值


这样,在您的应用程序中,模型总是简单的,但在数据库中,它将被加密。

在这种情况下,我甚至不使用attributesToArray()函数。使用::all()和::find对其进行了测试methods@HenryKolesnik
::all()
不直接序列化模型,因此在
dd($model)
中,您当然会看到原始属性。让我给你建议另一种做你想做的事的方法。我会在几分钟内更新答案@HenryKolesnik看看这个新答案!在这种情况下,我甚至不使用attributesToArray()函数。使用::all()和::find对其进行了测试methods@HenryKolesnik
::all()
不直接序列化模型,因此在
dd($model)
中,您当然会看到原始属性。让我给你建议另一种做你想做的事的方法。我会在几分钟内更新答案@HenryKolesnik看看这个新答案!我有密码,我可以用它来解密密码:“你可能想读。我有一个密码,我可以用它来解密密码:“你可能想读。你不应该加密密码。