О производительности (пустая трата времени с микрооптимизацией, как у меня), смотрите ответ : constв два раза быстрее, чем define. О времени загрузки страницы и использовании памяти: см. Этот вопрос и эту статью ... Смотрите также кое-что о кеше кода операции здесь .
Питер Краусс
2
Не смотрите только на текущий принятый ответ, но посмотрите на stackoverflow.com/a/3193704/1412157, поскольку это должен был быть принятый ответ
LucaM
1
Только что увидел уведомление для вашего комментария. Я обновил принятый ответ.
danjarvis
Ответы:
1039
Начиная с PHP 5.3, есть два способа определения констант : либо используя constключевое слово, либо используя define()функцию:
const FOO ='BAR';
define('FOO','BAR');
Принципиальное различие между этими двумя способами состоит в том, что они constопределяют константы во время компиляции, тогда как defineопределяют их во время выполнения. Это вызывает большинство constроссийских недостатков. Некоторые недостатки const:
constне может использоваться для условного определения констант. Чтобы определить глобальную константу, она должна использоваться во внешней области видимости:
Зачем тебе это делать? Одним из распространенных применений является проверка, была ли константа уже определена:
if(!defined('FOO')){
define('FOO','BAR');}
constпринимает статический скаляр (число, строку или другую константу , как true, false, null, __FILE__), в то время как define()принимает любое выражение. Начиная с PHP 5.6 допускаются constтакже константные выражения :
const BIT_5 =1<<5;// Valid since PHP 5.6 and invalid previously
define('BIT_5',1<<5);// Always valid
constпринимает простое имя константы, тогда как define()принимает любое выражение в качестве имени. Это позволяет делать такие вещи:
consts всегда чувствительны к регистру, в то время как define()позволяет вам определять нечувствительные к регистру константы, передавая trueв качестве третьего аргумента (Примечание: определение нечувствительных к регистру констант не рекомендуется с PHP 7.3.0.):
define('FOO','BAR',true);
echo FOO;// BAR
echo foo;// BAR
Итак, это была плохая сторона вещей. Теперь давайте посмотрим на причину, по которой я лично всегда использую, constесли не происходит одна из вышеперечисленных ситуаций:
constпросто читает лучше. Это языковая конструкция вместо функции, которая также согласуется с тем, как вы определяете константы в классах.
constбудучи языковой конструкцией, может быть статически проанализирован с помощью автоматизированного инструментария.
constопределяет константу в текущем пространстве имен, в то время define()как должно быть передано полное имя пространства имен:
namespace A\B\C;// To define the constant A\B\C\FOO:const FOO ='BAR';
define('A\B\C\FOO','BAR');
Начиная с PHP 5.6 constконстанты также могут быть массивами, но пока define()не поддерживают массивы. Однако массивы будут поддерживаться в обоих случаях в PHP 7.
const FOO =[1,2,3];// Valid in PHP 5.6
define('FOO',[1,2,3]);// Invalid in PHP 5.6 and valid in PHP 7.0
Наконец, обратите внимание, что constтакже можно использовать внутри класса или интерфейса для определения константы класса или константы интерфейса. defineне может быть использован для этой цели:
classFoo{const BAR =2;// Valid}// ButclassBaz{
define('QUX',2);// Invalid}
Резюме
Если вам не нужен какой-либо тип условного или экспрессивного определения, используйте consts вместо define()s - просто для удобства чтения!
Как я знаю, в PHP 5.6 вы получите возможность использовать простые скалярные выражения даже с constязыковой конструкцией - см. Wiki.php.net/rfc/const_scalar_exprs
mabe.berlin
6
Еще одним преимуществом использования constявляется отсутствие кавычек, что означает, что он отформатирован так же, как и в вашей IDE.
rybo111
3
Это должно быть то, что в документации PHP. Это лучшее объяснение, которое я видел, особенно ту часть, которую большинство людей забывают (компиляция против времени выполнения).
Джеймс
4
define('a', $_GET['param']);, const b = a;работает отлично и получает значение, пока const c = $_GET['param'];недействительно. Действительно constли время компиляции? Я так не думаю ... (проверено на PHP 7.0.7)
До PHP 5.3 constне могли использоваться в глобальном масштабе. Вы можете использовать это только внутри класса. Это следует использовать, когда вы хотите установить какую-то постоянную опцию или параметр, относящийся к этому классу. Или, может быть, вы хотите создать какое-то перечисление.
defineможет использоваться для той же цели, но может использоваться только в глобальной области видимости. Его следует использовать только для глобальных настроек, которые влияют на все приложение.
Примером хорошего constиспользования является избавление от магических чисел. Посмотрите на константы PDO . Когда вам нужно указать тип выборки, вы должны напечатать PDO::FETCH_ASSOC, например. Если бы conts не использовались, вы бы в конечном итоге набрали что-то вроде 35(или что-то FETCH_ASSOCопределено как). Это не имеет смысла для читателя.
Примером правильного defineиспользования может быть указание корневого пути вашего приложения или номера версии библиотеки.
Возможно, стоит упомянуть использование constс пространствами имен.
Salathe
31
Следует также отметить, что PHP5.3 может очень широко использовать const в глобальной области видимости.
Гордон
5.2 тоже может. Прелесть «против и против» в том, что вы должны поставить перед ними префикс имени класса. Их использование делает код более читабельным и красивым. И это бонус для меня.
выгодно
1
@ryeguy, но что после PHP 5.3, где const можно использовать глобально, как define?
Я знаю, что на этот вопрос уже дан ответ, но ни в одном из текущих ответов не упоминается пространство имен и то, как оно влияет на константы и определения.
Начиная с PHP 5.3, константы и определения во многом похожи. Однако есть еще несколько важных отличий:
Констант нельзя определить из выражения. 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));}
Предстоящий PHP 5.6 позволит немного больше гибкости с const. Теперь вы сможете определять константы в терминах выражений при условии, что эти выражения состоят из других констант или литералов. Это означает, что следующее должно быть действительным с 5.6:
const FOOBAR ='foo '.'bar';const FORTY_TWO =6*9;// For future editors: THIS IS DELIBERATE! Read the answer comments below for more detailsconst ULTIMATE_ANSWER ='The ultimate answer to life, the universe and everything is '. FORTY_TWO;
Вы по-прежнему не сможете определять константы в терминах переменных или возвратов функций, поэтому
Я не мог удержаться от вопроса: вы сознательно определили FORTY_TWOкак 54?
Punchlinern
9
«Шесть на девять? Сорок два? Я всегда говорил, что во вселенной что-то в корне не так» Посмотрите работы Дугласа Адамса, если вам нужно полное объяснение.
GordonM
2
Ой. Я знал, что 42 - это жизнь, вселенная и все остальное, но я пропустил Шесть из девяти частей. Спасибо за объяснение!
Punchlinern
22
Я считаю, что начиная с PHP 5.3, вы можете использовать constвне классов, как показано здесь во втором примере:
Как отмечалось в других ответах, const можно использовать вне классов в PHP 5.3+
MrWhite
Только константное ключевое слово может быть использовано для создания константы пространства имен, а не только классов
Алиреза Рахмани Халили
16
Ответ NikiC - лучший, но позвольте мне добавить неочевидное предостережение при использовании пространств имен, чтобы вы не попали в неожиданное поведение. Следует помнить, что определения всегда находятся в глобальном пространстве имен, если вы явно не добавите пространство имен как часть идентификатора определения. Что не очевидно в этом, так это то, что идентификатор пространства имен превосходит глобальный идентификатор. Так :
<?php
namespace foo
{// Note: when referenced in this file or namespace, the const masks the defined version// this may not be what you want/expectconst BAR ='cheers';
define('BAR','wonka');
printf("What kind of bar is a %s bar?\n", BAR);// To get to the define in the global namespace you need to explicitely reference it
printf("What kind of bar is a %s bar?\n", \BAR);}namespace foo2
{// But now in another namespace (like in the default) the same syntax calls up the // the defined version!
printf("Willy %s\n", BAR);
printf("three %s\n", \foo\BAR);}?>
производит:
What kind of bar is a cheers bar?What kind of bar is a wonka bar?
willy wonka
three cheers
Для меня это делает бесполезным путаницу понятия const, поскольку идея const в десятках других языков заключается в том, что она всегда одинакова, где бы вы ни находились в коде, и PHP на самом деле не гарантирует этого.
Да, но BARи \foo\BARпросто не одинаковые константы. Я согласен, что это действительно сбивает с толку, но если вы также считаете, что такие вещи, как логика пространств имен, являются непротиворечивыми и что они constне define()похожи на макрос C ( #define), то у PHP может быть какое-то оправдание.
СЗ
1
Понятие const - это именно то, как оно должно вести себя - вы находитесь в пространстве имен! Вы хотите получить его без идентификатора пространства имен, а затем создать его вне пространства имен. Это также делает его совместимым с определением const в классе, даже если он использует другой синтаксис. Да, определение тоже соответствует, по-другому.
Джерард ONeill
12
Большинство из этих ответов неверны или рассказывают только половину истории.
Вы можете определить ваши константы, используя пространства имен.
Вы можете использовать ключевое слово "const" вне определений классов. Однако, как и в классах, значения, назначаемые с помощью ключевого слова «const», должны быть константными выражениями.
PHP> = 5.6 В Zend Engine Compiler были внесены некоторые изменения, и const теперь обрабатывается по-другому.
Анкит Вишвакарма
6
Да, const определяются во время компиляции, и, поскольку никическим состояниям не может быть назначено выражение, как может определить define (). Но также const не может быть объявлен условно (по той же причине). то есть. Ты не сможешь это сделать:
if(/* some condition */){const WHIZZ =true;// CANNOT DO THIS!}
В то время как вы могли бы с помощью define (). Таким образом, это не сводится к личным предпочтениям, есть правильный и неправильный способ использовать оба.
В качестве отступления ... Я хотел бы увидеть некоторый класс const, которому можно присвоить выражение, своего рода define (), который можно выделить в классы?
С помощью определения ключевого слова константы вы получите возможность учета регистра без учета регистра, а с помощью константного ключевого слова - нет.
const
в два раза быстрее, чемdefine
. О времени загрузки страницы и использовании памяти: см. Этот вопрос и эту статью ... Смотрите также кое-что о кеше кода операции здесь .Ответы:
Начиная с PHP 5.3, есть два способа определения констант : либо используя
const
ключевое слово, либо используяdefine()
функцию:Принципиальное различие между этими двумя способами состоит в том, что они
const
определяют константы во время компиляции, тогда какdefine
определяют их во время выполнения. Это вызывает большинствоconst
российских недостатков. Некоторые недостаткиconst
:const
не может использоваться для условного определения констант. Чтобы определить глобальную константу, она должна использоваться во внешней области видимости:Зачем тебе это делать? Одним из распространенных применений является проверка, была ли константа уже определена:
const
принимает статический скаляр (число, строку или другую константу , какtrue
,false
,null
,__FILE__
), в то время какdefine()
принимает любое выражение. Начиная с PHP 5.6 допускаютсяconst
также константные выражения :const
принимает простое имя константы, тогда какdefine()
принимает любое выражение в качестве имени. Это позволяет делать такие вещи:const
s всегда чувствительны к регистру, в то время какdefine()
позволяет вам определять нечувствительные к регистру константы, передаваяtrue
в качестве третьего аргумента (Примечание: определение нечувствительных к регистру констант не рекомендуется с PHP 7.3.0.):Итак, это была плохая сторона вещей. Теперь давайте посмотрим на причину, по которой я лично всегда использую,
const
если не происходит одна из вышеперечисленных ситуаций:const
просто читает лучше. Это языковая конструкция вместо функции, которая также согласуется с тем, как вы определяете константы в классах.const
будучи языковой конструкцией, может быть статически проанализирован с помощью автоматизированного инструментария.const
определяет константу в текущем пространстве имен, в то времяdefine()
как должно быть передано полное имя пространства имен:Начиная с PHP 5.6
const
константы также могут быть массивами, но покаdefine()
не поддерживают массивы. Однако массивы будут поддерживаться в обоих случаях в PHP 7.Наконец, обратите внимание, что
const
также можно использовать внутри класса или интерфейса для определения константы класса или константы интерфейса.define
не может быть использован для этой цели:Резюме
Если вам не нужен какой-либо тип условного или экспрессивного определения, используйте
const
s вместоdefine()
s - просто для удобства чтения!источник
const
языковой конструкцией - см. Wiki.php.net/rfc/const_scalar_exprsconst
является отсутствие кавычек, что означает, что он отформатирован так же, как и в вашей IDE.define('a', $_GET['param']);
,const b = a;
работает отлично и получает значение, покаconst c = $_GET['param'];
недействительно. Действительноconst
ли время компиляции? Я так не думаю ... (проверено на PHP 7.0.7)До PHP 5.3
const
не могли использоваться в глобальном масштабе. Вы можете использовать это только внутри класса. Это следует использовать, когда вы хотите установить какую-то постоянную опцию или параметр, относящийся к этому классу. Или, может быть, вы хотите создать какое-то перечисление.define
может использоваться для той же цели, но может использоваться только в глобальной области видимости. Его следует использовать только для глобальных настроек, которые влияют на все приложение.Примером хорошего
const
использования является избавление от магических чисел. Посмотрите на константы PDO . Когда вам нужно указать тип выборки, вы должны напечататьPDO::FETCH_ASSOC
, например. Если бы conts не использовались, вы бы в конечном итоге набрали что-то вроде35
(или что-тоFETCH_ASSOC
определено как). Это не имеет смысла для читателя.Примером правильного
define
использования может быть указание корневого пути вашего приложения или номера версии библиотеки.источник
const
с пространствами имен.Я знаю, что на этот вопрос уже дан ответ, но ни в одном из текущих ответов не упоминается пространство имен и то, как оно влияет на константы и определения.
Начиная с PHP 5.3, константы и определения во многом похожи. Однако есть еще несколько важных отличий:
const FOO = 4 * 3;
не работает, ноdefine('CONST', 4 * 3);
работает.define
должно включать пространство имен, которое должно быть определено в этом пространстве имен.Код ниже должен иллюстрировать различия.
Содержимое пользовательского подмассива будет
['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3]
.=== ОБНОВЛЕНИЕ ===
Предстоящий PHP 5.6 позволит немного больше гибкости с
const
. Теперь вы сможете определять константы в терминах выражений при условии, что эти выражения состоят из других констант или литералов. Это означает, что следующее должно быть действительным с 5.6:Вы по-прежнему не сможете определять константы в терминах переменных или возвратов функций, поэтому
все еще будет вне.
источник
FORTY_TWO
как 54?Я считаю, что начиная с PHP 5.3, вы можете использовать
const
вне классов, как показано здесь во втором примере:http://www.php.net/manual/en/language.constants.syntax.php
источник
define
Я использую для глобальных констант.const
Я использую для констант класса.Вы не можете
define
в поле зрения класса, а сconst
вами можете. Излишне говорить, что вы не можете использоватьconst
вне области видимости.Кроме того, с
const
, это фактически становится членом класса, и сdefine
, это будет перемещено в глобальную область.источник
Ответ NikiC - лучший, но позвольте мне добавить неочевидное предостережение при использовании пространств имен, чтобы вы не попали в неожиданное поведение. Следует помнить, что определения всегда находятся в глобальном пространстве имен, если вы явно не добавите пространство имен как часть идентификатора определения. Что не очевидно в этом, так это то, что идентификатор пространства имен превосходит глобальный идентификатор. Так :
производит:
Для меня это делает бесполезным путаницу понятия const, поскольку идея const в десятках других языков заключается в том, что она всегда одинакова, где бы вы ни находились в коде, и PHP на самом деле не гарантирует этого.
источник
BAR
и\foo\BAR
просто не одинаковые константы. Я согласен, что это действительно сбивает с толку, но если вы также считаете, что такие вещи, как логика пространств имен, являются непротиворечивыми и что ониconst
неdefine()
похожи на макрос C (#define
), то у PHP может быть какое-то оправдание.Большинство из этих ответов неверны или рассказывают только половину истории.
Например:
Плохой пример:
Для создания переменных констант используйте define () примерно так:
источник
Да, const определяются во время компиляции, и, поскольку никическим состояниям не может быть назначено выражение, как может определить define (). Но также const не может быть объявлен условно (по той же причине). то есть. Ты не сможешь это сделать:
В то время как вы могли бы с помощью define (). Таким образом, это не сводится к личным предпочтениям, есть правильный и неправильный способ использовать оба.
В качестве отступления ... Я хотел бы увидеть некоторый класс const, которому можно присвоить выражение, своего рода define (), который можно выделить в классы?
источник
Добавить ответ Никии.
const
может использоваться в классах следующим образом:Вы не можете сделать это с
define()
.источник
Никто ничего не говорит о php-doc, но для меня это тоже очень важный аргумент в пользу предпочтения
const
:источник
С помощью определения ключевого слова константы вы получите возможность учета регистра без учета регистра, а с помощью константного ключевого слова - нет.
источник