我有一列存储信用卡号。目前,它的值是encrypted
写入数据库之前,decrypted
则是从表中读取。
我想要做的是一旦从表和decrypted
中读取了值,就“屏蔽了值”。 “掩盖值”是指用x
代替除数字以外的所有内容。例如,4242 4242 4242 4242
应该变成x4242
。为此,我创建了新的trait
,将其命名为Maskable
,其中函数getAttribute
被覆盖以执行上述操作,并且setAttribute
函数被覆盖以检查值是否为试图保存等于“ x” +四位数。如果是,请跳过此列,因为这意味着它尚未更改。否则,将其正常保存,然后更改表中的值(但先对其进行加密)。
是否可以在一个模型中多次重写同一功能?如果是,我该如何判断应该先使用哪种set/getAttribute
方法?我在不同的模型中使用Encryptable trait
,但是新的trait
暂时仅在这里使用,这就是为什么我不能在同一trait
中全部使用它。
编辑
我面临的错误:
Trait method getAttribute has not been applied, because there are collisions with other trait methods on ...
//My example model
class RentalApplication extends Model {
use Encryptable, Maskable;
protected $encryptable = ['card_number'];
protected $maskable = ['card_number'];
}
//Traits
trait Maskable {
public function getAttribute($key) {
$value = parent::getAttribute($key);
if(isset($this->maskable) && in_array($key, $this->maskable) && !empty($value)) {
try {
$value = 'x'.substr($value, -4);
} catch (\Exception $e) {
return $value;
}
}
return $value;
}
trait Encryptable {
public function getAttribute($key) {
$value = parent::getAttribute($key);
if(isset($this->encryptable) && in_array($key, $this->encryptable) && !empty($value)) {
try {
$value = Crypt::decrypt($value);
} catch (\Exception $e) {
return $value;
}
}
return $value;
}
public function setAttribute($key, $value) {
if(isset($this->encryptable) && in_array($key, $this->encryptable) && !is_null($value)) {
if(Schema::hasColumn($this->getTable(), $key.'_search') && !empty($this->id)) {
parent::setAttribute($key.'_search', hash('sha512', env('APP_KEY').$this->id.$value));
}
$value = Crypt::encrypt($value);
}
return parent::setAttribute($key, $value);
}
public function toArray() {
$array = parent::toArray();
foreach($this->encryptable as $key) {
if(array_key_exists($key, $array)) {
$array[$key] = $this->{$key};
}
}
return $array;
}
}
答案 0 :(得分:1)
不推荐使用的解决方案
//Traits
trait Maskable {
public function getAttribute($key) {
$value = parent::getAttribute($key);
if(isset($this->maskable) && in_array($key, $this->maskable) && !empty($value)) {
try {
$value = 'x'.substr($value, -4);
} catch (\Exception $e) {
return $value;
}
}
return $value;
}
trait Encryptable {
public function getAttribute($key) {
if (in_array(Maskable::class, class_uses(self::class))) {
$value = self::getMaskedAttribute($key);
} else {
$value = parent::getAttribute($key);
}
if(isset($this->encryptable) && in_array($key, $this->encryptable) && !empty($value)) {
try {
$value = Crypt::decrypt($value);
} catch (\Exception $e) {
return $value;
}
}
return $value;
}
然后解决冲突
//My example model
class RentalApplication extends Model {
use Encryptable, Maskable {
Encryptable::getAttribute insteadof Maskable;
Maskable::getAttribute as getMaskedAttribute;
};
protected $encryptable = ['card_number'];
protected $maskable = ['card_number'];
}