En PHP, quand utilisez-vous
define('FOO', 1);
et quand utilisez-vous
const FOO = 1;
?
Quelles sont les principales différences entre ces deux?
En PHP, quand utilisez-vous
define('FOO', 1);
et quand utilisez-vous
const FOO = 1;
?
Quelles sont les principales différences entre ces deux?
Réponses:
Depuis PHP 5.3, il existe deux façons de définir des constantes : soit en utilisant le const
mot - clé, soit en utilisant la define()
fonction:
const FOO = 'BAR';
define('FOO', 'BAR');
La différence fondamentale entre ces deux façons est de const
définir les constantes au moment de la compilation, tandis que de les define
définir au moment de l'exécution. Cela entraîne la plupart des const
inconvénients de. Certains inconvénients const
sont:
const
ne peut pas être utilisé pour définir conditionnellement des constantes. Pour définir une constante globale, elle doit être utilisée dans la portée la plus externe:
if (...) {
const FOO = 'BAR'; // Invalid
}
// but
if (...) {
define('FOO', 'BAR'); // Valid
}
Pourquoi voudriez-vous faire cela de toute façon? Une application courante consiste à vérifier si la constante est déjà définie:
if (!defined('FOO')) {
define('FOO', 'BAR');
}
const
accepte un scalaire (nombre, une chaîne ou une autre constante comme statique true
, false
, null
, __FILE__
), alors que define()
prend toute expression. Étant donné que les expressions constantes PHP 5.6 sont également autorisées dans const
:
const BIT_5 = 1 << 5; // Valid since PHP 5.6 and invalid previously
define('BIT_5', 1 << 5); // Always valid
const
prend un nom simple et constant, alors qu'il define()
accepte toute expression comme nom. Cela permet de faire des choses comme ça:
for ($i = 0; $i < 32; ++$i) {
define('BIT_' . $i, 1 << $i);
}
const
s sont toujours sensibles à la casse, tandis que define()
vous permet de définir des constantes insensibles à la casse en passant true
comme troisième argument (Remarque: la définition des constantes insensibles à la casse est déconseillée à partir de PHP 7.3.0.):
define('FOO', 'BAR', true);
echo FOO; // BAR
echo foo; // BAR
C'était donc le mauvais côté des choses. Voyons maintenant la raison pour laquelle j'utilise toujours personnellement, const
sauf si l'une des situations ci-dessus se produit:
const
lit simplement mieux. C'est une construction de langage au lieu d'une fonction et est également cohérente avec la façon dont vous définissez les constantes dans les classes.const
, étant une construction de langage, peut être analysé statiquement par un outillage automatisé.const
définit une constante dans l'espace de noms courant, tandis que define()
le nom complet de l'espace de noms doit être passé:
namespace A\B\C;
// To define the constant A\B\C\FOO:
const FOO = 'BAR';
define('A\B\C\FOO', 'BAR');
Étant donné que les const
constantes PHP 5.6 peuvent également être des tableaux, tandis que define()
ne prend pas encore en charge les tableaux. Cependant, les tableaux seront pris en charge dans les deux cas 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
Enfin, notez que const
peut également être utilisé dans une classe ou une interface pour définir une constante de classe ou une constante d' interface. define
ne peut pas être utilisé à cette fin:
class Foo {
const BAR = 2; // Valid
}
// But
class Baz {
define('QUX', 2); // Invalid
}
Sommaire
Sauf si vous avez besoin de tout type de définition conditionnelle ou expressionnelle, utilisez const
s au lieu de define()
s - simplement par souci de lisibilité!
const
construction du langage - voir wiki.php.net/rfc/const_scalar_exprs
const
est le manque de guillemets, ce qui signifie qu'il est formaté de la même manière qu'il est utilisé dans votre IDE.
define('a', $_GET['param']);
, const b = a;
fonctionne parfaitement et obtient la valeur alors qu'elle const c = $_GET['param'];
n'est pas valide. Est-ce const
vraiment du temps de compilation? Je le pense à peine ... (testé sur PHP 7.0.7)
Jusqu'à PHP 5.3, const
ne pouvait pas être utilisé dans la portée globale. Vous ne pouvez l'utiliser que depuis une classe. Cela doit être utilisé lorsque vous souhaitez définir une sorte d'option constante ou un paramètre qui se rapporte à cette classe. Ou peut-être voulez-vous créer une sorte d'énumération.
define
peut être utilisé dans le même but, mais il ne peut être utilisé que dans la portée globale. Il ne doit être utilisé que pour les paramètres globaux qui affectent l'ensemble de l'application.
Un exemple de bon const
usage est de se débarrasser des nombres magiques. Jetez un œil aux constantes de PDO . Lorsque vous devez spécifier un type d'extraction, vous devez taper PDO::FETCH_ASSOC
, par exemple. Si consts n'était pas utilisé, vous finiriez par taper quelque chose comme 35
(ou quoi que ce FETCH_ASSOC
soit défini comme). Cela n'a aucun sens pour le lecteur.
Un exemple de bonne define
utilisation peut être de spécifier le chemin racine de votre application ou le numéro de version d'une bibliothèque.
const
with namespaces.
Je sais que cela a déjà été répondu, mais aucune des réponses actuelles ne mentionne l'espace de noms et comment il affecte les constantes et définit.
Depuis PHP 5.3, consts et define sont similaires à la plupart des égards. Il existe cependant encore quelques différences importantes:
const FOO = 4 * 3;
ne fonctionne pas, mais define('CONST', 4 * 3);
fonctionne. define
doit inclure l'espace de noms à définir dans cet espace de noms.Le code ci-dessous doit illustrer les différences.
namespace foo
{
const BAR = 1;
define('BAZ', 2);
define(__NAMESPACE__ . '\\BAZ', 3);
}
namespace {
var_dump(get_defined_constants(true));
}
Le contenu du sous-tableau utilisateur sera ['foo\\BAR' => 1, 'BAZ' => 2, 'foo\\BAZ' => 3]
.
=== MISE À JOUR ===
Le prochain PHP 5.6 permettra un peu plus de flexibilité avec const
. Vous pourrez désormais définir des consts en termes d'expressions, à condition que ces expressions soient constituées d'autres consts ou de littéraux. Cela signifie que les éléments suivants doivent être valides à 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;
Cependant, vous ne pourrez toujours pas définir de consts en termes de variables ou de retours de fonctions, donc
const RND = mt_rand();
const CONSTVAR = $var;
sera toujours sorti.
FORTY_TWO
comme 54?
Je crois qu'à partir de PHP 5.3, vous pouvez utiliser en const
dehors des classes, comme indiqué ici dans le deuxième exemple:
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
J'utilise pour les constantes globales.
const
J'utilise pour les constantes de classe.
Vous ne pouvez pas define
entrer dans la portée de la classe et avec const
vous le pouvez. Inutile de dire que vous ne pouvez pas utiliser la const
portée de classe en dehors.
De plus, avec const
, il devient en fait un membre de la classe, et avec define
, il sera poussé à la portée globale.
La réponse de NikiC est la meilleure, mais permettez-moi d'ajouter une mise en garde non évidente lors de l'utilisation des espaces de noms afin de ne pas vous faire surprendre par un comportement inattendu. La chose à retenir est que les définitions sont toujours dans l'espace de noms global, sauf si vous ajoutez explicitement l'espace de noms comme partie de l'identificateur de définition. Ce qui n'est pas évident à ce sujet, c'est que l'identifiant de l'espace de nom l'emporte sur l'identifiant global. Donc :
<?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);
}
?>
produit:
What kind of bar is a cheers bar?
What kind of bar is a wonka bar?
willy wonka
three cheers
Ce qui pour moi rend la notion de const confondante inutilement car l'idée d'un const dans des dizaines d'autres langages est qu'il est toujours le même où que vous soyez dans votre code, et PHP ne le garantit pas vraiment.
BAR
et ce ne \foo\BAR
sont tout simplement pas les mêmes constantes. Je suis d' accord qu'il est vraiment déroutant, mais si l' on considère aussi des choses comme la logique de l' espace de nommage étant cohérente de cette façon, et que ni const
ne define()
ressemble à un C macro ( #define
), alors PHP peut avoir une excuse.
La plupart de ces réponses sont fausses ou ne racontent que la moitié de l'histoire.
Par exemple:
const AWESOME = 'Bob'; // Valid
Mauvais exemple:
const AWESOME = whatIsMyName(); // Invalid (Function call)
const WEAKNESS = 4+5+6; // Invalid (Arithmetic)
const FOO = BAR . OF . SOAP; // Invalid (Concatenation)
Pour créer des constantes variables, utilisez define () comme ceci:
define('AWESOME', whatIsMyName()); // Valid
define('WEAKNESS', 4 + 5 + 6); // Valid
define('FOO', BAR . OF . SOAP); // Valid
Oui, les const sont définis au moment de la compilation et comme les états nikic ne peuvent pas être assignés à une expression, comme le peuvent les define (). Mais les const ne peuvent pas non plus être déclarés conditionnellement (pour la même raison). c'est à dire. Tu ne peux pas faire ça:
if (/* some condition */) {
const WHIZZ = true; // CANNOT DO THIS!
}
Alors que vous pourriez avec un define (). Donc, cela ne se résume pas vraiment à une préférence personnelle, il y a une bonne et une mauvaise façon d'utiliser les deux.
En passant ... Je voudrais voir une sorte de classe const à laquelle on peut assigner une expression, une sorte de define () qui peut être isolé aux classes?
Pour ajouter sur la réponse de NikiC. const
peut être utilisé dans les classes de la manière suivante:
class Foo {
const BAR = 1;
public function myMethod() {
return self::BAR;
}
}
Vous ne pouvez pas faire cela avec define()
.
Personne ne dit rien sur php-doc, mais pour moi, c'est aussi un argument très important pour la préférence de const
:
/**
* My foo-bar const
* @var string
*/
const FOO = 'BAR';
Avec define keyword constant, vous obtiendrez les fonctionnalités de la casse insensible, mais avec const keyword vous ne l'avez pas fait.
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
est deux fois plus rapide quedefine
. À propos du temps de chargement des pages et de l'utilisation de la mémoire: voir cette question et cet article ... Voir aussi quelque chose sur le cache opcode ici .