Vérifier si var existe avant de se désinstaller en PHP?

88

Avec le rapport d'erreur sur, ou même pour les meilleures pratiques, lors de la désactivation d'une variable en PHP, devriez-vous vérifier si elle existe en premier (dans ce cas, elle n'existe pas toujours) et la désactiver, ou simplement la désactiver?

<?PHP
if (isset($_SESSION['signup_errors'])){
    unset($_SESSION['signup_errors']);
}

// OR

unset($_SESSION['signup_errors']);
?>
JasonDavis
la source
2
Cf. dk2.php.net/unset#77310
jensgram
1
Il est plus efficace à NOTutiliser isset. Jetez un œil à ma réponse. J'ai fait des tests pour trouver la différence de vitesse.
Dan Bray

Réponses:

167

Désactivez-le, s'il n'existe pas, rien ne sera fait.

João Silva
la source
3
Je ne savais pas si cela jetterait un avertissement ou un avis
JasonDavis
19
@SilentGhost Je suis d'accord, cela semble un test si simple, mais ils demandent des conseils professionnels, et bien que le journal des erreurs puisse ne pas contenir d'erreur / d'avertissement / de notification annulant une variable non définie, il pourrait y avoir eu d'autres problèmes qui ne sont pas enregistrés. Par exemple, le simple fait d'appeler unset signifie que PHP parcourt TOUTES les données var parce qu'il ne trouve rien, alors que l'utilisation if setpourrait avoir un meilleur schéma d'indexation. (Juste un exemple, le précédent est probablement des cordonniers et les deux approches utilisent la même méthode de vérification des données).
James
C'est vrai, et c'est aussi plus efficace. Jetez un œil à ma réponse car j'ai testé la vitesse d'utilisation des issetversets sans utilisation isset.
Dan Bray
voter contre - vous ne pouvez pas annuler la définition des clés de tableau qui ne sont pas définies.
Behnam
1
@jascha j'ai dit, nous ne pouvons pas!
Behnam
48

À partir du manuel PHP :

En ce qui concerne une certaine confusion plus tôt dans ces notes sur les raisons pour lesquelles unset () déclenche des notifications lors de la désactivation de variables qui n'existent pas ...

Désactiver des variables qui n'existent pas, comme dans

<?php
unset($undefinedVariable);
?>

ne déclenche pas une notification "Variable non définie". Mais

<?php
unset($undefinedArray[$undefinedKey]);
?>

déclenche deux avis, car ce code sert à désarmer un élément d'un tableau; ni $ undefinedArray ni $ undefinedKey ne sont eux-mêmes non définis, ils sont simplement utilisés pour localiser ce qui doit l'être. Après tout, s'ils existaient, vous vous attendriez toujours à ce qu'ils soient tous les deux là après. Vous ne voudriez PAS que votre tableau entier disparaisse simplement parce que vous désactivez () l'un de ses éléments!

M. Smith
la source
41
Cela nécessite un peu plus de clarification. Vous pouvez annuler la définition des clés de tableau qui ne sont pas définies tant que le tableau lui-même existe.
kingmaple
@kristovaher En effet - cela ne répond pas du tout au scénario spécifique décrit par l'OP.
Mark Amery
21

L'utilisation unsetsur une variable non définie ne provoquera aucune erreur (sauf si la variable est l'index d'un tableau (ou d'un objet) qui n'existe pas).

Par conséquent, la seule chose que vous devez considérer, c'est ce qui est le plus efficace. Il est plus efficace de ne pas tester avec 'isset', comme mon test le montrera.

Tester:

function A()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        unset($defined);
    }
}

function B()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        unset($undefined);
    }
}

function C()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        if (isset($defined))
            unset($defined);
    }
}

function D()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        if (isset($undefined))
            unset($undefined);
    }
}

$time_pre = microtime(true);
A();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function A time = $exec_time ";

$time_pre = microtime(true);
B();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function B time = $exec_time ";

