No PHP, quando você usa
define('FOO', 1);
e quando você usa
const FOO = 1;
?
Quais são as principais diferenças entre os dois?
No PHP, quando você usa
define('FOO', 1);
e quando você usa
const FOO = 1;
?
Quais são as principais diferenças entre os dois?
Respostas:
No PHP 5.3, existem duas maneiras de definir constantes : Usando a const
palavra - chave ou a define()
função:
const FOO = 'BAR';
define('FOO', 'BAR');
A diferença fundamental entre essas duas maneiras é que const
define constantes em tempo de compilação, enquanto as define
define em tempo de execução. Isso causa a maioria das const
desvantagens. Algumas desvantagens const
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:
if (...) {
const FOO = 'BAR'; // Invalid
}
// but
if (...) {
define('FOO', 'BAR'); // Valid
}
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');
}
const
aceita 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
const
recebe um nome constante e simples, enquanto define()
aceita qualquer expressão como nome. Isso permite fazer coisas como esta:
for ($i = 0; $i < 32; ++$i) {
define('BIT_' . $i, 1 << $i);
}
const
s sempre diferenciam maiúsculas de minúsculas, ao passo que define()
permitem definir constantes que não diferenciam maiúsculas de minúsculas, passando true
como 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 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, 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 const
constantes 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 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:
class Foo {
const BAR = 2; // Valid
}
// But
class Baz {
define('QUX', 2); // Invalid
}
Sumário
A menos que você precise de qualquer tipo de definição condicional ou expressional, use const
s em vez de define()
s - simplesmente para facilitar a leitura!
const
construção da linguagem - ver wiki.php.net/rfc/const_scalar_exprs
const
é 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 enquanto const 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, digite PDO::FETCH_ASSOC
, por exemplo. Se consts não fossem usados, você acabaria digitando algo como 35
(ou o que FETCH_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.
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, mas define('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.
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 details
const 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,
const RND = mt_rand();
const CONSTVAR = $var;
ainda estará fora.
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
<?php
// Works as of PHP 5.3.0
const CONSTANT = 'Hello World';
echo CONSTANT;
?>
define
Eu uso para constantes globais.
const
Eu uso para constantes de classe.
Você não pode define
entrar no escopo da classe e com const
você pode. Escusado será dizer que você não pode usar const
fora do escopo da classe.
Além disso, com const
, ele realmente se torna um membro da classe e define
, com , será empurrado para o escopo global.
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/expect
const 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.
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 que const
nem define()
é 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:
const AWESOME = 'Bob'; // Valid
Mau exemplo:
const AWESOME = whatIsMyName(); // Invalid (Function call)
const WEAKNESS = 4+5+6; // Invalid (Arithmetic)
const FOO = BAR . OF . SOAP; // Invalid (Concatenation)
Para criar constantes variáveis, use define () da seguinte forma:
define('AWESOME', whatIsMyName()); // Valid
define('WEAKNESS', 4 + 5 + 6); // Valid
define('FOO', BAR . OF . SOAP); // Valid
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?
Para adicionar a resposta do NikiC. const
pode ser usado nas classes da seguinte maneira:
class Foo {
const BAR = 1;
public function myMethod() {
return self::BAR;
}
}
Você não pode fazer isso com define()
.
Ninguém diz nada sobre php-doc, mas para mim esse também é um argumento muito significativo para a preferência de const
:
/**
* My foo-bar const
* @var string
*/
const FOO = 'BAR';
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.
define("FOO", 1, true);
echo foo; //1
echo "<br/>";
echo FOO; //1
echo "<br/>";
class A {
const FOO = 1;
}
echo A::FOO; //valid
echo "<br/>";
//but
class B {
define FOO = 1; //syntax error, unexpected 'define'
}
echo B::FOO; //invalid
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 .