кэшировани объектов в ОП

Василий М.

Новичок
Писал свою ORM, наткнулся на косяк, связанный с кэшированием объектов во время жизни сценария.
Как раньше было: если объект доставался из базы и у него было свойство ID, то объект сохранялся
в многомерный массив в структуру типа [Модуль][Класс][ID] = object

PHP:
$model = UserMapper::findById(123);
$model->name = 'Петя';
UserMapper::save($model);
// в след строке не было смысла, т.к. была бы возвращена ссылка на $model из внетреннего хранилища абстрактного маппера.
$model_1 = UserMapper::findById(123);
Таким образом осуществлялось кэширование объектов и это давало результаты.

Проблема выскрылась, когда обнаружилось, что кэшировались объекты, содержащие не полные данные.
Такие объекты тоже попадали в кэш.
Соотвтетственно кэширование вида [Модуль][Класс][ID] = object
стало работать не верно, т.к. в кэше могли храниться объекты, содержащие например только свойство ID
и строка
PHP:
$model = UserMapper::findById(123);
могла бы мне выдать объект с неполными свойствами.

Возникает вопрос - как точно идентифицировать результат.
Идея - хранить SQL запрос как ключ (естественно, после всеразличных prepare и в md5) и по этому по сути уникальному ключу и проверять наличие объектов в памяти.

Я прав?
 

hell0w0rd

Продвинутый новичок
в доктрине это решено прокси-классами. Для любой сущности создается прокси-класс, который оборачивает все геттеры в проверку загружена ли сущность, или нет. Это позволяет организовать ленивую загрузку, когда известен только PK из базы.
 

keltanas

marty cats
У меня сразу встречный вопрос: А по какой причине объекты попадают в кеш неполными? Может, устранить эту причину?
 

Василий М.

Новичок
Пичина в том, что данные ВСЕГДА вытягиваются исключительно как объекты.
Объект - это оболочка над таблицей с первичным ключом.
 

keltanas

marty cats
Ну правильно. AR как AR.
PHP:
$model = UserMapper::findById(123);
$model->name = 'Петя';
UserMapper::save($model);
// в след строке не было смысла, т.к. была бы возвращена ссылка на $model из внетреннего хранилища абстрактного маппера.
$model_1 = UserMapper::findById(123);
А что не так в этом коде? На мой взгляд он совершенно верно себя ведет.
Если $model получаешь по ссылке (а мы о PHP5 говорим?), то и ->name должно было измениться у объекта по ссылке в кеше.
 
Сверху