Почему PHP не разрешает частные константы?

Почему 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, экспериментируя с кодом этого ответа.