$time_pre = microtime(true);
C();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function C time = $exec_time ";

$time_pre = microtime(true);
D();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function D time = $exec_time";
exit();

Résultats:

  1. Function A time = 1.0307259559631
    • Défini sans isset
  2. Function B time = 0.72514510154724
    • Indéfini sans isset
  3. Function C time = 1.3804969787598
    • Défini à l'aide de isset
  4. Function D time = 0.86475610733032
    • Indéfini avec isset

Conclusion:

Il est toujours moins efficace à utiliser isset, sans parler du peu de temps supplémentaire qu'il faut pour écrire. Il est plus rapide d'essayer unsetune variable non définie que de vérifier si elle peut l'être unset.

Dan Bray
la source
1
C'est bien mieux que la réponse acceptée! Merci d'avoir exécuté ces tests.
Adam Friedman le
3

Si vous souhaitez désactiver une variable, vous pouvez simplement utiliser unset

unset($any_variable); // bool, object, int, string etc

La vérification de son existence n'a aucun avantage lorsque vous essayez de désactiver une variable.

Si la variable est un tableau et que vous souhaitez annuler la définition d'un élément, vous devez d'abord vous assurer que le parent existe, cela vaut également pour les propriétés d'objet.

unset($undefined_array['undefined_element_key']); // error - Undefined variable: undefined_array

unset($undefined_object->undefined_prop_name); // error - Undefined variable: undefined_object

Ceci est facilement résolu en enveloppant le unsetdans un if(isset($var)){ ... }bloc.

if(isset($undefined_array)){
    unset($undefined_array['undefined_element_key']); 
}

if(isset($undefined_object)){
    unset($undefined_object->undefined_prop_name); 
}

La raison pour laquelle nous ne vérifions que la variable ( parent ) est simplement parce que nous n'avons pas besoin de vérifier la propriété / l'élément et que cela serait beaucoup plus lent à écrire et à calculer car cela ajouterait une vérification supplémentaire.

if(isset($array)){
...
}

if(isset($object)){
...
}

.contre

$object->prop_name = null;
$array['element_key'] = null;

// This way elements/properties with the value of `null` can still be unset.

if(isset($array) && array_key_exists('element_key', $array)){
...
}

if(isset($object) && property_exists($object, 'prop_name')){
...
}

// or 

// This way elements/properties with `null` values wont be unset.

if(isset($array) && $array['element_key'])){
...
}

if(isset($object) && $object->prop_name)){
...
}

Cela va sans dire, mais il est également crucial que vous connaissiez typela variable lors de l'obtention, de la définition et de la désactivation d'un élément ou d'une propriété; l'utilisation d'une syntaxe incorrecte provoquera une erreur.

C'est la même chose lorsque vous essayez d'annuler la valeur d'un tableau ou d'un objet multidimensionnel. Vous devez vous assurer que la clé / le nom parent existe.

if(isset($variable['undefined_key'])){
    unset($variable['undefined_key']['another_undefined_key']);
}

if(isset($variable->undefined_prop)){
    unset($variable->undefined_prop->another_undefined_prop);
}

Lorsqu'il s'agit d'objets, il y a autre chose à penser, c'est la visibilité.

Ce n'est pas parce qu'il existe que vous avez la permission de le modifier.

TarranJones
la source
Enfin, une bonne réponse. Merci.
wp78de
Une petite mise à jour: En PHP 7.4 / 8.0, aucune erreur n'est générée lorsque vous avez unsetla propriété d'un objet parent non existant. Cependant, désinstaller une clé dans un tableau non existant en PHP8 soulève non seulement un avis mais un avertissement (sujet à changement).
wp78de
1

Vérifiez ce lien https://3v4l.org/hPAto

L'outil en ligne montre la compatibilité du code pour différentes versions de PHP

Selon cet outil, le code

unset($_SESSION['signup_errors']);

fonctionnerait pour PHP> = 5.4.0 sans vous donner aucun avis / avertissement / erreur.

evgpisarchik
la source