Проблемы с запуском функции на __get и __set

Я пришел к решению, основанному на ответе сумеречного ответа. Он ответил на вопрос, который я задал. Это здесь для всех в будущем — в основном для себя.

Как он упомянул, выданный лгал в $this->{$key} = $val;

Я обновил __constructor присвоить значения защищенному атрибуту $attributes а не сам объект, который позволяет __get а также __set быть запущенным правильно.

Я оставил остальную часть кода нетронутым.


Я недавно начал работать над новым проектом, с которым я не знаком, так что терпите меня. У нас есть пользовательские классы, написанные для извлечения записей из MongoDB и Sql Server. Все модели Sql Server и Mongo в конечном итоге расширят Model класс с их соответствующими MongoModel а также MsSqlModel классы между ними.

Пример: Vendor extends MongoModel > MongoModel extends DatabaseModel > DatabaseModel extends Model

class Model implements JsonSerializable, IteratorAggregate {
...
public function __construct($attributes = []) {
foreach ( $attributes as $key => $val )
$this->{$key} = $val;
}
...
public function &__get($key) {
if ( $this->isPrivateKey($key) ) {
return $this->$key;
} else {
return $this->attributes[$key];
}
}

public function __set($key, $value) {
if ( $this->isPrivateKey($key) ) {
$this->$key = $value;
} else {
$this->attributes[$key] = $value;
}
}
...
}

Для целей тестирования я включил Cryptarch класс и Encryptable класс в Vendor файл модели. Cryptarch имеет только две функции encrypt а также decrypt — При необходимости я могу опубликовать их, но они ничего особенного, так как я не эксперт по безопасности.

trait Encryptable {

public function &__get($key) {

$value = parent::__get($key);

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

return $value;

}

public function __set($key, $value) {

if ( in_array($key, $this->encryptable) ) {
$value = Cryptarch::encrypt($value);
}

parent::__set($key, $value);

}

}

class Vendor extends MongoModel
{
use Encryptable;

protected $encryptable = [
'ssn'
];
...
}

В связи с этим я пытаюсь автоматически зашифровать / расшифровать конфиденциальную информацию, когда атрибут модели устанавливается (шифровать) или получает (расшифровывать).

На своей странице я просто загружаю запись, на которой хочу проверить:
$res = Vendor::load('myid');
Если я var_dump($res->ssn) Я получаю зашифрованная значение вместо расшифрованный значение.

Если я установлю значение $res->ssn = 'somethingelse'; а также var_dump($res->ssn) это выводит string(13) "somethingelse",

тем не мение, если я уберу __set функция от Encryptable и попытаться вывести $res->ssn Я получаю правильно расшифрованное значение.

Если я var_dump параметр в Cryptarch::decrypt($val) Я получаю правильное значение из БД (в зашифрованном виде) — но если я пытаюсь var_dump «расшифрованный» результат и exit; из функции расшифровки он возвращает зашифрованное значение не bool(false) лайк openssl_decrypt должен вернуться, если не получится. Если я переопределить ($val = 'encryptedstring';) параметр в расшифрованном виде с прямым значением из БД и var_dump в расшифрованном виде все работает нормально.

Теперь остальная часть страницы / сайта работает с Vendor с использованием Encryptable черта характера. Я все еще могу устанавливать значения, сохранять их, извлекать их и т. Д. Единственное, что вызывает зависание, — это попытка расшифровать значение, возвращающее то же значение вместо bool(false) лайк openssl_decrypt следует, если это не удается, и установка значения не шифрует его.

0

Решение

Вы сталкиваетесь с ограничением PHP — __get а также __set магические функции запускаются только при обращении к атрибуту, который не существует на объекте. Их никогда не вызывают для существующих атрибутов.

Ваша реализация __set включает в себя:

$this->$key = $value;

который мог бы устанавливать атрибуты на объекте. Любой атрибут, который был создан таким образом, больше не будет вызывать __get или же __set методы.

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector