En PHP, ¿cuándo usas
define('FOO', 1);
y cuando usas
const FOO = 1;
?
¿Cuáles son las principales diferencias entre esos dos?
En PHP, ¿cuándo usas
define('FOO', 1);
y cuando usas
const FOO = 1;
?
¿Cuáles son las principales diferencias entre esos dos?
Respuestas:
A partir de PHP 5.3, hay dos formas de definir constantes : utilizando la const
palabra clave o utilizando la define()
función:
const FOO = 'BAR';
define('FOO', 'BAR');
La diferencia fundamental entre esas dos formas es que const
define constantes en tiempo de compilación, mientras que las define
define en tiempo de ejecución. Esto causa la mayoría de const
las desventajas. Algunas desventajas de const
son:
const
no se puede usar para definir condicionalmente constantes. Para definir una constante global, debe usarse en el ámbito más externo:
if (...) {
const FOO = 'BAR'; // Invalid
}
// but
if (...) {
define('FOO', 'BAR'); // Valid
}
¿Por qué querrías hacer eso de todos modos? Una aplicación común es verificar si la constante ya está definida:
if (!defined('FOO')) {
define('FOO', 'BAR');
}
const
acepta un escalar estático (número, cadena o cualquier otra constante como true
, false
, null
, __FILE__
), mientras que define()
toma cualquier expresión. Como PHP 5.6 también se permiten expresiones constantes const
:
const BIT_5 = 1 << 5; // Valid since PHP 5.6 and invalid previously
define('BIT_5', 1 << 5); // Always valid
const
toma un nombre constante simple, mientras que define()
acepta cualquier expresión como nombre. Esto permite hacer cosas como esta:
for ($i = 0; $i < 32; ++$i) {
define('BIT_' . $i, 1 << $i);
}
const
s siempre distingue entre mayúsculas y minúsculas, mientras define()
que le permite definir constantes que no distinguen entre mayúsculas y minúsculas pasando true
como tercer argumento (Nota: la definición de constantes que distinguen mayúsculas de minúsculas es obsoleta a partir de PHP 7.3.0):
define('FOO', 'BAR', true);
echo FOO; // BAR
echo foo; // BAR
Entonces, ese era el lado malo de las cosas. Ahora echemos un vistazo a la razón por la que personalmente siempre uso a const
menos que ocurra una de las situaciones anteriores:
const
simplemente se lee mejor. Es una construcción de lenguaje en lugar de una función y también es coherente con la forma en que define constantes en las clases.const
, al ser una construcción de lenguaje, puede analizarse estáticamente mediante herramientas automatizadas.const
define una constante en el espacio de nombres actual, mientras define()
que debe pasarse el nombre completo del espacio de nombres:
namespace A\B\C;
// To define the constant A\B\C\FOO:
const FOO = 'BAR';
define('A\B\C\FOO', 'BAR');
Dado que las const
constantes de PHP 5.6 también pueden ser matrices, define()
aún no son compatibles. Sin embargo, las matrices serán compatibles para ambos casos en 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
Finalmente, tenga en cuenta que const
también se puede usar dentro de una clase o interfaz para definir una constante de clase o constante de interfaz. define
no se puede usar para este propósito:
class Foo {
const BAR = 2; // Valid
}
// But
class Baz {
define('QUX', 2); // Invalid
}
Resumen
A menos que necesite algún tipo de definición condicional o expresiva, use const
s en lugar de define()
s, ¡simplemente por razones de legibilidad!
const
construcción del lenguaje - vea wiki.php.net/rfc/const_scalar_exprs
const
es la falta de comillas, lo que significa que está formateado de la misma manera que se usa en su IDE.
define('a', $_GET['param']);
, const b = a;
funciona perfectamente y obtiene el valor mientras const c = $_GET['param'];
no es válido. ¿ const
Realmente es tiempo de compilación? Apenas lo creo ... (probado en PHP 7.0.7)
Hasta PHP 5.3, const
no se podía utilizar en el ámbito global. Solo puedes usar esto desde una clase. Esto debe usarse cuando desee establecer algún tipo de opción constante o configuración que pertenezca a esa clase. O tal vez quieras crear algún tipo de enumeración.
define
puede usarse para el mismo propósito, pero solo puede usarse en el ámbito global. Solo debe usarse para configuraciones globales que afectan a toda la aplicación.
Un ejemplo de buen const
uso es deshacerse de los números mágicos. Echa un vistazo a las constantes de PDO . Cuando necesite especificar un tipo de búsqueda, escriba PDO::FETCH_ASSOC
, por ejemplo. Si no se usaran const, terminaría escribiendo algo como 35
(o lo que FETCH_ASSOC
se define como). Esto no tiene sentido para el lector.
Un ejemplo de buen define
uso es quizás especificar la ruta raíz de su aplicación o el número de versión de una biblioteca.
const
con espacios de nombres.
Sé que esto ya está respondido, pero ninguna de las respuestas actuales menciona el espacio de nombres y cómo afecta a las constantes y las definiciones.
A partir de PHP 5.3, los consts y define son similares en la mayoría de los aspectos. Sin embargo, todavía hay algunas diferencias importantes:
const FOO = 4 * 3;
no funciona, pero lo define('CONST', 4 * 3);
hace. define
debe incluir el espacio de nombres que se definirá dentro de ese espacio de nombres.El siguiente código debería ilustrar las diferencias.
namespace foo
{
const BAR = 1;
define('BAZ', 2);
define(__NAMESPACE__ . '\\BAZ', 3);
}
namespace {
var_dump(get_defined_constants(true));
}
El contenido de la sub-matriz de usuario será ['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3]
.
=== ACTUALIZACIÓN ===
El próximo PHP 5.6 permitirá un poco más de flexibilidad con const
. Ahora podrá definir consts en términos de expresiones, siempre que esas expresiones estén formadas por otros consts o literales. Esto significa que lo siguiente debería ser válido a partir de 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;
Sin embargo, aún no podrá definir consts en términos de variables o retornos de funciones, por lo que
const RND = mt_rand();
const CONSTVAR = $var;
Todavía estará fuera.
FORTY_TWO
como 54?
Creo que a partir de PHP 5.3, puede usar const
fuera de clases, como se muestra aquí en el segundo ejemplo:
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
Yo uso para constantes globales.
const
Yo uso para constantes de clase.
No puede define
entrar en el alcance de la clase, y con const
usted puede. No hace falta decir que no se puede usar const
fuera del alcance de la clase.
Además, con const
, en realidad se convierte en un miembro de la clase, y con define
, será llevado a un alcance global.
La respuesta de NikiC es la mejor, pero permítame agregar una advertencia no obvia cuando use espacios de nombres para que no se vea atrapado con un comportamiento inesperado. Lo que debe recordar es que las definiciones siempre están en el espacio de nombres global a menos que agregue explícitamente el espacio de nombres como parte del identificador de definición. Lo que no es obvio al respecto es que el identificador de espacio de nombres prevalece sobre el identificador global. Entonces :
<?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);
}
?>
produce:
What kind of bar is a cheers bar?
What kind of bar is a wonka bar?
willy wonka
three cheers
Lo que para mí hace que toda la noción constante sea innecesariamente confusa, ya que la idea de una constante en docenas de otros idiomas es que siempre es lo mismo donde sea que esté en su código, y PHP realmente no garantiza eso.
BAR
y \foo\BAR
son sólo no las mismas constantes. Estoy de acuerdo en que es realmente confuso, pero si también considera que cosas como la lógica del espacio de nombres son consistentes de esta manera, y que ni const
tampoco define()
es como una macro C ( #define
), entonces PHP puede tener alguna excusa.
La mayoría de estas respuestas son incorrectas o solo cuentan la mitad de la historia.
Por ejemplo:
const AWESOME = 'Bob'; // Valid
Mal ejemplo:
const AWESOME = whatIsMyName(); // Invalid (Function call)
const WEAKNESS = 4+5+6; // Invalid (Arithmetic)
const FOO = BAR . OF . SOAP; // Invalid (Concatenation)
Para crear constantes variables use define () así:
define('AWESOME', whatIsMyName()); // Valid
define('WEAKNESS', 4 + 5 + 6); // Valid
define('FOO', BAR . OF . SOAP); // Valid
Sí, los const se definen en tiempo de compilación y como a los estados nikic no se les puede asignar una expresión, como se puede definir (). Pero también los const no se pueden declarar condicionalmente (por la misma razón). es decir. No puedes hacer esto:
if (/* some condition */) {
const WHIZZ = true; // CANNOT DO THIS!
}
Mientras que podría con un define (). Por lo tanto, en realidad no se trata de preferencias personales, hay una forma correcta y una incorrecta de usar ambos.
Como comentario aparte, me gustaría ver algún tipo de constante de clase a la que se le pueda asignar una expresión, una especie de define () que se pueda aislar a las clases.
Para agregar a la respuesta de NikiC. const
se puede usar dentro de las clases de la siguiente manera:
class Foo {
const BAR = 1;
public function myMethod() {
return self::BAR;
}
}
No puedes hacer esto con define()
.
Nadie dice nada sobre php-doc, pero para mí eso también es un argumento muy significativo para la preferencia de const
:
/**
* My foo-bar const
* @var string
*/
const FOO = 'BAR';
Con la definición de la palabra clave constante, obtendrá las facilidades de mayúsculas y minúsculas, pero con la palabra clave constante no.
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
es dos veces más rápido quedefine
. Acerca del tiempo de carga de la página y el uso de la memoria: vea esta pregunta y este artículo ... Vea también algo sobre el código de memoria caché aquí .