PHP | define() против const
В PHP вы можете объявлять константы двумя способами:
С помощью ключевого слова
define
define('FOO', 1);
С использованием ключевого слова
const
const FOO = 1;
- В чем основные различия между этими двумя подходами?
- Когда и почему следует использовать один способ, а когда - другой?
5 ответ(ов)
Я знаю, что этот вопрос уже обсуждался, но ни один из существующих ответов не затрагивает тему пространств имен и их влияние на константы и определения.
Начиная с PHP 5.3, константы (const
) и определения (define
) по большинству аспектов схожи. Однако есть несколько важных отличий:
- Константы не могут быть определены с помощью выражения. Например,
const FOO = 4 * 3;
не сработает, тогда какdefine('CONST', 4 * 3);
сработает. - Имя, передаваемое в
define
, должно включать пространство имен, в котором оно будет определено.
Ниже приведён код, который иллюстрирует отличия:
namespace foo
{
const BAR = 1;
define('BAZ', 2);
define(__NAMESPACE__ . '\\BAZ', 3);
}
namespace {
var_dump(get_defined_constants(true));
}
Содержимое подмассива "user" будет равно ['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3]
.
=== ОБНОВЛЕНИЕ ===
В грядущем PHP 5.6 будет возможна небольшая гибкость в использовании const
. Теперь вы сможете определять константы в зависимости от выражений, при условии, что эти выражения состоят из других констант или литералов. Это значит, что следующее будет допустимо с версии 5.6:
const FOOBAR = 'foo ' . 'bar';
const FORTY_TWO = 6 * 9; // Для будущих редакторов: ЭТО УМЫШЛЕННО! Читайте комментарии к ответу для подробностей
const ULTIMATE_ANSWER = 'The ultimate answer to life, the universe and everything is ' . FORTY_TWO;
Тем не менее, вы всё ещё не сможете определять константы на основе переменных или возвращаемых значений функций, так что
const RND = mt_rand();
const CONSTVAR = $var;
по-прежнему не будет работать.
define
я использую для глобальных констант.
const
я использую для констант в классах.
Вы не можете использовать define
в области видимости класса, а с const
это возможно.
Кроме того, с const
константа фактически становится членом класса, в то время как define
создаёт константу в глобальной области видимости.
Да, вы правы! Начиная с PHP 5.3, вы можете использовать const
для объявления констант вне классов. Это подтверждается документацией на официальном сайте PHP. Вот пример, который показывает, как это работает:
<?php
// Работает начиная с PHP 5.3.0
const CONSTANT = 'Hello World';
echo CONSTANT;
?>
В данном коде создается константа CONSTANT
со значением 'Hello World'
, и после этого с помощью echo
выводится текст этой константы. Вы можете использовать константы, объявленные таким образом, в любом месте вашего кода.
Ответ NikiC является лучшим, но я хочу добавить неочевидное предупреждение при использовании пространств имен, чтобы вы не попали в ловушку неожидаемого поведения. Важно помнить, что константы (defines) всегда находятся в глобальном пространстве имен, если вы не добавите пространство имен как часть идентификатора. Неочевидно, что идентификатор с пространством имен имеет приоритет над глобальным идентификатором. Например:
<?php
namespace foo
{
// Обратите внимание: когда это ссылается на данное пространство имен, константа скрывает определенную версию
// Это может быть не тем, что вы ожидаете
const BAR = 'cheers';
define('BAR', 'wonka');
printf("Какой бар это %s бар?\n", BAR);
// Чтобы получить доступ к определению в глобальном пространстве имен, нужно явно указать его
printf("Какой бар это %s бар?\n", \BAR);
}
namespace foo2
{
// Теперь в другом пространстве имен (например, в стандартном) тот же синтаксис вызывает
// определенную версию!
printf("Уилли %s\n", BAR);
printf("три %s\n", \foo\BAR);
}
?>
Это приводит к следующему выводу:
Какой бар это cheers бар?
Какой бар это wonka бар?
уилли wonka
три cheers
На мой взгляд, это делает концепцию констант ненужным образом запутанной, так как идея константы в десятках других языков заключается в том, что она остается неизменной везде в вашем коде, и PHP на самом деле не гарантирует этого.
Большинство этих ответов неверны или отражают только половину правды.
- Вы можете ограничить область видимости своих констант с помощью пространств имен.
- Вы можете использовать ключевое слово "const" вне определений классов. Однако, как и в классах, значения, присвоенные с помощью ключевого слова "const", должны быть константными выражениями.
Например:
const AWESOME = 'Bob'; // Верно
Плохой пример:
const AWESOME = whatIsMyName(); // Неверно (Вызов функции)
const WEAKNESS = 4 + 5 + 6; // Неверно (Арифметика)
const FOO = BAR . OF . SOAP; // Неверно (Конкатенация)
Чтобы создать переменные-константы, используйте define()
следующим образом:
define('AWESOME', whatIsMyName()); // Верно
define('WEAKNESS', 4 + 5 + 6); // Верно
define('FOO', BAR . OF . SOAP); // Верно
Разница между const int*, const int * const и int * const?
UTF-8 на всех уровнях!
Сортировка двумерного массива по значению в столбце
Что означает "const" в конце объявления функции?
Как передать переменные и данные из PHP в JavaScript?