我目前正致力于使用defuse/php-encryption加密某些数据库字段。我选择这样做的方法是加密MyObject->setField()
上的特定字段并在MyObject->getField
上解密,如下所示:
public function getField($field)
{
$val = parent::getField($field);
if (in_array($field, static::$fieldsToEncrypt)) {
$key = $this->getEncryptionKey();
try {
$newVal = Crypto::decrypt($val, $key);
$val = $newVal;
} catch (Exception $e) {
}
}
return $val;
}
public function setField($fieldName, $val)
{
if (in_array($fieldName, static::$fieldsToEncrypt)) {
$key = $this->getEncryptionKey();
$val = Crypto::encrypt($val, $key);
}
return parent::setField($fieldName, $val);
}
为了使加密工作,我必须将我的字段类型更改为Text
,这对所有Varchar
字段都适用。现在我有一个时间DateTime
的字段也需要加密,好吧,它实际上是SS_DateTime
的扩展,但是这个扩展也被其他对象的其他字段共享所以我不能/不应该(?)在DBType级别执行。
由于这是在现有网站上,因此我不必重写每个提及此字段的内容,以便从字符串中创建新的SS_DateTime
。
如何在解密后将字段时间“重新”重载到DateTime
?
谢谢
答案 0 :(得分:2)
似乎答案比我预期的要简单。简单地向对象添加铸件似乎可以完成这项工作。例如:
private static $db = array(
'DOB' => 'Text' // should be DateTime
);
private static $casting = array(
'DOB' => 'DateTime'
);
答案 1 :(得分:0)
根据Silverstripe的文档https://docs.silverstripe.org/en/3/developer_guides/model/data_types_and_casting/#casting
,使用DBField::create_field()
投射您的输出
示例:
private static $db = array(
'Date' => 'Text' // Encrypted value
);
public function getField($field)
{
$val = parent::getField($field);
if (in_array($field, static::$fieldsToEncrypt)) {
$key = $this->getEncryptionKey();
try {
$newVal = Crypto::decrypt($val, $key);
$val = $newVal;
} catch (Exception $e) {
}
}
return $val;
}
public function getDate()
{
// Cast it to DateTime
return DBField::create_field('DateTime', $this->getField('Date'));
}