OO PHP прямой доступ к членам

Я всегда думал, что вы никогда не должны устанавливать / получать переменную-член напрямую. Например

$x = new TestClass();
$x->varA = "test":
echo $->varB;

Я думал, что вы всегда должны использовать методы объекта для доступа к переменным-членам.

Но я только что посмотрел на __set и __get, что означает, что можно напрямую обращаться к участникам.

7 ответов

Решение

Здесь нет правильного ответа.

Вначале прямой доступ к переменным-членам считался плохой идеей, потому что вы теряете возможность сделать этот доступ условным для некоторого набора произвольной логики программирования. Вот почему у нас есть ужас методов получения и установки.

Наличие магических методов, таких как __set а также __get снимает эту проблему У вас могут быть пользователи ваших переменных доступа к объекту, которые вы хотите, и затем, если вы обнаружите, что вам нужна программная логика для этого доступа, вы можете использовать магические методы.

Тем не менее, особенно в PHP, __set а также __get не свободны с точки зрения производительности. Кроме того, помните, что __set а также __get Вызываются только при доступе к недоступной (приватной, защищенной и т. д.) переменной-члену. Это означает, что нет способа вызвать __set а также __get внутри класса, вне удаления переменной-члена из определения класса, что делает ваш класс менее понятным.

Как и большинство вещей PHP, нет ясного "лучшего" способа справиться с этим.

Не только в PHP, но и в объектно-ориентированном программировании в целом, если в классе есть переменные-члены, для которых нет необходимости выполнять код при обращении к ним, нет необходимости создавать методы установки и получения, и к переменным можно обращаться напрямую.

Доступ к свойствам (переменным) объекта в порядке, если они общедоступны.

Если они защищены / закрыты (что является чем-то новым в PHP 5, чего не было в PHP 4), вы не можете получить к ним доступ напрямую.

Выполнение этого или прохождение доступа зависит от того, что вам нужно / что вы хотите сделать:

  • если вы хотите получить доступ только к данным, вам не нужны средства доступа
  • если вы хотите выполнить какие-либо действия при доступе к данным (например, проверьте правильность значения), вам следует использовать средства доступа - держите пари, это метод maginc __get/__set или нет.
  • Использование этих двух магических методов имеет то преимущество, что оно прозрачно для пользователя; и вы можете добавлять их в любое время, не заставляя пользователей переписывать их код.
  • Но обратите внимание, что использование геттеров / сеттеров, как говорят, имеет свою стоимость (когда вы говорите о производительности, это стоит некоторого ЦП, поскольку вы должны вызывать метод)

В конце концов, нет "правильного", а не "лучшего" пути: есть два пути, и вам решать, какой из них лучше всего подходит для ваших нужд.

Для моих собственных проектов вот что я обычно делаю:

  • когда мне не нужно ничего проверять, я не использую методы получения / установки
  • когда мне нужно особое поведение, я объявляю свои переменные как protected/privateи создать специальный метод получения / установки (например, getName/setName)
    • это дает преимущество наличия phpdoc для каждого метода и подсказки в IDE, которую я использую, кстати

До PHP 5 вы могли это сделать. С введением PHP 5 вы можете объявлять закрытые переменные. Так что нет ничего необычного в том, чтобы видеть коды PHP 4, которые обращаются к переменным напрямую, потому что нет никаких правил для частных переменных.

Я думаю, что можно обращаться к переменным класса напрямую. Если вы не хотите, чтобы другие классы модифицировали эти переменные, вы можете сделать их приватными. Если у вас есть общедоступный метод получения и установки, который строго копирует значение, переданное в поле класса, я думаю, что это просто слишком сложный подход.

Единственная ситуация, которую я могу придумать, где вы хотите использовать getter или setter, это когда вам нужно как-то обработать значение.

Правильная вещь с точки зрения пуристической ОО - создать свой собственный метод установки / получения (в идеале путем перегрузки PHP), который делает доступными соответствующие данные. (PHP эффективно предоставляет вам общие версии этого с __get и __set, но они позволят вам получить / установить все, что, скорее всего, не идеально.)

Вы также должны установить все переменные (и, действительно, методы) в классе, чтобы они имели правильную видимость (приватную, защищенную и т. Д.), Поэтому вы должны использовать методы set/get.

Посмотрите на руководство:
http://us2.php.net/manual/en/language.oop5.magic.php

Магические методы
Имена функций __construct, __destruct, __call, __callStatic, __get, __set, __isset, __unset, __sleep, __wakeup, __toString, __invoke, __set_state и __clone являются магическими в классах PHP. Вы не можете иметь функции с этими именами ни в одном из ваших классов, если вы не хотите магическую функциональность, связанную с ними. 

предосторожность
PHP резервирует все имена функций, начинающиеся с __, как магические. Рекомендуется не использовать имена функций с __ в PHP, если вы не хотите документировать некоторые магические функции. 

Просто сделайте хороший ООП (я предлагаю вам объявить методы получения и установки против прямого доступа к переменным...) и забыть о __get и __set. Если я не ошибаюсь, есть также вызов __call для вызова произвольных методов. Это MAGIC-методы, которыми они не являются не предназначен для обычных операций.

Вам не следует использовать __get и __set или __call, если вы не пишете очень специфический код (например, некоторую платформу или что-то для прокси-вызовов для других объектов, как в библиотеке php Javabridge http://php-java-bridge.sourceforge.net/).

Другие вопросы по тегам