7

PHP | define() против const

6

В PHP вы можете объявлять константы двумя способами:

  1. С помощью ключевого слова define

    define('FOO', 1);
    
  2. С использованием ключевого слова const

    const FOO = 1;
    

  • В чем основные различия между этими двумя подходами?
  • Когда и почему следует использовать один способ, а когда - другой?

5 ответ(ов)

0

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

Начиная с 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;

по-прежнему не будет работать.

0

define я использую для глобальных констант.

const я использую для констант в классах.

Вы не можете использовать define в области видимости класса, а с const это возможно.

Кроме того, с const константа фактически становится членом класса, в то время как define создаёт константу в глобальной области видимости.

0

Да, вы правы! Начиная с PHP 5.3, вы можете использовать const для объявления констант вне классов. Это подтверждается документацией на официальном сайте PHP. Вот пример, который показывает, как это работает:

<?php
// Работает начиная с PHP 5.3.0
const CONSTANT = 'Hello World';

echo CONSTANT;
?>

В данном коде создается константа CONSTANT со значением 'Hello World', и после этого с помощью echo выводится текст этой константы. Вы можете использовать константы, объявленные таким образом, в любом месте вашего кода.

0

Ответ 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 на самом деле не гарантирует этого.

0

Большинство этих ответов неверны или отражают только половину правды.

  1. Вы можете ограничить область видимости своих констант с помощью пространств имен.
  2. Вы можете использовать ключевое слово "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); // Верно
Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь