À partir de la isset()
documentation :
isset() will return FALSE if testing a variable that has been set to NULL.
Fondamentalement, isset()
ne vérifie pas si la variable est définie, mais si elle est définie sur autre chose NULL
.
Compte tenu de cela, quelle est la meilleure façon de vérifier réellement l'existence d'une variable? J'ai essayé quelque chose comme:
if(isset($v) || @is_null($v))
(le @
est nécessaire pour éviter l'avertissement quand $v
n'est pas défini) mais is_null()
a un problème similaire à isset()
: il retourne TRUE
sur des variables non définies ! Il apparaît également que:
@($v === NULL)
fonctionne exactement comme @is_null($v)
, donc c'est aussi.
Comment sommes-nous censés vérifier de manière fiable l'existence d'une variable en PHP?
Edit: il y a clairement une différence en PHP entre les variables qui ne sont pas définies et les variables qui sont définies sur NULL
:
<?php
$a = array('b' => NULL);
var_dump($a);
PHP montre que cela $a['b']
existe et a une NULL
valeur. Si vous ajoutez:
var_dump(isset($a['b']));
var_dump(isset($a['c']));
vous pouvez voir l'ambiguïté dont je parle avec la isset()
fonction. Voici le résultat de ces trois éléments var_dump()s
:
array(1) {
["b"]=>
NULL
}
bool(false)
bool(false)
Modifier davantage: deux choses.
Premièrement, un cas d'utilisation. Un tableau en cours de conversion en données d'une UPDATE
instruction SQL , où les clés du tableau sont les colonnes de la table et les valeurs du tableau sont les valeurs à appliquer à chaque colonne. Toutes les colonnes de la table peuvent contenir une NULL
valeur, signifiée en passant une NULL
valeur dans le tableau. Vous avez besoin d' un moyen de différencier entre une clé de tableau qui n'existe pas et la valeur d'un tableau définie sur NULL
; c'est la différence entre ne pas mettre à jour la valeur de la colonne et mettre à jour la valeur de la colonne surNULL
.
En second lieu , la réponse de Zoredache , array_key_exists()
fonctionne correctement, pour mon cas d' utilisation ci - dessus et pour toutes les variables globales:
<?php
$a = NULL;
var_dump(array_key_exists('a', $GLOBALS));
var_dump(array_key_exists('b', $GLOBALS));
les sorties:
bool(true)
bool(false)
Étant donné que cela gère correctement à peu près partout, je peux voir qu'il y a une ambiguïté entre des variables qui n'existent pas et des variables qui sont définies sur NULL
, j'appelle array_key_exists()
le moyen officiel le plus simple en PHP pour vraiment vérifier l'existence d'une variable .
(Le seul autre cas auquel je peux penser concerne les propriétés de classe, pour lesquelles il existe property_exists()
, qui, selon sa documentation , fonctionne de la même manière array_key_exists()
en ce sens qu'il distingue correctement entre ne pas être défini et être défini sur NULL
.)
register_globals
, j'ai encore du mal à penser à une situation où même cela nécessiterait une telle distinction, car tout ce qui est enregistré à partir de la requête HTTP serait toujours une chaîne, nonnull
.Réponses:
Si la variable que vous vérifiez est dans la portée globale, vous pouvez faire:
la source
$defined_vars = get_defined_vars();
puis tester viaarray_key_exists('v', $defined_vars);
.isset($foo[$bar])
devientarray_key_exists($bar, $foo)
property_exists
semble prometteur, sauf pour ceci:> La fonction property_exists () ne peut pas détecter les propriétés qui sont magiquement accessibles en utilisant la méthode magique __get.Tenter de donner un aperçu des différentes discussions et réponses:
Il n'y a pas de réponse unique à la question qui puisse remplacer tous les moyens qui
isset
peuvent être utilisés. Certains cas d'utilisation sont traités par d'autres fonctions, tandis que d'autres ne résistent pas à l'examen ou ont une valeur douteuse au-delà du code golf. Loin d 'être «cassés» ou «incohérents», d' autres cas d 'utilisation démontrent pourquoiisset
la réaction denull
est au comportement logique.Cas d'utilisation réels (avec solutions)
1. Touches de tableau
Les tableaux peuvent être traités comme des collections de variables, avec
unset
et en lesisset
traitant comme s'ils l'étaient. Cependant, puisqu'elles peuvent être itérées, comptées, etc., une valeur manquante n'est pas la même que celle dont la valeur estnull
.La réponse dans ce cas, est d' utiliser
array_key_exists()
au lieu deisset()
.Puisque ceci prend le tableau à vérifier en tant qu'argument de fonction, PHP lèvera toujours des "avis" si le tableau lui-même n'existe pas. Dans certains cas, on peut valablement faire valoir que chaque dimension aurait dû être initialisée en premier, de sorte que l'avis fait son travail. Pour les autres cas, une fonction "récursive"
array_key_exists
, qui vérifie tour à tour chaque dimension du tableau, éviterait cela, mais serait fondamentalement la même que@array_key_exists
. C'est aussi quelque peu tangentiel à la gestion desnull
valeurs.2. Propriétés de l'objet
Dans la théorie traditionnelle de la «programmation orientée objet», l'encapsulation et le polymorphisme sont des propriétés clés des objets; dans une mise en œuvre des propriétés de la POO base de classe comme PHP de, les encapsulées sont déclarées dans le cadre du niveau d'accès définition de la classe, et compte tenu de (
public
,protected
ouprivate
).Cependant, PHP vous permet également d'ajouter dynamiquement des propriétés à un objet, comme vous le feriez pour des clés d'un tableau, et certaines personnes utilisent des objets sans classe (techniquement, des instances du intégré
stdClass
, qui n'a pas de méthodes ou de fonctionnalités privées) dans un façon de tableaux associatifs. Cela conduit à des situations où une fonction peut vouloir savoir si une propriété particulière a été ajoutée à l'objet qui lui est donné.Comme avec les clés du tableau, une solution pour le contrôle des propriétés d'objet est inclus dans la langue, appelée, assez raisonnablement,
property_exists
.Cas d'utilisation non justifiables, avec discussion
3.
register_globals
et autres pollutions de l'espace de noms mondialLa
register_globals
fonctionnalité ajoutait des variables à la portée globale dont les noms étaient déterminés par des aspects de la requête HTTP (paramètres GET et POST et cookies). Cela peut conduire à un code bogué et non sécurisé, c'est pourquoi il a été désactivé par défaut depuis PHP 4.2, publié en août 2000 et complètement supprimé dans PHP 5.4, publié en mars 2012 . Cependant, il est possible que certains systèmes fonctionnent toujours avec cette fonctionnalité activée ou émulée. Il est également possible de «polluer» l'espace de noms global par d'autres moyens, en utilisant leglobal
mot - clé ou le$GLOBALS
tableau.Premièrement, il
register_globals
est peu probable qu'il produise de manière inattendue unenull
variable, car les valeurs GET, POST et cookie seront toujours des chaînes (avec''
toujours un retourtrue
deisset
), et les variables de la session devraient être entièrement sous le contrôle du programmeur.Deuxièmement, la pollution d'une variable avec la valeur
null
n'est un problème que si cela écrase une initialisation précédente. "Écraser" une variable non initialisée avecnull
ne serait problématique que si du code ailleurs faisait la distinction entre les deux états, donc à elle seule, cette possibilité est un argument contre une telle distinction.4.
get_defined_vars
etcompact
Quelques fonctions rarement utilisées en PHP, telles que
get_defined_vars
etcompact
, vous permettent de traiter les noms de variables comme s'il s'agissait de clés dans un tableau. Pour les variables globales, le tableau super-global$GLOBALS
permet un accès similaire, et est plus courant. Ces méthodes d'accès se comporteront différemment si une variable n'est pas définie dans la portée correspondante.Une fois que vous avez décidé de traiter un ensemble de variables comme un tableau en utilisant l'un de ces mécanismes, vous pouvez effectuer toutes les mêmes opérations sur celui-ci que sur n'importe quel tableau normal. Par conséquent, voir 1.
La fonctionnalité qui n'existait que pour prédire comment ces fonctions sont sur le point de se comporter (par exemple "y aura-t-il une clé 'foo' dans le tableau renvoyé par
get_defined_vars
?") Est superflue, car vous pouvez simplement exécuter la fonction et découvrir sans effets négatifs.4a. Variables variables (
$$foo
)Bien que ce ne soit pas tout à fait la même chose que les fonctions qui transforment un ensemble de variables en un tableau associatif, la plupart des cas utilisant des "variables variables" ("assigner à une variable nommée en fonction de cette autre variable") peuvent et doivent être modifiés pour utiliser un tableau associatif à la place .
Un nom de variable, fondamentalement, est l'étiquette donnée à une valeur par le programmeur; si vous le déterminez au moment de l'exécution, ce n'est pas vraiment une étiquette mais une clé dans un magasin clé-valeur. Plus concrètement, en n'utilisant pas de tableau, vous perdez la capacité de compter, d'itérer, etc. il peut également devenir impossible d'avoir une variable «en dehors» du magasin de valeurs-clés, car elle pourrait être écrasée par
$$foo
.Une fois changé pour utiliser un tableau associatif, le code sera prêt pour la solution 1. L'accès indirect aux propriétés des objets (par exemple
$foo->$property_name
) peut être adressé avec la solution 2.5.
isset
est tellement plus facile à taper quearray_key_exists
Je ne suis pas sûr que ce soit vraiment pertinent, mais oui, les noms de fonctions de PHP peuvent parfois être assez longs et incohérents. Apparemment, les versions préhistoriques de PHP utilisaient la longueur d'un nom de fonction comme clé de hachage, de sorte que Rasmus a délibérément composé des noms de fonction de
htmlspecialchars
manière à ce qu'ils aient un nombre inhabituel de caractères ...Pourtant, au moins, nous n'écrivons pas Java, hein? ;)
6. Les variables non initialisées ont un type
La page de manuel sur les principes de base des variables comprend cette déclaration:
Je ne sais pas s'il existe dans le Zend Engine une notion de "type non initialisé mais connu" ou si cela lit trop dans l'instruction.
Ce qui est clair, c'est que cela ne fait aucune différence pratique à leur comportement, puisque les comportements décrits sur cette page pour les variables non initialisées sont identiques au comportement d'une variable dont la valeur est
null
. Pour choisir un exemple, les deux$a
et$b
dans ce code finiront par être l'entier42
:(Le premier soulèvera une notification concernant une variable non déclarée, dans le but de vous faire écrire un meilleur code, mais cela ne fera aucune différence sur la façon dont le code s'exécute réellement.)
99. Détecter si une fonction a été exécutée
(Garder celui-ci en dernier, car il est beaucoup plus long que les autres. Peut-être que je le modifierai plus tard ...)
Considérez le code suivant:
Si
some_function
peut revenirnull
, il est possible que leecho
ne soit pas atteint même s'ilsome_test
est retournétrue
. L'intention du programmeur était de détecter quand il$result
n'avait jamais été défini, mais PHP ne leur permet pas de le faire.Cependant, il existe d'autres problèmes avec cette approche, qui deviennent évidents si vous ajoutez une boucle externe:
Comme il
$result
n'est jamais initialisé explicitement, il prendra une valeur lorsque le tout premier test réussit, ce qui rend impossible de dire si les tests suivants ont réussi ou non. C'est en fait un bogue extrêmement courant lorsque les variables ne sont pas initialisées correctement.Pour résoudre ce problème, nous devons faire quelque chose sur la ligne où j'ai commenté qu'il manque quelque chose. La solution la plus évidente est de définir
$result
une "valeur terminale" quisome_function
ne peut jamais revenir; si tel est le casnull
, le reste du code fonctionnera correctement. S'il n'y a pas de candidat naturel pour une valeur terminale parcesome_function
que son type de retour est extrêmement imprévisible (ce qui est probablement un mauvais signe en soi), alors une valeur booléenne supplémentaire, par exemple$found
, pourrait être utilisée à la place.Première expérience de pensée: la
very_null
constantePHP pourrait théoriquement fournir une constante spéciale - ainsi que
null
- à utiliser comme valeur terminale ici; vraisemblablement, il serait illégal de le renvoyer à partir d'une fonction, ou il y serait contraintnull
, et la même chose s'appliquerait probablement à sa transmission en tant qu'argument de fonction. Cela simplifierait légèrement ce cas très spécifique, mais dès que vous décidiez de re-factoriser le code - par exemple, de mettre la boucle interne dans une fonction séparée - cela deviendrait inutile. Si la constante pouvait être transmise entre les fonctions, vous ne pouviez pas garantir qu'ellesome_function
ne la renverrait pas, elle ne serait donc plus utile comme valeur de terminal universelle.L'argument pour détecter les variables non initialisées dans ce cas se résume à l'argument de cette constante spéciale: si vous remplacez le commentaire par
unset($result)
et que vous le traitez différemment$result = null
, vous introduisez une "valeur" car elle$result
ne peut pas être transmise, et ne peut être détecté par des fonctions intégrées spécifiques.Deuxième expérience de pensée: compteur d'affectation
Une autre façon de penser à ce que le dernier
if
demande est "quelque chose a-t-il été assigné$result
?" Plutôt que de le considérer comme une valeur spéciale de$result
, vous pourriez peut-être considérer cela comme des "métadonnées" sur la variable, un peu comme la "variable tainting" de Perl. Ainsi , plutôt queisset
vous pourriez l' appelerhas_been_assigned_to
, et plutôt queunset
,reset_assignment_state
.Mais si oui, pourquoi s'arrêter à un booléen? Que faire si vous voulez savoir combien de fois le test a réussi; vous pouvez simplement étendre vos métadonnées à un entier et avoir
get_assignment_count
etreset_assignment_count
...De toute évidence, l'ajout d'une telle fonctionnalité aurait un compromis entre la complexité et les performances du langage, il faudrait donc le peser soigneusement par rapport à son utilité attendue. Comme pour une
very_null
constante, elle ne serait utile que dans des circonstances très restreintes, et résiste de la même manière au réaffacturage.La question qui semble évidente est de savoir pourquoi le moteur d'exécution PHP devrait supposer à l'avance que vous voulez garder une trace de ces choses, plutôt que de vous laisser le faire explicitement, en utilisant du code normal.
la source
Parfois, je me perds un peu en essayant de déterminer quelle opération de comparaison utiliser dans une situation donnée.
isset()
s'applique uniquement aux valeurs non initialisées ou explicitement nulles. Passer / attribuer null est un excellent moyen de s'assurer qu'une comparaison logique fonctionne comme prévu.Pourtant, il est un peu difficile de penser alors voici une matrice simple comparant comment différentes valeurs seront évaluées par différentes opérations:
Pour s'adapter à la table, j'ai compressé un peu les étiquettes:
$a;
fait référence à une variable déclarée mais non attribuée$a = null;
$a = [];
$a = 0;
$a === null
isset($a)
empty($a)
$a ? true : false
Tous les résultats sont booléens,
true
imprimés etfalse
omis.Vous pouvez exécuter les tests vous-même, vérifiez ceci:
https://gist.github.com/mfdj/8165967
la source
"0"
au tableau, pour l'exhaustivité et la clarté de l'empty
opérationVous pouvez utiliser la construction de langage compact pour tester l'existence d'une variable nulle. Les variables qui n'existent pas ne s'afficheront pas dans le résultat, tandis que les valeurs nulles s'afficheront.
Dans le cas de votre exemple:
Bien sûr, pour les variables de portée globale, vous pouvez également utiliser array_key_exists ().
D'ailleurs, personnellement, j'éviterais des situations comme la peste où il y a une différence sémantique entre une variable inexistante et la variable ayant une valeur nulle. PHP et la plupart des autres langages ne le pensent tout simplement pas.
la source
NULL
. Sémantiquement, celaNULL
devrait signifier «aucune ressource», mais ne pas définir une variable est une erreur de programmeur.undefined
etnull
sont si rares que cela ne me manque pas. À mon humble avis, l'utilisation principaleundefined
est "erreur de programmeur dans un langage non strict". Dans un langage strict, si j'ai besoin d'un état distinct pourclient did not state a value
, alors je déclare une valeur appropriée à la situation et la teste. Dans le pire des cas, vous devez ajouter une variable d'indicateur distincte. Mais faire cela rarement est mieux que de devoir TOUJOURS faire face à DEUX états différents sans valeur !!Expliquer NULL, penser logiquement
Je suppose que la réponse évidente à tout cela est ... N'initialisez pas vos variables comme NULL, initialisez-les comme quelque chose de pertinent par rapport à ce qu'elles sont censées devenir.
Traitez NULL correctement
NULL doit être traité comme une "valeur inexistante", qui est la signification de NULL. La variable ne peut pas être classée comme existante en PHP car on ne lui a pas dit quel type d'entité elle essaie d'être. Il peut aussi ne pas exister, donc PHP dit simplement "Très bien, ce n'est pas parce que ça ne sert à rien de toute façon et NULL est ma façon de dire cela".
Une dispute
Discutons maintenant. "Mais NULL, c'est comme dire 0 ou FALSE ou ''.
Wrong, 0-FALSE- '' sont toujours classés comme des valeurs vides, mais ils SONT spécifiés comme un type de valeur ou une réponse prédéterminée à une question. FALSE est la réponse à oui ou non '', est la réponse au titre que quelqu'un a soumis, et 0 est la réponse à la quantité ou au temps, etc. Ils SONT définis comme un type de réponse / résultat qui les rend valides comme étant définis.
NULL est juste aucune réponse quoi que ce soit, il ne nous dit pas oui ou non et il ne nous dit pas l'heure et il ne nous dit pas qu'une chaîne vide a été soumise. C'est la logique de base pour comprendre NULL.
Résumé
Il ne s'agit pas de créer des fonctions farfelues pour contourner le problème, il s'agit simplement de changer la façon dont votre cerveau regarde NULL. Si c'est NULL, supposez que ce n'est rien. Si vous prédéfinissez des variables, prédéfinissez-les sur 0, FALSE ou "" selon le type d'utilisation que vous prévoyez pour elles.
N'hésitez pas à citer ceci. C'est hors de ma tête logique :)
la source
isset($a['x'])
vous dira false si ellex
est nulle, mais elle apparaîtra danscount($a)
..compact
fonctionnera sur toutes les variables d'ensemble, y comprisnulls
, et ainsi de suite.L'existence des propriétés de l'objet peut être vérifiée par property_exists
Exemple d'un test unitaire:
la source
En complément de la discussion de greatbigmassive sur ce que signifie NULL , considérez ce que signifie réellement «l'existence d'une variable».
Dans de nombreux langages, vous devez déclarer explicitement chaque variable avant de l'utiliser ; cela peut déterminer son type, mais plus important encore, il déclare sa portée . Une variable "existe" partout dans sa portée, et nulle part en dehors - que ce soit une fonction entière, ou un seul "bloc".
Dans son champ d'application, une variable attribue une signification à une étiquette que vous, le programmeur, avez choisie. En dehors de sa portée, cette étiquette n'a pas de sens (si vous utilisez la même étiquette dans une portée différente n'est fondamentalement pas pertinente).
En PHP, les variables n'ont pas besoin d'être déclarées - elles prennent vie dès que vous en avez besoin. Lorsque vous écrivez dans une variable pour la première fois, PHP alloue une entrée en mémoire pour cette variable. Si vous lisez une variable qui n'a pas actuellement d'entrée, PHP considère que cette variable a la valeur
NULL
.Cependant, les détecteurs automatiques de qualité de code vous avertiront généralement si vous utilisez une variable sans "l'initialiser" au préalable. Premièrement, cela aide à détecter les fautes de frappe, telles que l'attribution à
$thingId
mais la lecture à partir de$thing_id
; mais deuxièmement, cela vous oblige à considérer la portée sur laquelle cette variable a un sens, tout comme le ferait une déclaration.Tout code qui se soucie de savoir si une variable "existe" fait partie de la portée de cette variable - qu'elle ait été initialisée ou non, vous, en tant que programmeur, avez donné une signification à cette étiquette à ce point du code. Puisque vous l'utilisez, il doit dans un certain sens "exister", et s'il existe, il doit avoir une valeur implicite; en PHP, cette valeur implicite est
null
.En raison du fonctionnement de PHP, il est possible d'écrire du code qui traite l'espace de noms des variables existantes non pas comme une portée d'étiquettes auxquelles vous avez donné un sens, mais comme une sorte de magasin clé-valeur. Vous pouvez, par exemple, exécuter du code comme ceci:
$var = $_GET['var_name']; $$var = $_GET['var_value'];
. Ce n'est pas parce que vous le pouvez que c'est une bonne idée.Il s'avère que PHP a une bien meilleure façon de représenter les magasins clé-valeur, appelés tableaux associatifs. Et bien que les valeurs d'un tableau puissent être traitées comme des variables, vous pouvez également effectuer des opérations sur le tableau dans son ensemble. Si vous avez un tableau associatif, vous pouvez tester s'il contient une clé à l'aide de
array_key_exists()
.Vous pouvez également utiliser des objets de la même manière, en définissant dynamiquement les propriétés, auquel cas vous pouvez les utiliser
property_exists()
exactement de la même manière. Bien sûr, si vous définissez une classe, vous pouvez déclarer les propriétés qu'il a - vous pouvez même choisir entrepublic
,private
etprotected
la portée.Bien qu'il existe une différence technique entre une variable (par opposition à une clé de tableau ou à une propriété d'objet) qui n'a pas été initialisée (ou qui a été explicitement
unset()
) et celle dont la valeur estnull
, tout code qui considère cette différence comme significative utilise des variables d'une manière qu'elles ne sont pas censées être utilisées.la source
isset()
se comporte-t-il ainsi?".null
. La question de savoir si cette valeur existe avant que vous la regardiez est une question pour les philosophes, mais en ce qui concerne tout comportement observable, la valeur est cohérentenull
.isset
vérifie si la variable est définie et, le cas échéant, si sa valeur n'est pas NULL. Cette dernière partie n'entre (à mon avis) pas dans le cadre de cette fonction. Il n'existe pas de solution de contournement décente pour déterminer si une variable est NULL car elle n'est pas définie ou parce qu'elle est explicitement définie sur NULL .Voici une solution possible:
Une autre solution de contournement consiste à sonder la sortie de
get_defined_vars()
:la source
Je ne suis pas d'accord avec votre raisonnement sur NULL , et dire que vous devez changer votre état d'esprit à propos de NULL est juste bizarre.
Je pense que isset () n'a pas été conçu correctement, isset () devrait vous dire si la variable a été définie et il ne devrait pas être concerné par la valeur réelle de la variable.
Que faire si vous vérifiez les valeurs renvoyées par une base de données et que l'une des colonnes a une valeur NULL, vous voulez toujours savoir si elle existe même si la valeur est NULL ... non, ne faites pas confiance à isset () ici.
également
isset () aurait dû être conçu pour fonctionner comme ceci:
de cette façon, nous laissons au programmeur le soin de vérifier les types et de ne pas laisser à isset () le soin de supposer que ce n'est pas là parce que la valeur est NULL - c'est juste une conception stupide
la source
array_key_exists
. Vous ne devriez jamais être dans une situation où vous ne savez pas au moment de l'exécution si une variable réelle existe.register_globals
, alors votre réponse n'est pas un changement deisset()
. Le manuel PHP mentionne "c'est généralement une bonne pratique de programmation d'initialiser d'abord les variables", ce qui résoutregister_globals
au moment de la conception plutôt qu'à l'exécution. Il y a aussi une entrée de FAQ donnant uneunregister_globals()
fonction pour le traiter au moment de l'exécution.Je vais ajouter un petit deux cents à cela. L'une des raisons pour lesquelles ce problème est déroutant est que ce scénario semble renvoyer le même résultat avec un rapport d'erreur non complet:
Vous pouvez supposer à partir de ce résultat que la différence entre
$a = null
et ne pas définir$b
du tout n'est rien.Rapport d'erreur de démarrage:
Remarque: il a renvoyé une erreur de variable non définie, mais la valeur de sortie de
var_dump
est toujoursNULL
.PHP a évidemment une capacité interne à faire la distinction entre une variable nulle et une variable non définie. Il me semble qu'il devrait y avoir une fonction intégrée pour vérifier cela.
Je pense que la réponse acceptée est bonne pour la plupart, mais si j'allais l'implémenter, j'écrirais un wrapper pour cela. Comme mentionné précédemment dans cette réponse , je dois admettre que je n'ai pas réellement rencontré de situation où cela a posé un problème. Il me semble que je me retrouve presque toujours dans un scénario où mes variables sont soit définies et définies, soit elles ne le sont pas (indéfinies, non définies, nulles, vides, etc.). Cela ne veut pas dire qu'une situation comme celle-ci ne se produira pas à l'avenir, mais comme cela semble être un problème assez unique, je ne suis pas surpris que les développeurs PHP n'aient pas pris la peine de mettre cela en place.
la source
Si j'exécute ce qui suit:
J'obtiens une erreur:
Si j'exécute ce qui suit:
Je ne reçois pas l'erreur.
Si j'ai une variable à définir, je fais généralement quelque chose comme ce qui suit.
ou
De cette façon, plus loin dans le script, je peux utiliser en toute sécurité $ foo et savoir qu'il "est défini", et qu'il est par défaut à null. Plus tard, je peux
if ( is_null($foo) ) { /* ... */ }
si j'ai besoin et savoir avec certitude que la variable existe, même si elle est nulle.La documentation complète de l' iset lit un peu plus que ce qui a été initialement collé. Oui, il renvoie false pour une variable précédemment définie mais qui est maintenant nulle, mais il renvoie également false si une variable n'a pas encore été définie (jamais) et pour toute variable qui a été marquée comme non définie. Il note également que l'octet NULL ("\ 0") n'est pas considéré comme nul et retournera vrai.
la source
Essayez d'utiliser
Il semble que la seule fois où une variable n'est pas définie, c'est lorsqu'elle est spécifiquement désactivée ($ v). Il semble que votre signification d '«existence» soit différente de la définition de PHP. NULL existe certainement, il est NULL.
la source
Je dois dire qu'au cours de toutes mes années de programmation PHP, je n'ai jamais rencontré de problème pour
isset()
renvoyer false sur une variable nulle. OTOH, j'ai rencontré des problèmes d'isset()
échec sur une entrée de tableau nul - maisarray_key_exists()
fonctionne correctement dans ce cas.Pour certaines comparaisons, Icon définit explicitement une variable inutilisée comme retournant
&null
afin que vous utilisiez le test is-null dans Icon pour également rechercher une variable non définie. Cela facilite les choses. D'autre part, Visual BASIC a plusieurs états pour une variable qui n'a pas de valeur (Null, Empty, Nothing, ...), et vous devez souvent en rechercher plusieurs. Ceci est connu pour être une source de bogues.la source
Selon le manuel PHP pour la fonction empty (), "Détermine si une variable est considérée comme vide. Une variable est considérée comme vide SI ELLE N'EXISTE PAS ou si sa valeur est égale à FALSE. Empty () ne génère pas d'avertissement si le variable n'existe pas. " (Je souligne.) Cela signifie que la fonction empty () devrait être qualifiée de "meilleure façon de tester l'existence d'une variable en PHP", selon le titre Question.
Cependant, ce n'est pas suffisant, car la fonction empty () peut être trompée par une variable qui existe et qui est définie sur NULL.
J'interromps ma réponse précédente pour présenter quelque chose de mieux, car elle est moins encombrante que ma réponse originale (qui fait suite à cette interruption, pour comparer).
Deux simples lignes de code peuvent utiliser la fonction ci-dessus pour révéler si une variable n'est pas définie:
Vous pouvez suivre ces deux lignes avec tout ce qui est approprié, comme cet exemple:
Je voulais mettre l'appel à ob_start () et le ($ testvar === null) à l'intérieur de la fonction, et passer simplement la variable à la fonction, mais cela ne fonctionne pas. Même si vous essayez d'utiliser "passer par référence" de la variable à la fonction, la variable DEVIENT définie et la fonction ne peut jamais détecter qu'elle était précédemment indéfinie. Ce qui est présenté ici est un compromis entre ce que je voulais faire et ce qui fonctionne réellement.
Ce qui précède implique qu'il existe un autre moyen d'éviter de toujours rencontrer le message d'erreur "Variable non définie". (L'hypothèse ici est que la prévention d'un tel message est la raison pour laquelle vous voulez tester pour voir si une variable n'est pas définie.)
Appelez simplement cette fonction avant de faire quelque chose sur votre $ testvar:
La valeur de la variable nouvellement instanciée est définie sur null, bien sûr!
(L'interruption prend fin)
Donc, après quelques études et expérimentations, voici quelque chose qui fonctionnera:
L'explication: Une variable $ er est initialisée à une valeur par défaut de "pas d'erreur". Une "fonction gestionnaire" est définie. Si $ testvar (la variable que nous voulons savoir si elle n'est pas définie ou non) réussit le test préliminaire de la fonction empty (), alors nous faisons le test plus approfondi. Nous appelons la fonction set_error_handler () pour utiliser la fonction de gestionnaire précédemment définie. Ensuite, nous faisons une simple comparaison d'identité impliquant $ testvar, QUI SI NON DÉFINI DÉCLENCHERA UNE ERREUR. La fonction de gestionnaire capture l'erreur et teste spécifiquement pour voir si la raison de l'erreur est le fait que la variable n'est pas définie. Le résultat est placé dans la variable d'information d'erreur $ er, que nous pouvons tester ultérieurement pour faire tout ce que nous voulons en sachant avec certitude si $ testvar a été défini ou non. Étant donné que nous n'avons besoin de la fonction de gestionnaire que dans ce but limité, nous restaurons la fonction de gestion des erreurs d'origine. La fonction "myHndlr" n'a besoin d'être déclarée qu'une seule fois; l'autre code peut être copié à n'importe quel endroit approprié, pour $ testvar ou toute autre variable que nous voulons tester de cette façon.
la source
inst
fonction est fondamentalement comme l'@
opérateur de suppression d'erreurs: "Je sais que je fais quelque chose de mal ici, mais je veux juste que ce message disparaisse, sans changer en fait le fonctionnement de mon code de quelque manière que ce soit".Je pense que la seule solution complète est de signaler les notifications avec
Mais vous devrez corriger tous les avis générés par des variables non définies, des constantes, des clés de tableau, des propriétés de classe, entre autres. Une fois que vous avez fait cela, vous n'aurez plus à vous soucier de la différence entre les variables nulles et non déclarées, et l'ambiguïté disparaît.
L'activation de la notification des notifications peut ne pas être une bonne alternative dans toutes les situations, mais il existe de bonnes raisons de l'activer:
Pourquoi devrais-je corriger les erreurs E_NOTICE?
Dans mon cas, c'était plus d'un an à travailler dans un projet sans cela, mais on avait l'habitude de faire attention à la déclaration des variables, donc la transition était rapide.
la source
Le seul moyen de savoir si une variable est définie dans la portée actuelle (
$GLOBALS
n'est pas digne de confiance) estarray_key_exists( 'var_name', get_defined_vars() )
.la source
Je préfère utiliser pas vide comme meilleure méthode pour vérifier l'existence d'une variable qui a) existe et que b) n'est pas nul.
la source
empty()
ne vérifie pas si la variable est nulle, il vérifie si elle est fausse-y, par exemple pas l' un des""
(une chaîne vide),0
(0 comme un nombre entier),0.0
(0 en tant que flotteur),"0"
(0 sous forme de chaîne)NULL
,FALSE
,array()
(un tableau vide) et$var;
(une variable déclarée, mais sans valeur). Supposons que vous ayez un champ radio obligatoire dans un formulaire avec deux entrées avec les valeurs0
et1
. Si vous utilisezempty()
pour la validation et que l'utilisateur sélectionne celui-0
ci, vous feriez par inadvertance une erreur "le champ obligatoire ne peut pas être vide". Voir le manuel php.net/manual/en/function.empty.php