On va — dans un premier temps — effectuer des rappels à propos de la déclaration des variables dans PHP, puis — dans un second temps — observer les différences entre isset, empty et is_null.
Variables : praeludo
Déclaration de variables
La déclaration des variables en PHP est très simple. Pas de type à définir, pas de notation à rallonge, juste son nom et une valeur par défaut :
$foo = 'bar';
Si on ne précise pas de valeur par défaut, PHP ne va pas déclarer la variable. Il n'y aura pas d'erreur, mais elle n'existera pas. Donc si on souhaite l'utiliser par la suite, on risque d'avoir des erreurs. Démonstration : $foo;
var_dump($foo);
// PHP va nous dire :
// Notice: Undefined variable: foo in /some/where/- on line 42
Déclaration de variables « non-initialisées »Si on souhaite avoir une variable avec aucune valeur, on l'initialisera à NULL.
NULL est une constante de PHP qui désigne « rien ». En réalité, NULL signifie qu'il n'y a aucun lien entre la variable et l'espace mémoire, donc qu'aucune valeur n'est attribuée. On dit donc qu'on attribut une valeur nulle.
Ainsi, si on souhaite déclarer une variable avec aucune valeur, on fera de cette façon :
$foo = null;
Détruire une variableOn a trois façons de détruire une variable en PHP.
La plus évidente est de mettre sa valeur à NULL. On s'assure de la « remise à zéro » de la variable.
Si on fait ceci :
$foo = 'bar';
$foo = null;
La chaîne bar va disparaître. En réalité, on attendra que le garbage collector passe par là pour supprimer la chaîne de caractères car elle n'est plus référencée, comprendre qu'elle n'est plus « liée » à une variable (on ne regarde pas des symboles vers la mémoire mais de la mémoire vers les symboles). Donc si la chaîne n'est plus référencée, le garbage collector va la supprimer.Note sur le garbage collector : comme PHP gère tout seul la mémoire, il utilise entre autre un garbage collector, ou ramasse-miette. C'est un système qui scanne la mémoire et repère les valeurs qui ne sont plus utilisées.
Note sur les références (pour ceux qui savent ce que c'est) : passer une variable à NULL est le seul moyen de déréférencer — i.e. de casser la référence — une valeur.
Une autre façon de faire est d'utiliser la fonction unset (on verra par la suite que ce n'est pas une fonction mais une structure du langage). Ainsi :
$foo = 'bar';
unset($foo);
La valeur est bien détruite, et elle le sera immédiatement.Dernière façon de procéder : le transtypage.
Vous connaissez sans doute le transtypage, ou le cast. Ça ressemble à ceci :
$foo = 4.2;
$foo = (int) $foo;
var_dump($foo);
// Affichera :
// int(4)
C'est le fait de passer d'un type à l'autre.PHP ne comporte pas de type unset mais a pourtant un cast unset. Ainsi :
$foo = 'bar';
$foo = (unset) $foo;
var_dump($foo);
// Affichera :
// NULL
Structures du langage versus fonctions natives : prestissimoPHP propose des fonctions, comme substr, preg_replace, trigger_error etc. Mais — a contrario de ce que beaucoup pense — isset et empty n'en sont pas. Ce sont des structures du langage.
À l'instar de echo, print, unset, include, require, ainsi que les structures de contrôle telles que if, elseif, declare, while etc., isset et empty sont des structures du langage. Elles sont repérées par l'analyseur syntaxique de PHP et ont un traitement de faveur. Ce sont des comportements de bas-niveaux qui ont des équivalents bytecodes connus et systématiques.
Ainsi, il est évident que c'est bien plus rapide à traiter qu'une fonction de PHP, même si elle est native (et a fortiori écrite en C). Il faut les voir comme des mot-clés du langage.
C'est pour cette raison qu'on ne peut utiliser que des variables dans isset par exemple :
isset($foo); // est correct.
isset('foo'); // est incorrect.
PHP ira jusqu'à nous dire qu'il y a une erreur de syntaxe … et oui ! On a dit que c'était l'analyseur syntaxique qui reconnaissait les structures du langage.C'est aussi pour cette raison qu'on peut écrire require (et structures analogues) avec ou sans parenthèse :
require('file.php'); // correct.
require 'file.php'; // correct.
Il n'y a aucune différence.Chaque structure a ses spécificités (include, include_once, require et require_once peuvent avoir ou pas des parenthèses, mais if, while, isset etc. doivent obligatoirement en avoir).
En ce qui nous concerne, nous avons isset et empty qui sont des structures du langage et is_null qui est une fonction.
isset, empty et is_null : allegro
isset
La structure du langage isset permet de savoir si une variable est définie ou pas. Les plus bilingues d'entre nous auront compris que ça vient de is set en anglais, soit est défini en français. Autrement dit, on demande à PHP si la variable est définie ou pas. Encore autrement dit, on lui demande si le symbole est défini dans une des tables de variables. Ainsi :
$foo = null;
$bar = 'dummy';
var_dump(
isset($foo),
isset($bar)
);
// Affichera :
// bool(false)
// bool(true)
Toute valeur différente de NULL est considérée comme valable, donc comme étant définie.Aparté sur les tableaux
Si une variable est initialisée à NULL ou qu'une variable n'existe pas, PHP ne fera pas la différence. Ça peut être gênant dans le cas de tableau. En effet :
$array = array(
'foo' => null,
'bar' => 'dummy'
);
var_dump(
isset($array['foo']),
isset($array['answerToLife'])
);
// Affichera :
// bool(false)
// bool(false)
Comment faire la différence entre une clé qui existe mais dont la valeur vaut NULL et une clé qui n'existe pas ? C'est quelque chose que l'on veut faire très souvent et qui est à l'origine de bugs difficilement corrigeables. Heureusement, PHP a la solution avec la fonction array_key_exists : var_dump(
array_key_exists('foo', $array),
array_key_exists('answerToLife', $array)
);
// Affichera :
// bool(true)
// bool(false)
empty
À l'instar de isset, empty ne comprend que des variables. Ainsi :
empty($foo); // est correct.
empty('foo'); // est incorrect.
empty sert à savoir si une variable contient une donnée nulle, donc égale à la constante NULL dans un premier temps. Voyons plutôt : $foo = null;
var_dump(
empty($foo),
isset($foo)
);
// Affichera :
// bool(true)
// bool(false)
En réalité, empty considère comme vide une chaîne vide (''), zéro (0), zéro en chaîne de caractères ('0'), nul (NULL), faux (FALSE), un tableau vide (array()) et un attribut d'objet sans valeur par défaut (public $foo; par exemple) : class Foo {
public $bar; // est strictement équivalent à : public $bar = null;.
}
$foo = new Foo();
$a = '';
$b = 0;
$c = '0';
$d = null;
$e = false;
$f = array();
$g = $foo->bar;
var_dump(
empty($a),
empty($b),
empty($c),
empty($d),
empty($e),
empty($f),
empty($g)
);
// Affichera :
// bool(true)
// bool(true)
// bool(true)
// bool(true)
// bool(true)
// bool(true)
// bool(true)
empty et les tableaux (cas pratique)empty a dans ses caractéristiques qu'elle est capable de savoir si un tableau est vide. Ainsi :
$ar = array();
$ray = array('foo' => 'bar');
var_dump(
empty($ar),
empty($ray)
);
// Affichera :
// bool(true)
// bool(false)
C'est très pratique.is_null
Enfin, la fonction is_null qui vérifie si une valeur est strictement égale à la constante NULL. Elle est moins généraliste que empty et moins stricte que isset. De plus, elle est une fonction et pas une structure du langage, donc on peut mettre ce qu'on veut en paramètre. Ainsi :
var_dump(
is_null(null),
is_null(0)
);
// Affichera :
// bool(true)
// bool(false)
En revanche, a contrario de isset, is_null ne doit pas servir à tester l'existence d'une variable ! Car : var_dump(is_null($baz));
// PHP va nous dire :
// Notice: Undefined variable: baz in /some/where/- on line 42
// bool(true)
PHP va nous dire que $baz vaut NULL mais va émettre une erreur … C'est un peu tordu, mais logique au final.Compléments/annexes
Je vous conseille de lire la documentation :
- http://php.net/isset ;
- http://php.net/unset ;
- http://php.net/empty ;
- http://php.net/is_null ;
- http://php.net/types.comparisons
Wala . J'espère que c'est plus clair maintenant !