Я читал эту страницу – http://deaduseful.com/blog/posts/50-php-optimisation-tips-revisited
И одна из рекомендаций заключалась в том, чтобы избегать использования Магических методов, приведенных в PDF-файле Zend, который не дает никаких оснований для его рекомендации избегать их.
После некоторого поиска в Google (и, вернувшись сюда к несвязанному вопросу), я задавался вопросом, есть ли у кого-то какие-либо рекомендации на этом фронте?
Я использую __get () много в моем коде, обычно для сохранения переменных, которые я не всегда использую, например
У меня может быть таблица с именем, desc, category_id, time_added
Мой get будет выглядеть примерно так:
public function __get ($ name) { switch ($ name) { case 'name': case 'desc': case 'category': case 'time_added': $ result = do_mysql_query (); $ this-> name = $ result ['name']; $ this-> desc = $ result ['desc']; $ this-> category = $ result ['category']; $ this-> time_added = $ result ['time_added']; return $ this -> {$ name}; ломать; по умолчанию: throw Exception («Попытка получить доступ к несуществующей или частной собственности -». $ name); } }
Это похоже на отличный способ сделать что-то, потому что я когда-либо получаю что-то из базы данных, если это необходимо, и я могу возвращать такие вещи, как $ article-> time_added, а не возиться с массивами.
Будет ли это считаться плохой практикой и дополнительной нагрузкой на сервер?
Часто я буду расширять классы с помощью магических методов и делать что-то вроде этого, если дочерний класс не соответствует чему-то в get.
public function __get ($ name) { switch ($ name) { case 'name': case 'desc': case 'category': case 'time_added': $ result = do_mysql_query (); $ this-> name = $ result ['name']; $ this-> desc = $ result ['desc']; $ this-> category = $ result ['category']; $ this-> time_added = $ result ['time_added']; return $ this -> {$ name}; ломать; по умолчанию: return parent :: __ get ($ name); } }
Будет ли это плохой практикой и плохим для производительности? Максимальное количество уровней, которое я получаю при распространении магических методов, – три.
Это правда, они медленнее … но разница настолько крошечная, что скорость против кода является фактором. Стоит ли беспокоиться о различии для более быстрого развития и обслуживания?
См. Магические критерии для статистики
Рассмотрите возможность использования аксессуаров массива .
class Record implements ArrayAccess { /** * @see ArrayAccess::offsetExists() * * @param offset $offset */ public function offsetExists($offset) { } /** * @see ArrayAccess::offsetGet() * * @param offset $offset */ public function offsetGet($offset) { //fetch and cache $result return $result[$offset]; } /** * @see ArrayAccess::offsetSet() * * @param offset $offset * @param value $value */ public function offsetSet($offset, $value) { } /** * @see ArrayAccess::offsetUnset() * * @param offset $offset */ public function offsetUnset($offset) { }
Я провел несколько тестов с помощью магических методов PHP и собственных операций get / set (в публичном свойстве)
Результаты:
Магические методы намного медленнее, чем собственный доступ. НО время доступа все еще так мало, что это не повлияет на 99,9% всех случаев.
Даже если вы делаете 1 миллион магических методов доступа в рамках одного запроса, он все равно занимает около 0,1 секунды …
«Только чтение» означает доступ через магические методы. На изображении показаны результаты PHP 5.5.9 и PHP 7.0.
Вот эталонный сценарий: https://github.com/stracker-phil/php-benchmark/blob/master/benchmark.php