PHP | definir() frente a constante

Resuelto danjarvis asked hace 54 años • 9 respuestas

En PHP, puedes declarar constantes de dos maneras:

  1. Con definepalabra clave

    define('FOO', 1);
    
  2. Usando constpalabra clave

    const FOO = 1;
    

  • ¿Cuáles son las principales diferencias entre esos dos?
  • ¿Cuándo y por qué debería utilizar uno y cuándo utilizar el otro?
danjarvis avatar Jan 01 '70 08:01 danjarvis
Aceptado

A partir de PHP 5.3, hay dos formas de definir constantes : ya sea usando la constpalabra clave o usando la define()función:

const FOO = 'BAR';
define('FOO', 'BAR');

La diferencia fundamental entre esas dos formas es que constdefine constantes en tiempo de compilación, mientras que definelas define en tiempo de ejecución. Esto causa la mayoría de constlas desventajas. Algunas desventajas de constson:

  • constno se puede utilizar para definir constantes condicionalmente. 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 comprobar si la constante ya está definida:

     if (!defined('FOO')) {
         define('FOO', 'BAR');
     }
    
  • constacepta un escalar estático (número, cadena u otra constante como ,,, true) , mientras que falseacepta cualquier expresión. Desde PHP 5.6 también se permiten expresiones constantes :null__FILE__define()const

     const BIT_5 = 1 << 5;    // Valid since PHP 5.6 and invalid previously
     define('BIT_5', 1 << 5); // Always valid
    
  • consttoma 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);
     }
    
  • consts siempre distinguen entre mayúsculas y minúsculas, mientras que define()le permiten definir constantes que no distinguen entre mayúsculas y minúsculas pasándolas truecomo tercer argumento (Nota: la definición de constantes que no distinguen entre mayúsculas y minúsculas está obsoleta a partir de PHP 7.3.0 y se elimina desde PHP 8.0.0):

     define('FOO', 'BAR', true);
     echo FOO; // BAR
     echo foo; // BAR
    

Entonces ese fue el lado malo de las cosas. Ahora veamos la razón por la que personalmente siempre uso consta menos que ocurra una de las situaciones anteriores:

  • constsimplemente se lee mejor. Es una construcción del 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 del lenguaje, se puede analizar estáticamente mediante herramientas automatizadas.

  • constdefine una constante en el espacio de nombres actual, mientras que define()se 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 PHP 5.6 constlas constantes también pueden ser matrices, aunque define()todavía no admite matrices. Sin embargo, las matrices serán compatibles en 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 consttambién se puede utilizar dentro de una clase o interfaz para definir una constante de clase o constante de interfaz. defineno 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 algún tipo de definición condicional o expresiva, utilice consts en lugar de define()s, ¡simplemente por razones de legibilidad!

NikiC avatar Jul 07 '2010 09:07 NikiC

Hasta PHP 5.3, constno se podía utilizar en el ámbito global. Sólo puedes usar esto desde dentro de una clase. Esto debe usarse cuando desee establecer algún tipo de opción o configuración constante que pertenezca a esa clase. O tal vez quieras crear algún tipo de enumeración.

definese puede utilizar para el mismo propósito, pero solo se puede utilizar en el ámbito global. Sólo debe usarse para configuraciones globales que afecten a toda la aplicación.

Un ejemplo de buen constuso es deshacerse de los números mágicos. Eche un vistazo a las constantes de PDO . Cuando necesite especificar un tipo de recuperación, deberá escribir PDO::FETCH_ASSOC, por ejemplo. Si no se usaran constantes, terminaría escribiendo algo como 35(o lo que sea que FETCH_ASSOCse defina). Esto no tiene sentido para el lector.

Un ejemplo de buen defineuso es tal vez especificar la ruta raíz de su aplicación o el número de versión de una biblioteca.

ryeguy avatar Mar 15 '2010 14:03 ryeguy

Sé que esto ya está respondido, pero ninguna de las respuestas actuales menciona el espacio de nombres y cómo afecta las constantes y las definiciones.

A partir de PHP 5.3, las constantes y definiciones son similares en la mayoría de los aspectos. Sin embargo, todavía existen algunas diferencias importantes:

  • Las constantes no se pueden definir a partir de una expresión. const FOO = 4 * 3;no funciona, pero define('CONST', 4 * 3);lo hace.
  • El nombre pasado definedebe 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 submatriz 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 constantes en términos de expresiones, siempre que esas expresiones estén formadas por otras constantes 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ás definir constantes en términos de variables o retornos de funciones, por lo que

const RND = mt_rand();
const CONSTVAR = $var;

todavía estará fuera.

GordonM avatar Sep 26 '2011 12:09 GordonM

defineLo uso para constantes globales.

constLo uso para constantes de clase.

No puedes defineentrar en el ámbito de la clase, y contigo constpuedes.

Además, con const, en realidad se convierte en miembro de la clase y con define, será llevado al ámbito global.

Jacob Relkin avatar Mar 15 '2010 14:03 Jacob Relkin