PHP – Zend сказал, избегайте Волшебных Методов?

Я читал эту страницу – 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