Модели данных в php
Я экспериментирую с очень малоизвестными моделями данных в php. Например, если у меня есть таблица с именем "model_attributes" в базе данных SQL. Это список всех доступных атрибутов для модели, над которой я работаю. Теперь я хочу, чтобы модель и другие модели могли выводить функции из этого списка для извлечения данных из массива после загрузки данных в массив из конструктора. Вот пример в псевдокоде:
for each attributes as attribute
create new function ( getAttributeName )
а также
getAttributeName()
было бы
return $this->_model_data['attribute_name']
Во-первых, это хорошая практика? Кажется организованным, но в то же время кажется грязным. Может быть, кто-то может дать мне несколько других советов о том, как обрабатывать большие модели данных в php.
Кроме того, если кто-то сделал что-то подобное, как я мог бы справиться с этим в phpDocs?
2 ответа
Вы не сможете сделать это легко во время выполнения с PHP.
Вы можете использовать существующий ORM, например Doctrine или Propel.
Или вы можете предварительно сгенерировать файлы классов модели или использовать магические методы.
Быстрый пример:
class something {
private $_model_data;
public function __call($name, $value = null) {
if (strpos($name, 'get') === 0) {
$attribute = substr($name, 3);
return $this->_model_data[$attribute];
} else if (strpos($name, 'set') === 0) {
$attribute = substr($name, 3);
$this->_model_data[$attribute] = $value;
}
}
}
__call
это магический метод, который вызывается, когда метод не существует. Итак, звоня getAttributeName
на экземпляр класса будет вызывать __call
со строкой getAttributeName
в качестве первого аргумента.
Если вы просто хотите получить доступ к массиву model_data
из контекста объекта контейнера, вы должны использовать либо __get
волшебный метод, или реализовать ArrayAccess
интерфейс.
__get
это простой выход, так как реализация будет выглядеть примерно так:
function __get($name)
{
if (array_key_exists($name, $this->model_data))
{
return $this->model_data[$name];
}
return;
}
Чтобы получить доступ к данным, вам нужно просто вызвать свойство объекта: $obj->property_name
или в случае, если вы используете строку: $obj->{$property}
Конечно, это может помешать любым общедоступным атрибутам, которые у вас есть (как правило, плохая идея иметь их в любом случае).
В качестве альтернативы вы можете настроить свой объект как реализацию ArrayAccess, которая позволит вам получить доступ к свойству как: $obj['property_name']
, или же $obj[$property]
Оба решения позволят вам иметь настраиваемое управление доступом, если вы хотите запутать имена ваших полей или настроить порядок получения данных позже.
AFAIK метод ArrayAccess быстрее, но вам нужно проверить его, чтобы быть уверенным. Магические методы имеют тенденцию быть немного медленными.