Sobre desempenho (perda de tempo com micro-otimização como eu), veja esta resposta : consté duas vezes mais rápido que define. Sobre o tempo de carregamento da página e o uso de memória: consulte esta pergunta e este artigo ... Consulte também algo sobre o cache do opcode aqui .
Peter Krauss
2
Não só olhar para a resposta aceita atual, mas por favor, dê uma olhada para stackoverflow.com/a/3193704/1412157 como deveria ter sido a resposta aceita
Lucam
1
Acabei de ver a notificação do seu comentário. Atualizei a resposta aceita.
Danjarvis 30/07/2015
Respostas:
1039
No PHP 5.3, existem duas maneiras de definir constantes : Usando a constpalavra - chave ou a define()função:
const FOO ='BAR';
define('FOO','BAR');
A diferença fundamental entre essas duas maneiras é que constdefine constantes em tempo de compilação, enquanto as definedefine em tempo de execução. Isso causa a maioria das constdesvantagens. Algumas desvantagens constsão:
constnão pode ser usado para definir condicionalmente constantes. Para definir uma constante global, ela deve ser usada no escopo mais externo:
Por que você faria isso de qualquer maneira? Uma aplicação comum é verificar se a constante já está definida:
if(!defined('FOO')){
define('FOO','BAR');}
constaceita um escalar estática (número, string ou outra constante, como true, false, null, __FILE__), enquanto define()toma qualquer expressão. Desde PHP 5.6, expressões constantes também são permitidas const:
const BIT_5 =1<<5;// Valid since PHP 5.6 and invalid previously
define('BIT_5',1<<5);// Always valid
constrecebe um nome constante e simples, enquanto define()aceita qualquer expressão como nome. Isso permite fazer coisas como esta:
consts sempre diferenciam maiúsculas de minúsculas, ao passo que define()permitem definir constantes que não diferenciam maiúsculas de minúsculas, passando truecomo terceiro argumento (Nota: definir constantes que não diferenciam maiúsculas de minúsculas é preterido no PHP 7.3.0.):
define('FOO','BAR',true);
echo FOO;// BAR
echo foo;// BAR
Então, esse era o lado ruim das coisas. Agora, vamos ver o motivo pelo qual eu sempre uso pessoalmente, a constmenos que ocorra uma das situações acima:
constsimplesmente lê melhor. É uma construção de linguagem em vez de uma função e também é consistente com a forma como você define constantes nas classes.
const, sendo uma construção de linguagem, pode ser analisada estaticamente por ferramentas automatizadas.
constdefine uma constante no espaço para nome atual, enquanto define()deve ser passado o nome completo do espaço para nome:
namespace A\B\C;// To define the constant A\B\C\FOO:const FOO ='BAR';
define('A\B\C\FOO','BAR');
Como as constconstantes do PHP 5.6 também podem ser matrizes, enquanto define()ainda não suporta matrizes. No entanto, matrizes serão suportadas para ambos os casos no 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
Por fim, observe que consttambém pode ser usado em uma classe ou interface para definir uma constante de classe ou constante de interface. definenão pode ser utilizado para este fim:
classFoo{const BAR =2;// Valid}// ButclassBaz{
define('QUX',2);// Invalid}
Sumário
A menos que você precise de qualquer tipo de definição condicional ou expressional, use consts em vez de define()s - simplesmente para facilitar a leitura!
Como eu sei com PHP 5.6 você terá a possibilidade de usar expressões escalares simples mesmo com a constconstrução da linguagem - ver wiki.php.net/rfc/const_scalar_exprs
mabe.berlin
6
Outro benefício do uso consté a falta de aspas, o que significa que é formatado da mesma forma que é usado no seu IDE.
rybo111
3
Esse deve ser o conteúdo dos documentos PHP. É a melhor explicação que eu já vi, especialmente a parte que a maioria das pessoas esquece (compilação versus tempo de execução).
James
4
define('a', $_GET['param']);, const b = a;funciona perfeitamente e obtém o valor enquanto const c = $_GET['param'];é inválido. É constrealmente tempo de compilação? Eu dificilmente penso assim ... (testado no PHP 7.0.7)
mcserep 4/17/17
1
wiki.php.net/rfc/case_insensitive_constant_deprecation " No PHP 8.0: Remover a possibilidade de declarar constantes de maiúsculas e minúsculas. " para qualquer outra pessoa se aventurar aqui para o futuro no que diz respeito à sensibilidade caso
Scuzzy
196
Até o PHP 5.3, constnão podia ser usado no escopo global. Você só pode usar isso de dentro de uma classe. Isso deve ser usado quando você deseja definir algum tipo de opção constante ou configuração que pertence a essa classe. Ou talvez você queira criar algum tipo de enum.
definepode ser usado para a mesma finalidade, mas só pode ser usado no escopo global. Só deve ser usado para configurações globais que afetam o aplicativo inteiro.
Um exemplo de bom constuso é se livrar dos números mágicos. Dê uma olhada nas constantes da DOP . Quando você precisar especificar um tipo de busca, digite PDO::FETCH_ASSOC, por exemplo. Se consts não fossem usados, você acabaria digitando algo como 35(ou o que FETCH_ASSOCfor definido como). Isso não faz sentido para o leitor.
Um exemplo de bom defineuso é talvez especificar o caminho raiz do aplicativo ou o número da versão da biblioteca.
Vale a pena mencionar o uso de constcom namespaces.
Salathe
31
Deve-se notar também que o PHP5.3 pode usar const constantemente no escopo global.
Gordon
5.2 também pode. A beleza de consts vs. define é que você deve prefixá-los com o nome da classe. Usá-los torna o código mais legível e mais bonito. E isso é um bônus para mim.
lucifurious
1
@ryeguy, mas e depois do PHP 5.3, em que const pode ser usado globalmente como define?
andho
1
@andho, giz outro para a dança PHP de um passo à frente, um passo para trás, dança de "melhorias". Ele. :)
Contrato do Prof. Falken violado
37
Sei que isso já foi respondido, mas nenhuma das respostas atuais faz menção ao namespacing e como isso afeta constantes e define.
A partir do PHP 5.3, consts e define são semelhantes na maioria dos aspectos. Ainda existem, no entanto, algumas diferenças importantes:
Consts não podem ser definidos a partir de uma expressão. const FOO = 4 * 3;não funciona, mas define('CONST', 4 * 3);funciona.
O nome passado para definedeve incluir o espaço para nome a ser definido dentro desse espaço para nome.
O código abaixo deve ilustrar as diferenças.
namespace foo {const BAR =1;
define('BAZ',2);
define(__NAMESPACE__ .'\\BAZ',3);}namespace{
var_dump(get_defined_constants(true));}
O conteúdo da sub-matriz do usuário será ['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3].
=== ATUALIZAÇÃO ===
O próximo PHP 5.6 permitirá um pouco mais de flexibilidade com const. Agora você poderá definir consts em termos de expressões, desde que essas expressões sejam compostas de outros consts ou literais. Isso significa que o seguinte deve ser válido a partir da versão 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;
Você ainda não será capaz de definir consts em termos de variáveis ou retornos de funções, portanto,
Não pude resistir a perguntar: você definiu conscientemente FORTY_TWOcomo 54?
Punchlinern
9
"Seis por nove? Quarenta e dois? Eu sempre disse que havia algo fundamentalmente errado com o universo". Confira os trabalhos de Douglas Adams se precisar de uma explicação completa.
precisa saber é o seguinte
2
Oh. Eu estava ciente de que 42 é a resposta da vida, do universo e de tudo, mas eu tinha perdido o Seis em nove partes. Obrigada pelo esclarecimento!
Punchlinern
22
Acredito que, a partir do PHP 5.3, você possa usar constfora das classes, como mostrado aqui no segundo exemplo:
Como observado em outras respostas, const pode ser usado fora das classes no PHP 5.3+
MrWhite
Apenas a palavra-chave const pode ser usado para criar uma constante namespaced, não apenas as classes
Alireza Rahmani Khalili
16
A resposta do NikiC é a melhor, mas deixe-me acrescentar uma ressalva não óbvia ao usar espaços de nome para que você não seja pego com comportamento inesperado. É importante lembrar que define sempre está no espaço para nome global, a menos que você inclua explicitamente o espaço para nome como parte do identificador de definição. O que não é óbvio nisso é que o identificador no namespace supera o identificador global. Assim :
<?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);}?>
produz:
What kind of bar is a cheers bar?What kind of bar is a wonka bar?
willy wonka
three cheers
O que para mim torna desnecessariamente confusa toda a noção de const, já que a idéia de uma const em dezenas de outras linguagens é que ela é sempre a mesma onde quer que você esteja no seu código, e o PHP realmente não garante isso.
Sim, mas BARe \foo\BARsimplesmente não são as mesmas constantes. Concordo que é realmente confuso, mas se você também considerar coisas como a lógica de namespacing consistentes dessa maneira, e que constnem define()é nem como uma macro C ( #define), o PHP pode ter alguma desculpa.
Sz.
1
A noção de const é exatamente como deve se comportar - você está em um espaço para nome! Você o deseja sem o identificador do espaço para nome e, em seguida, crie-o fora do espaço para nome. Isso também o torna consistente com a const que está sendo definida em uma classe, mesmo que use sintaxe diferente. Sim, define também é consistente, de uma maneira diferente.
precisa
12
A maioria dessas respostas está errada ou conta apenas metade da história.
Você pode escopo suas constantes usando namespaces.
Você pode usar a palavra-chave "const" fora das definições de classe. No entanto, assim como nas classes, os valores atribuídos usando a palavra-chave "const" devem ser expressões constantes.
PHP> = 5.6 algumas alterações foram feitas no Zend Engine Compiler e o const está sendo tratado de outra maneira agora.
Ankit Vishwakarma
6
Sim, const são definidos em tempo de compilação e como estados nikic não podem ser atribuídos a uma expressão, como define () pode. Mas também const's não podem ser declarados condicionalmente (pelo mesmo motivo). ie Você não pode fazer isso:
if(/* some condition */){const WHIZZ =true;// CANNOT DO THIS!}
Considerando que você poderia com um define (). Portanto, não se resume a preferência pessoal, existe uma maneira correta e errada de usar as duas coisas.
Como um aparte ... Eu gostaria de ver algum tipo de classe const que pode ser atribuída a uma expressão, um tipo de define () que pode ser isolado para classes?
Com definir a palavra-chave constante, você obterá as facilidades de distinção entre maiúsculas e minúsculas, mas com a palavra-chave const, você não conseguiu.
const
é duas vezes mais rápido quedefine
. Sobre o tempo de carregamento da página e o uso de memória: consulte esta pergunta e este artigo ... Consulte também algo sobre o cache do opcode aqui .Respostas:
No PHP 5.3, existem duas maneiras de definir constantes : Usando a
const
palavra - chave ou adefine()
função:A diferença fundamental entre essas duas maneiras é que
const
define constantes em tempo de compilação, enquanto asdefine
define em tempo de execução. Isso causa a maioria dasconst
desvantagens. Algumas desvantagensconst
são:const
não pode ser usado para definir condicionalmente constantes. Para definir uma constante global, ela deve ser usada no escopo mais externo:Por que você faria isso de qualquer maneira? Uma aplicação comum é verificar se a constante já está definida:
const
aceita um escalar estática (número, string ou outra constante, comotrue
,false
,null
,__FILE__
), enquantodefine()
toma qualquer expressão. Desde PHP 5.6, expressões constantes também são permitidasconst
:const
recebe um nome constante e simples, enquantodefine()
aceita qualquer expressão como nome. Isso permite fazer coisas como esta:const
s sempre diferenciam maiúsculas de minúsculas, ao passo quedefine()
permitem definir constantes que não diferenciam maiúsculas de minúsculas, passandotrue
como terceiro argumento (Nota: definir constantes que não diferenciam maiúsculas de minúsculas é preterido no PHP 7.3.0.):Então, esse era o lado ruim das coisas. Agora, vamos ver o motivo pelo qual eu sempre uso pessoalmente, a
const
menos que ocorra uma das situações acima:const
simplesmente lê melhor. É uma construção de linguagem em vez de uma função e também é consistente com a forma como você define constantes nas classes.const
, sendo uma construção de linguagem, pode ser analisada estaticamente por ferramentas automatizadas.const
define uma constante no espaço para nome atual, enquantodefine()
deve ser passado o nome completo do espaço para nome:Como as
const
constantes do PHP 5.6 também podem ser matrizes, enquantodefine()
ainda não suporta matrizes. No entanto, matrizes serão suportadas para ambos os casos no PHP 7.Por fim, observe que
const
também pode ser usado em uma classe ou interface para definir uma constante de classe ou constante de interface.define
não pode ser utilizado para este fim:Sumário
A menos que você precise de qualquer tipo de definição condicional ou expressional, use
const
s em vez dedefine()
s - simplesmente para facilitar a leitura!fonte
const
construção da linguagem - ver wiki.php.net/rfc/const_scalar_exprsconst
é a falta de aspas, o que significa que é formatado da mesma forma que é usado no seu IDE.define('a', $_GET['param']);
,const b = a;
funciona perfeitamente e obtém o valor enquantoconst c = $_GET['param'];
é inválido. Éconst
realmente tempo de compilação? Eu dificilmente penso assim ... (testado no PHP 7.0.7)Até o PHP 5.3,
const
não podia ser usado no escopo global. Você só pode usar isso de dentro de uma classe. Isso deve ser usado quando você deseja definir algum tipo de opção constante ou configuração que pertence a essa classe. Ou talvez você queira criar algum tipo de enum.define
pode ser usado para a mesma finalidade, mas só pode ser usado no escopo global. Só deve ser usado para configurações globais que afetam o aplicativo inteiro.Um exemplo de bom
const
uso é se livrar dos números mágicos. Dê uma olhada nas constantes da DOP . Quando você precisar especificar um tipo de busca, digitePDO::FETCH_ASSOC
, por exemplo. Se consts não fossem usados, você acabaria digitando algo como35
(ou o queFETCH_ASSOC
for definido como). Isso não faz sentido para o leitor.Um exemplo de bom
define
uso é talvez especificar o caminho raiz do aplicativo ou o número da versão da biblioteca.fonte
const
com namespaces.Sei que isso já foi respondido, mas nenhuma das respostas atuais faz menção ao namespacing e como isso afeta constantes e define.
A partir do PHP 5.3, consts e define são semelhantes na maioria dos aspectos. Ainda existem, no entanto, algumas diferenças importantes:
const FOO = 4 * 3;
não funciona, masdefine('CONST', 4 * 3);
funciona.define
deve incluir o espaço para nome a ser definido dentro desse espaço para nome.O código abaixo deve ilustrar as diferenças.
O conteúdo da sub-matriz do usuário será
['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3]
.=== ATUALIZAÇÃO ===
O próximo PHP 5.6 permitirá um pouco mais de flexibilidade com
const
. Agora você poderá definir consts em termos de expressões, desde que essas expressões sejam compostas de outros consts ou literais. Isso significa que o seguinte deve ser válido a partir da versão 5.6:Você ainda não será capaz de definir consts em termos de variáveis ou retornos de funções, portanto,
ainda estará fora.
fonte
FORTY_TWO
como 54?Acredito que, a partir do PHP 5.3, você possa usar
const
fora das classes, como mostrado aqui no segundo exemplo:http://www.php.net/manual/en/language.constants.syntax.php
fonte
define
Eu uso para constantes globais.const
Eu uso para constantes de classe.Você não pode
define
entrar no escopo da classe e comconst
você pode. Escusado será dizer que você não pode usarconst
fora do escopo da classe.Além disso, com
const
, ele realmente se torna um membro da classe edefine
, com , será empurrado para o escopo global.fonte
A resposta do NikiC é a melhor, mas deixe-me acrescentar uma ressalva não óbvia ao usar espaços de nome para que você não seja pego com comportamento inesperado. É importante lembrar que define sempre está no espaço para nome global, a menos que você inclua explicitamente o espaço para nome como parte do identificador de definição. O que não é óbvio nisso é que o identificador no namespace supera o identificador global. Assim :
produz:
O que para mim torna desnecessariamente confusa toda a noção de const, já que a idéia de uma const em dezenas de outras linguagens é que ela é sempre a mesma onde quer que você esteja no seu código, e o PHP realmente não garante isso.
fonte
BAR
e\foo\BAR
simplesmente não são as mesmas constantes. Concordo que é realmente confuso, mas se você também considerar coisas como a lógica de namespacing consistentes dessa maneira, e queconst
nemdefine()
é nem como uma macro C (#define
), o PHP pode ter alguma desculpa.A maioria dessas respostas está errada ou conta apenas metade da história.
Por exemplo:
Mau exemplo:
Para criar constantes variáveis, use define () da seguinte forma:
fonte
Sim, const são definidos em tempo de compilação e como estados nikic não podem ser atribuídos a uma expressão, como define () pode. Mas também const's não podem ser declarados condicionalmente (pelo mesmo motivo). ie Você não pode fazer isso:
Considerando que você poderia com um define (). Portanto, não se resume a preferência pessoal, existe uma maneira correta e errada de usar as duas coisas.
Como um aparte ... Eu gostaria de ver algum tipo de classe const que pode ser atribuída a uma expressão, um tipo de define () que pode ser isolado para classes?
fonte
Para adicionar a resposta do NikiC.
const
pode ser usado nas classes da seguinte maneira:Você não pode fazer isso com
define()
.fonte
Ninguém diz nada sobre php-doc, mas para mim esse também é um argumento muito significativo para a preferência de
const
:fonte
Com definir a palavra-chave constante, você obterá as facilidades de distinção entre maiúsculas e minúsculas, mas com a palavra-chave const, você não conseguiu.
fonte