php - variable - define() vs const
prestashop smarty shop id (10)
A partir de PHP 5.3 hay dos formas de definir constantes : usando la palabra clave const
o usando la función define()
:
const FOO = ''BAR'';
define(''FOO'', ''BAR'');
La diferencia fundamental entre estas dos formas es que las const
definen constantes en tiempo de compilación, mientras que las define en tiempo de ejecución. Esto causa la mayoría de las desventajas de const
. Algunas desventajas de const
son:
const
no puede usarse para definir condicionalmente constantes. Para definir una constante global, debe utilizarse 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 u otra constante comotrue
,false
,null
,__FILE__
), mientras quedefine()
toma cualquier expresión. Dado que PHP 5.6 también se permiten expresiones constantes enconst
:const BIT_5 = 1 << 5; // valid since PHP 5.6, invalid previously define(''BIT_5'', 1 << 5); // always valid
const
toma un nombre de constante simple, mientras quedefine()
acepta cualquier expresión como nombre. Esto permite hacer cosas como esta:for ($i = 0; $i < 32; ++$i) { define(''BIT_'' . $i, 1 << $i); }
const
siempre distinguen entre mayúsculas y minúsculas, mientras quedefine()
permite definir constantes que no distinguen entre mayúsculas y minúsculas al pasartrue
como tercer argumento:define(''FOO'', ''BAR'', true); echo FOO; // BAR echo foo; // BAR
Entonces, ese era el lado malo de las cosas. Ahora veamos la razón por la que personalmente uso siempre const
menos que ocurra una de las situaciones anteriores:
-
const
simplemente lee mejor. Es una construcción de lenguaje en lugar de una función y también es consistente con la forma en que se definen las 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 quedefine()
debe pasar 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 constantes de PHP 5.6 también pueden ser matrices, mientras que
define()
aún no admite matrices. 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, valid in PHP 7.0
Finalmente, tenga en cuenta que const
también se puede utilizar dentro de una clase o interfaz para definir una constante de clase o una constante de interfaz. define
no se puede utilizar para este propósito:
class Foo {
const BAR = 2; // valid
}
// but
class Baz {
define(''QUX'', 2); // invalid
}
Resumen
A menos que necesite cualquier tipo de definición condicional o expresiva, use const
s en lugar de define()
s, ¡simplemente para facilitar la lectura!
Pregunta bastante sencilla: en PHP, ¿cuándo usas?
define(''FOO'', 1);
y cuando usas
const FOO = 1;
¿Cuáles son las principales diferencias entre esos dos?
Creo que a partir de PHP 5.3, puedes usar const
fuera de las 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;
?>
Hasta PHP 5.3, const
no podía usarse en el ámbito global. Solo puedes usar esto desde dentro de una clase. Debe usarse cuando desee establecer algún tipo de opción constante o configuración que pertenezca a esa clase. O tal vez quieres crear algún tipo de enumeración.
define
se puede usar para el mismo propósito, pero solo se puede usar en el ámbito global. Solo debe usarse para configuraciones globales que afectan a toda la aplicación.
Un ejemplo de buen uso de const
es deshacerse de los números mágicos. Echa un vistazo a las constantes de la DOP . Cuando necesite especificar un tipo de recuperación, escriba PDO::FETCH_ASSOC
, por ejemplo. Si no se usaran consts, terminarías escribiendo algo como 35
(o FETCH_ASSOC
se define FETCH_ASSOC
). Esto no tiene sentido para el lector.
Un ejemplo de buen uso de define
es tal vez especificar la ruta raíz de su aplicación o el número de versión de una biblioteca.
La mayoría de estas respuestas están equivocadas o solo cuentan la mitad de la historia.
- Puedes medir tus constantes usando espacios de nombres.
- Puede utilizar la palabra clave "const" fuera de las definiciones de clase. Sin embargo, al igual que en las clases, los valores asignados con la palabra clave "const" deben ser expresiones constantes.
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 usa define () de esta manera:
define(''AWESOME'', whatIsMyName()); // Valid
define(''WEAKNESS'', 4 + 5 + 6); // Valid
define(''FOO'', BAR . OF . SOAP); // Valid
La respuesta de NikiC es la mejor, pero permítame agregar una advertencia no obvia al usar espacios de nombres para que no quede atrapado con un comportamiento inesperado. Lo que hay que recordar es que las definiciones están siempre 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 de esto es que el identificador de espacio de nombres supera al identificador global. Asi que :
<?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 de confusión sea innecesaria, ya que la idea de una constante en docenas de otros idiomas es que siempre es la misma donde sea que esté en su código, y PHP realmente no lo garantiza.
Nadie dice nada sobre php-doc, pero para mí eso también es un argumento muy importante para la preferencia de const
:
/**
* My foo-bar const
* @var string
*/
const FOO = ''BAR'';
Para agregar en la respuesta de NikiC. const
se puede utilizar 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()
.
Sé que esto ya está respondido, pero ninguna de las respuestas actuales hace mención alguna del espacio de nombres y cómo afecta a las constantes y las definiciones.
A partir de PHP 5.3, consts y define son similares en la mayoría de los aspectos. Todavía hay, sin embargo, algunas diferencias importantes:
- Consts no se puede definir a partir de una expresión.
const FOO = 4 * 3;
no funciona, perodefine(''CONST'', 4 * 3);
hace. - El nombre que se pasa para
define
debe incluir el espacio de nombres que se definirá dentro de ese espacio de nombres.
El siguiente código debe 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 compuestas 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 rendimientos de funciones, por lo que
const RND = mt_rand();
const CONSTVAR = $var;
todavía estará fuera
Sí, const se definen en tiempo de compilación y, como nikic, no se le puede asignar una expresión, como define () ''s puede. Pero también los const no pueden ser declarados condicionalmente (por la misma razón). es decir. No puedes hacer esto:
if (/* some condition */) {
const WHIZZ = true; // CANNOT DO THIS!
}
Mientras que puedes con un define (). Por lo tanto, realmente no se reduce a las preferencias personales, hay una forma correcta e incorrecta de usar ambas.
Dejando de lado ... me gustaría ver algún tipo de const de clase a la que se le pueda asignar una expresión, una especie de define () que pueda ser aislada a las clases.
define
uso para constantes globales.
const
utilizo para constantes de clase.
No se puede define
en el alcance de la clase, y con const
se puede. No hace falta decir que no puede utilizar const
fuera del alcance de la clase.
Además, con const
, en realidad se convierte en un miembro de la clase, con define
, será empujado al alcance global.