¿Comprobar si var existe antes de desactivar en PHP?

6 minutos de lectura

avatar de usuario
jason davis

Con el informe de errores, o incluso como mejor práctica, al desarmar una variable en PHP, ¿debería verificar primero si existe (en este caso, no siempre existe) y luego desarmarla, o simplemente desarmarla?

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

// OR

unset($_SESSION['signup_errors']);
?>

  • Cf. dk2.php.net/unset#77310

    – jensgram

    3 de septiembre de 2009 a las 17:13

  • Es más eficiente para NOT usar isset. Echa un vistazo a mi respuesta. He hecho pruebas para encontrar la diferencia de velocidad.

    – Dan Bray

    6 de marzo de 2016 a las 1:37

avatar de usuario
joão silva

Simplemente desactívelo, si no existe, no se hará nada.

  • No sabía si arrojaría una advertencia o un aviso.

    – Jason Davis

    3 de septiembre de 2009 a las 17:12

  • @SilentGhost Estoy de acuerdo, parece una prueba tan simple, pero están pidiendo asesoramiento profesional, y aunque el registro de errores puede no tener ningún error/advertencia/aviso al desactivar una variable indefinida, podría haber otros problemas que no están registrados. por ejemplo, simplemente llamar a unset significa que PHP analiza TODOS los datos var porque no puede encontrar nada, mientras que usar if set podría tener un mejor esquema de indexación. (Solo un ejemplo, el anterior probablemente sea zapatero y ambos enfoques usan el mismo método de verificación de datos).

    – Jaime

    1 de marzo de 2015 a las 2:59

  • vote hacia abajo: no puede anular las claves de matriz que no están definidas.

    – Behnam

    13 de julio de 2018 a las 16:47


  • Eso no está bien, @Behnam. No puede anular las claves de matriz de “matrices indefinidas”. Echa un vistazo a la respuesta de TarranJones

    – ya-cha

    12 de noviembre de 2018 a las 16:03

  • @jascha Dije, ¡no podemos!

    – Behnam

    25 de enero de 2019 a las 11:51

Del manual de PHP:

Con respecto a cierta confusión anterior en estas notas sobre lo que hace que unset() active avisos cuando se deshacen variables que no existen…

Desarmar variables que no existen, como en

<?php
unset($undefinedVariable);
?>

no activa un aviso de “Variable indefinida”. Pero

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

activa dos avisos, porque este código es para desarmar un elemento de una matriz; ni $undefinedArray ni $undefinedKey se están desarmando, simplemente se usan para ubicar lo que se debe desarmar. Después de todo, si existieran, aún esperaría que ambos existieran después. ¡NO querrías que toda tu matriz desapareciera solo porque desarmaste() uno de sus elementos!

  • Esto necesita un poco más de aclaración. Puede desactivar las claves de matriz que no están definidas siempre que exista la propia matriz.

    – arce rey

    24 de agosto de 2012 a las 10:49

  • @kristovaher De hecho, esto no aborda el escenario específico que describe el OP en absoluto.

    –Mark Amery

    2 abr 2014 a las 12:16

avatar de usuario
dan bray

Usando unset en una variable indefinida no causará ningún error (a menos que la variable sea el índice de una matriz (u objeto) que no existe).

Por lo tanto, lo único que debe considerar es qué es lo más eficiente. Es más eficiente no probar con ‘isset’, como mostrará mi prueba.

Prueba:

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();

Resultados:

  1. Function A time = 1.0307259559631
    • Definido sin isset
  2. Function B time = 0.72514510154724
    • Indefinido sin isset
  3. Function C time = 1.3804969787598
    • Definido usando isset
  4. Function D time = 0.86475610733032
    • indefinido usando isset

Conclusión:

Siempre es menos eficiente usar isset, sin mencionar la pequeña cantidad de tiempo extra que lleva escribir. Es más rápido intentar unset una variable indefinida que comprobar si puede ser unset.

  • ¡Esto es mucho mejor que la respuesta aceptada! Gracias por hacer estas pruebas.

    –Adam Friedman

    19 de junio de 2020 a las 15:57

  • No estás probando igual por igual. La asignación de memoria es más cara que la asignación de memoria, por lo que A y C tardan más. Es mejor pensar en lo que tiene que pasar debajo del capó. php no puede desactivar algo sin saber si está configurado, por lo que debe llamar a isset internamente. Entonces, llamar a unset por sí mismo siempre será más rápido.

    – Ruido

    23/09/2021 a las 20:15


avatar de usuario
TarranJones

Si desea desarmar una variable, puede usar unset

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

Verificar su existencia no tiene ningún beneficio cuando se trata de desarmar una variable.

Si la variable es una matriz y desea desarmar un elemento, debe asegurarse de que la padre existe primero, esto también se aplica a las propiedades del objeto.

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

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

Esto se soluciona fácilmente envolviendo el unset en un if(isset($var)){ ... } bloquear.

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

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

La razón por la que solo verificamos la variable (padre) es simplemente porque no necesitamos verificar la propiedad/elemento y hacerlo sería mucho más lento de escribir y calcular, ya que agregaría una verificación adicional.

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

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

.vs

$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)){
...
}

Esto no hace falta decirlo, pero también es crucial que conozcas el type de la variable al obtener, activar y desactivar un elemento o propiedad; usar la sintaxis incorrecta generará un error.

Es lo mismo cuando se intenta anular el valor de una matriz u objeto multidimensional. Debe asegurarse de que exista la clave/nombre principal.

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

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

Cuando se trata de objetos, hay otra cosa en la que pensar, y es la visibilidad.

El hecho de que exista no significa que tenga permiso para modificarlo.

Consulta este enlace
https://3v4l.org/hPAto

La herramienta en línea muestra compatibilidad de código para diferentes versiones de PHP

Según esta herramienta el código

unset($_SESSION['signup_errors']);

funcionaría para PHP> = 5.4.0 sin darte ningún aviso/advertencia/error.

¿Ha sido útil esta solución?