Почему PHP не разрешает частные константы?
Я знаю, что есть обходные пути, например, использование частного статического свойства.
Однако, с точки зрения ООП или разработки программного обеспечения, в чем были причины?
Почему PHP не разрешает частные константы?
В PHP-константы являются частью интерфейса, и интерфейс является общедоступным, всегда (для этого нужен интерфейс).
Смотрите также PHP-интерфейсы .
Я почти уверен, что это причина, разумная.
Что касается комментария по вашему вопросу о том, что кто-то хочет уменьшить видимость констант, чтобы изменить их позже, я бы сказал, что это больше похоже на переменную, чем константа, которая не меняет ее значение. Это постоянно.
ТЛ; тр
Какова была причина не применять частные константы?
Это хороший вопрос.
Действительно ли они это рассматривали?
Я не знаю.
При поиске в списке рассылки внутри PHP я ничего не нашел об этом. Если член внутренних не говорит, мы никогда не узнаем.
Что касается истории языка – перенос метода бит 1: 1 C, некоторые бит из Perl (regexp), некоторые бит Java (oop) – возможно, эта идея возникла, ища новые языковые функции.
Я бы связал концепцию «частной константы» с VisualBasic или Java. Я сомневаюсь, что VB имеет большое влияние на PHP. VB позволяет определять «частные константы» в «Модулях» – это область доступа по умолчанию. Visual Basic не допускает константы в интерфейсах и пространствах имен (но PHP делает).
PHP может включать некоторые концепции ООП из Java, но есть одна большая разница: константы являются переменными в Java. Их модификаторы доступа / уровни видимости: «общедоступный, закрытый, конечный и статический». "private static final String MYCONST = "My Constant";
выглядит так: "private static final String MYCONST = "My Constant";
это ООП – конец истории. Постоянный доступ к PHP становится более хакерским по сравнению с этим – НО это более просто, и у вас все еще есть обходной путь.
Первый комментарий в руководстве PHP для констант класса :
Это может показаться очевидным, но константы класса всегда общедоступны. Они не могут быть закрыты или защищены. Я не вижу, чтобы это указывалось в документах где угодно.
Почему это очевидно? «Почему постоянный класс по умолчанию по умолчанию, а не частный?» Возможно, это недостающая особенность языка, потому что не все члены класса могут быть скрыты должным образом. И он прав, когда вы приходят с Java или VB на PHP, этот вопрос всплывает.
Давайте рассмотрим спецификацию PHP . Текущее состояние реализации в PHP: константы класса всегда являются общедоступными и статическими. Итак, снова и снова, большие пальцы вверх для Facebook для написания такого подробного документа: автор рассматривал разные уровни видимости или контроля доступа.
Давайте посмотрим на интерфейс, класс, константу и видимость:
Как понятие «const» отличается от «частного статического»?
Статическая переменная может быть изменена, константа не может быть изменена. Вы не можете назначить значение времени выполнения функции для константы ( const A = sprintf('foo %s', 'bar');
), но для частного статического var.
Интерфейс может иметь константы – они не могут быть переопределены.
Класс может иметь константу, которая может быть переопределена наследующим классом / интерфейсом.
Существует также шаблон ООП, называемый «шаблоном постоянного интерфейса» – он описывает использование интерфейса только для определения констант, а классы реализуют этот интерфейс для достижения удобного синтаксического доступа к этим константам.
Предоставляется интерфейс, позволяющий описать набор функций, а затем скрыть окончательную реализацию функций в классе реализации. Это позволяет вам изменять реализацию функций, не изменяя, как вы его используете. Существуют интерфейсы для отображения API.
И, определяя константы в интерфейсе и реализуя интерфейс классом, константы становятся частью API. Фактически, вы пропускаете детали реализации в API. Вот почему некоторые считают, что это анти-шаблон, в том числе Джошуа Блох (Java).
Теперь давайте попробуем объединить некоторые понятия и посмотреть, подходят ли они.
Давайте сделаем вид, что пытаемся избежать критики сверху, тогда вам нужно ввести синтаксис, который позволяет квалифицированный доступ к константе, но скрывает константу в API. Вы можете придумать «Контроль доступа» через уровни видимости: «общественный, частный, защищенный, друг, враг». Цель состоит в том, чтобы запретить пользователям пакета или класса зависать от ненужных деталей реализации этого пакета или класса. Это все о скрытии деталей реализации, не так ли?
Как насчет «частных констант» в «интерфейсах»?
Это на самом деле решило бы критику сверху, верно? Но сочетание интерфейса с «частным», не имеет смысла. Эти понятия противоположны. Вот почему интерфейс не разрешает «частные» уровни доступа / видимости. И «частная» константа в «интерфейсе» также была бы взаимоисключающей.
Как насчет «частных констант» в «классах»?
class a { /*private*/ const k = 'Class private constant k from a'; } class b extends a { const k = 'Overridden private constant a::k with Class constant k from b'; const k_a = parent::k; // fatal error: self-referencing constant #const k_selfref = self::k . ' + ' . self::k_selfref; // fatal error: "static::" is not allowed in compile-time constants #const k_staticref = static::k; } // direct static access would no longer work, if private // you need an instance of the parent class or an inheriting class instance echo a::k; echo b::k; echo b::k_a; $obj_b = new b; echo $obj_b::k; echo $obj_b::k_a;
Есть ли польза?
Частная константа в классе не будет отображаться в API. Это хороший ООП.
Доступ к родительской константе извне был бы доступом класса и / или наследования.
echo a::k
, который теперь работает, может ответить «Фатальная ошибка: попытка получить доступ к частной константе без экземпляра класса или наследования».
(Это может работать только во время компиляции, если для const не назначено значение времени выполнения. Но я не уверен в этом.)
Есть ли оговорки?
Мы потеряли бы прямой статический доступ к константам.
Требование создания экземпляра класса, просто для доступа к константам, является пустой тратой ресурсов. Прямой статический доступ экономит ресурсы и прост. Если мы вводим private, это потеряно, и доступ будет привязан к экземпляру.
«Закрытая константа» неявно является «частной статической константой». Оператор доступа по-прежнему «::».
Возможным последующим изменением будет переход к неявным постоянным константам. Это перерыв в БК. Если вы переключите поведение по умолчанию на нестатический, оператор доступа изменится с «::» на «->». Это устанавливает правильный доступ к объектам ООП к константам, что сопоставимо с концепцией Java «константы как переменные с уровнем доступа». Это будет примерно так: http://3v4l.org/UgEEm . Оператор доступа изменяется на static, когда константа объявляется как «public static const», правильно?
Является ли пособие достаточно хорошим для его реализации?
Я не знаю. Это обсуждается. Мне нравится и то и другое: постоянный статический доступ, потому что он прост и понятен как «константы как переменные» и правильные уровни доступа.
После того, как это реализовано, чтобы сохранить ресурсы и продолжать идти быстро, каждый начинает (повторно) объявлять «public static const», отбрасывать требование экземпляра и нарушать OOP;)
И btw: я обнаружил переполнение HHVM, экспериментируя с кодом этого ответа.