Определение класса PHP: отдельные аксессоры / мутаторы или __set () с ключом ()?

При определении класса PHP, который является предпочтительным / лучшей практикой? Есть ли какие-то ключевые различия, которые я пропускаю?

Похоже, что может быть более чистым, лаконичным и удобным написать магический метод __set() и поместить в него конструкцию switch() с случаями для всех частных членов, к которым я хочу разрешить доступ. Это не было бы setFoo() внутри класса, но тогда и не было бы setFoo() , поэтому, если я хочу использовать внутреннее setFoo() доступа / мутатора, я должен был бы явно вызвать метод в любом случае.

Другое отличие состоит в том, что в коде вне класса я всегда мог обращаться к членам-членам таким же образом, как и $obj->foo , будь то public (напрямую) или private (с использованием __set() ), а также с использованием многих отдельных методов.

Я предполагаю, что это сводится в основном к эстетическому выбору. Например, если у меня есть адресные данные о покупке, я не хочу иметь 16 или более отдельных методов доступа только для имени, фамилии, адреса1, адреса2, города, штата и т. Д. Для отправки и выставления счетов.

Есть ли какие-то ключевые различия, которые я забыл? (Может ли сложная IDE отказаться от автоматического заполнения имени участника за пределами класса, потому что она помечена как конфиденциальная?) Действительно ли я ответил на свой собственный оригинальный вопрос? Спасибо заранее за ваш вклад.

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

  • Независимо от того, что вы используете для документирования вашего API (doxygen / PHPdoc / Zend), созданные документы не будут отображать членов, доступных через магические функции.
  • Вы можете документировать аксессоры. Вы действительно должны вставить такую ​​строку в документацию: « ВАЖНО! Эта функция подключается к базе данных, она будет очень медленной, используйте otherFunction (), если сможете».
  • Реализация устройства доступа легко доступна для всех. Я бы не захотел вникнуть в детали 200-строчной магической функции, чтобы проверить, делает ли аксессуар что-либо помимо установки / получения значения (поэтому мы все-таки пишем аксессоры).
  • Вы уже упоминали автозаполнение IDE.
  • Функция __get () имеет четко определенный заголовок функции, поэтому вы не сможете создавать геттеры, которые возвращают ссылку, например (что очень $numbers = &$object->getNumbers(); $numbers[] = 4; при работе с массивами, то есть $numbers = &$object->getNumbers(); $numbers[] = 4; – без ссылки, вам нужно будет снова вызвать setter.)

Самое большое различие, которое я вижу в phpdoc:

  • используя __set , вы не сможете генерировать phpdoc для каждого доступа
  • phpdoc используется средствами IDE современных, это также означает, что вы не будете получать подсказки типов или завершение кода, если вы используете магические методы (использование @property может помочь, однако, на этом этапе) .

Personnaly, я бы пошел с определением аксессоров самостоятельно, даже если это означает писать немного больше кода:

  • нет проблем с phpdoc
  • вы можете использовать любые параметры и возвращаемые типы, которые вы хотите
  • вы явно указываете, какие методы могут быть использованы
  • проще использовать конкретный код для каждой проприетарности, не имея действительно длинного метода __set .

Кроме того, я бы использовал эти методы доступа при настройке свойств внутри класса: это означает немного больше кода, да, но это также означает переход через определенный код (например, код для проверки некоторых вещей), которые они содержат.

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