Verificare se var esiste prima di disinserire in PHP?


88

Con la segnalazione degli errori attivata, o anche per la migliore pratica, quando si disattiva una variabile in PHP, è necessario verificare prima se esiste (in questo caso non sempre esiste) e disattivarla o semplicemente disattivarla?

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

// OR

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


1
È più efficiente da NOTusare isset. Dai un'occhiata alla mia risposta. Ho fatto dei test per trovare la differenza di velocità.
Dan Bray

Risposte:


167

Disinseriscilo, se non esiste, non verrà fatto nulla.


3
Non sapevo se avrebbe lanciato un avviso o un avviso
JasonDavis

19
@SilentGhost Sono d'accordo, sembra un test così semplice, ma stanno chiedendo un consiglio professionale, e sebbene il log degli errori potrebbe non avere alcun errore / avviso / avviso di disinserimento di una var non definita, potrebbero esserci stati altri problemi che non sono stati registrati. ad esempio, solo chiamare unset significa che PHP rastrella TUTTI i dati var perché non riesce a trovare nulla, mentre l'uso if setpotrebbe avere uno schema di indicizzazione migliore. (Solo un esempio, il precedente è probabilmente cobblers ed entrambi gli approcci utilizzano lo stesso metodo di controllo dei dati).
James

Vero, ed è anche più efficiente. Dai un'occhiata alla mia risposta perché ho testato la velocità di usare issetversi che non si usano isset.
Dan Bray

voto negativo: non è possibile annullare l'impostazione delle chiavi dell'array non definite.
Behnam

1
@jascha ho detto, non possiamo!
Behnam

48

Dal manuale PHP :

Per quanto riguarda un po 'di confusione all'inizio di queste note su ciò che fa sì che unset () attivi avvisi quando si disattendono variabili che non esistono ...

Disinserimento di variabili che non esistono, come in

<?php
unset($undefinedVariable);
?>

non attiva un avviso "Variabile non definita". Ma

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

attiva due avvisi, perché questo codice serve per disinserire un elemento di un array; né $ undefinedArray né $ undefinedKey sono essi stessi non impostati, vengono semplicemente utilizzati per individuare ciò che dovrebbe essere non impostato. Dopotutto, se esistessero, ti aspetteresti comunque che siano entrambi in giro dopo. NON vorresti che l'intero array sparisse solo perché hai annullato l'impostazione () di uno dei suoi elementi!


41
Ciò richiede un po 'più di chiarimento. È possibile annullare l'impostazione delle chiavi dell'array che non sono definite finché esiste l'array stesso.
kingmaple

@kristovaher In effetti, questo non affronta affatto lo scenario specifico descritto dal PO.
Mark Amery

21

L'utilizzo unsetsu una variabile non definita non causerà alcun errore (a meno che la variabile non sia l'indice di un array (o oggetto) che non esiste).

Pertanto l'unica cosa che devi considerare è ciò che è più efficiente. È più efficiente non testare con "isset", come mostrerà il mio test.

Test:

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

Risultati:

  1. Function A time = 1.0307259559631
    • Definito senza set
  2. Function B time = 0.72514510154724
    • Indefinito senza set
  3. Function C time = 1.3804969787598
    • Definito utilizzando isset
  4. Function D time = 0.86475610733032
    • Non definito utilizzando isset

Conclusione:

È sempre meno efficiente da usare isset, per non parlare del poco tempo in più necessario per scrivere. È più veloce tentare unsetuna variabile non definita che verificare se può esserlo unset.


1
Questo è molto meglio della risposta accettata! Grazie per aver eseguito questi test.
Adam Friedman,

3

Se desideri annullare l'impostazione di una variabile, puoi semplicemente usare unset

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

Verificare la sua esistenza non ha alcun vantaggio quando si tenta di annullare l'impostazione di una variabile.

Se la variabile è un array e desideri annullare l'impostazione di un elemento, devi prima assicurarti che il genitore esista, questo vale anche per le proprietà dell'oggetto.

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

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

Questo è facilmente risolvibile avvolgendo il unsetin un if(isset($var)){ ... }blocco.

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

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

Il motivo per cui controlliamo solo la variabile ( genitore ) è semplicemente perché non abbiamo bisogno di controllare la proprietà / elemento e così facendo sarebbe molto più lento scrivere e calcolare in quanto aggiungerebbe un controllo extra.

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

Questo è ovvio ma è anche fondamentale che tu conosca typela variabile della variabile quando ottieni, imposta e disattiva un elemento o una proprietà; l'utilizzo della sintassi sbagliata genererà un errore.

È lo stesso quando si tenta di annullare l'impostazione del valore di un array o di un oggetto multidimensionale. È necessario assicurarsi che la chiave / nome padre esista.

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

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

Quando si tratta di oggetti c'è un'altra cosa a cui pensare, e questa è la visibilità.

Solo perché esiste non significa che tu abbia il permesso di modificarlo.


Finalmente una risposta adeguata. Grazie.
wp78de

Un piccolo aggiornamento: in PHP 7.4 / 8.0 non viene generato alcun errore quando si unsetpossiede la proprietà di un oggetto genitore inesistente. Tuttavia, sconvolgere una chiave in un array non esistente in PHP8 solleva non solo un avviso ma un avviso (soggetto a modifiche).
wp78de

1

Controlla questo link https://3v4l.org/hPAto

Lo strumento online mostra la compatibilità del codice per diverse versioni di PHP

Secondo questo strumento il codice

unset($_SESSION['signup_errors']);

funzionerebbe per PHP> = 5.4.0 senza darti alcun avviso / avviso / errore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.