Являются ли глобальные константы PHP хорошей современной практикой развития?

Я работаю над новым проектом с большой кодовой базой PHP. Приложение использует довольно много PHP-констант ( define('FOO', 'bar') ), особенно для таких вещей, как параметры подключения к базе данных. Эти константы определены в одном файле конфигурации, который require_once() 'd напрямую, в основном, каждому классу приложения.

Несколько лет назад это имело бы смысл, но с тех пор я получил ошибку Unit Testing, и эта плотная связь между классами действительно беспокоит меня. Эти константы пахнут как глобальные переменные, и они ссылаются непосредственно на код приложения.

Это еще хорошая идея? Было бы разумно скопировать эти значения в объект и использовать этот объект (то есть Bean – там, я сказал), чтобы передать их через инъекцию зависимостей классам, которые взаимодействуют с базой данных? Я могу победить любые преимущества PHP-констант (скажем, скорость или что-то еще), выполнив это?

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

По моему мнению, константы должны использоваться только в двух случаях:

  • Фактические постоянные значения (т.е. вещи, которые никогда не будут меняться, SECONDS_PER_HOUR ).
  • OS-зависимые значения, пока константа может быть использована прозрачно приложением, в любой ситуации.

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

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

Эти константы пахнут как глобальные переменные, и на них прямо ссылаются […]. Было бы разумно скопировать эти значения в объект и […] передать их через инъекцию зависимостей?

Абсолютно! Я бы пошел еще дальше и сказал, что даже классовые константы следует избегать. Поскольку они являются общедоступными, они выставляют внутренние компоненты, и они являются API, поэтому вы не можете легко их изменить, не рискуя нарушить существующие приложения из-за жесткой связи. Объект конфигурации имеет гораздо больший смысл (просто не делайте его Singleton).

Также см:

Чтобы ответить на этот вопрос, важно обсудить стиль написания кода.

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

FOO_BAR конце концов, FOO_BAR может быть FOO::BAR , это сводится к тому, где вы хотите определить константу.

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

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

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

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

Если у вас PHP 5.3 или новее, вы можете использовать namespace .
http://www.php.net/manual/en/language.namespaces.php

Он работает с const variable = 'something';
К сожалению, это не wokrk с define('variable','something');

Глобалы в пространстве имен инкапсулируются. В некоторых ситуациях это лучше, чем наличие объекта.

Я не согласен с константами, а не с жестким кодом 🙂

Я предпочитаю, производительность в стороне, Zend_Config_Ini из ZendFramework.

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

http://framework.zend.com/manual/en/zend.config.adapters.ini.html