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/).