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

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

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

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

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

Ответы [ 6 ]

6 голосов
/ 18 июля 2011

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

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

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

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

5 голосов
/ 18 июля 2011

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

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

Также см .:

4 голосов
/ 18 июля 2011

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

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

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

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

2 голосов
/ 18 июля 2011

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

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

1 голос
/ 18 июля 2011

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

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

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

0 голосов
/ 18 июля 2011

Я не согласен ни с константами, ни с жестким кодом :-)

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

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

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

...