Domanda Il modo migliore per verificare l'esistenza di una variabile in PHP; isset () è chiaramente rotto


Dal isset() docs:

isset() will return FALSE if testing a variable that has been set to NULL.

Fondamentalmente, isset() non controlla se la variabile è impostata, ma se è impostata su qualsiasi cosa tranne che NULL.

Detto questo, qual è il modo migliore per verificare effettivamente l'esistenza di una variabile? Ho provato qualcosa come:

if(isset($v) || @is_null($v))

(il @ è necessario evitare l'avvertimento quando $v non è impostato) ma is_null() ha un problema simile a isset(): ritorna TRUE su variabili non impostate! Sembra anche che:

@($v === NULL)

funziona esattamente come @is_null($v)anche questo è fuori.

Come dovremmo controllare in modo affidabile l'esistenza di una variabile in PHP?


Modifica: esiste chiaramente una differenza in PHP tra le variabili non impostate e le variabili impostate su NULL:

<?php
$a = array('b' => NULL);
var_dump($a);

PHP lo dimostra $a['b'] esiste e ha un NULL valore. Se aggiungi:

var_dump(isset($a['b']));
var_dump(isset($a['c']));

puoi vedere l'ambiguità di cui sto parlando con isset() funzione. Ecco l'output di tutti e tre questi var_dump()s:

array(1) {
  ["b"]=>
  NULL
}
bool(false)
bool(false)

Ulteriore modifica: due cose.

Uno, un caso d'uso. Un array che viene trasformato nei dati di un SQL UPDATE istruzione, in cui le chiavi dell'array sono le colonne della tabella e i valori dell'array sono i valori da applicare a ciascuna colonna. Qualsiasi colonna della tabella può contenere a NULL valore, significato passando a NULL valore nella matrice. tu bisogno un modo per distinguere tra una chiave dell'array non esistente e il valore dell'array impostato NULL; questa è la differenza tra non aggiornare il valore della colonna e aggiornare il valore della colonna in NULL.

Secondo, La risposta di Zoredache, array_key_exists() funziona correttamente, per il mio caso di utilizzo sopra e per qualsiasi variabile globale:

<?php
$a = NULL;
var_dump(array_key_exists('a', $GLOBALS));
var_dump(array_key_exists('b', $GLOBALS));

uscite:

bool(true)
bool(false)

Dal momento che gestisce correttamente quasi ovunque, posso vedere che c'è qualche ambiguità tra le variabili che non esistono e le variabili impostate NULL, sto chiamando array_key_exists() il modo più semplice e ufficiale in PHP per verificare veramente l'esistenza di una variabile.

(Solo l'altro caso a cui riesco a pensare è per le proprietà di classe, per le quali c'è property_exists(), che, secondo i suoi documenti, funziona allo stesso modo di array_key_exists() in quanto distingue correttamente tra non essere impostato e impostato NULL.)


177
2018-01-06 20:46


origine


risposte:


Se la variabile che stai verificando si troverebbe nell'ambito globale, potresti fare:

array_key_exists('v', $GLOBALS) 

92
2018-01-06 21:07



Tentativo di fornire una panoramica delle varie discussioni e risposte:

Non esiste un'unica risposta alla domanda che possa sostituire tutti i modi isset può essere utilizzata. Alcuni casi d'uso sono indirizzati da altre funzioni, mentre altri non reggono il controllo, o hanno un valore dubbio al di là del codice golf. Lungi dall'essere "spezzati" o "incoerenti", altri casi d'uso dimostrano il perché issetLa reazione a null è il comportamento logico.

Casi di uso reale (con soluzioni)

1. Tasti della matrice

Le matrici possono essere trattate come raccolte di variabili, con unset e isset trattandoli come se fossero. Tuttavia, poiché possono essere ripetuti, contati, ecc., Un valore mancante non è uguale a uno il cui valore è null.

La risposta in questo caso è a uso array_key_exists() invece di isset().

Poiché questo è necessario all'array per verificare come argomento della funzione, PHP genererà ancora "notifiche" se l'array stesso non esiste. In alcuni casi, si può validamente sostenere che ogni dimensione avrebbe dovuto essere inizializzata per prima, quindi l'avviso sta facendo il suo lavoro. Per altri casi, un "ricorsivo" array_key_exists la funzione, che controllava a turno ogni dimensione della matrice, evitava questo, ma sarebbe sostanzialmente la stessa di @array_key_exists. È anche un po 'tangibile alla gestione di null valori.

2. Proprietà dell'oggetto

Nella teoria tradizionale di "Programmazione orientata agli oggetti", l'incapsulamento e il polimorfismo sono proprietà chiave degli oggetti; in un'implementazione OOP basata su classi come PHP, le proprietà incapsulate sono dichiarate come parte della definizione della classe e sono forniti i livelli di accesso (public, protected, o private).

Tuttavia, PHP ti consente anche di aggiungere dinamicamente le proprietà a un oggetto, come faresti con le chiavi di un array, e alcune persone usano oggetti senza classe (tecnicamente, le istanze del built-in stdClass, che non ha metodi o funzionalità private) in modo simile agli array associativi. Ciò porta a situazioni in cui una funzione potrebbe voler sapere se una particolare proprietà è stata aggiunta all'oggetto che gli è stato assegnato.

Come con i tasti dell'array, una soluzione per il controllo delle proprietà dell'oggetto è inclusa nella lingua, chiamata, abbastanza ragionevolmente, property_exists.

Casi d'uso non giustificabili, con discussione

3. register_globalse altro inquinamento del namespace globale

Il register_globals sono state aggiunte variabili all'ambito globale i cui nomi sono stati determinati da aspetti della richiesta HTTP (parametri GET e POST e cookie). Questo può portare a codice bug e insicuro, motivo per cui è stato disabilitato di default da allora PHP 4.2, rilasciato nell'agosto 2000 e rimosso completamente dentro PHP 5.4, pubblicato a marzo 2012. Tuttavia, è possibile che alcuni sistemi siano ancora in esecuzione con questa funzione abilitata o emulata. È anche possibile "inquinare" lo spazio dei nomi globale in altri modi, usando il global parola chiave, o $GLOBALS array.

In primo luogo, register_globals è improbabile che inaspettatamente produca un null variabile, poiché i valori GET, POST e cookie saranno sempre stringhe (con '' ancora tornando true a partire dal isset) e le variabili nella sessione dovrebbero essere interamente sotto il controllo del programmatore.

In secondo luogo, l'inquinamento di una variabile con il valore null è solo un problema se questo sovrascrive alcune precedenti inizializzazioni. "Sovrascrittura" di una variabile non inizializzata con null sarebbe solo problematico se il codice da qualche altra parte distinguesse tra i due stati, quindi da solo questa possibilità è un argomento contro fare una tale distinzione.

4. get_defined_vars e compact

Alcune funzioni raramente utilizzate in PHP, come ad esempio get_defined_vars e compact, ti permettono di trattare i nomi delle variabili come se fossero chiavi in ​​un array. Per le variabili globali, l'array super-globale $GLOBALS consente un accesso simile ed è più comune. Questi metodi di accesso si comportano diversamente se una variabile non è definita nell'ambito pertinente.

Una volta che hai deciso di trattare un insieme di variabili come un array usando uno di questi meccanismi, puoi fare tutte le stesse operazioni su di esso come su qualsiasi array normale. Di conseguenza, vedi 1.

Funzionalità che esisteva solo per prevedere come queste funzioni stanno per comportarsi (ad esempio "ci sarà una chiave" pippo "nella matrice restituita da get_defined_vars? ") è superfluo, dal momento che puoi semplicemente eseguire la funzione e scoprire senza effetti negativi.

4a. Variabili variabili ($$foo)

Pur non proprio come le funzioni che trasformano un insieme di variabili in un array associativo, utilizzando la maggior parte dei casi "variabili variabili" ("assegnare a una variabile denominata in base a questa altra variabile") può e deve essere modificato per utilizzare invece un array associativo.

Un nome di variabile, fondamentalmente, è l'etichetta assegnata ad un valore dal programmatore; se lo stai determinando in fase di esecuzione, non si tratta in realtà di un'etichetta, ma di una chiave in qualche archivio di valori-chiave. Più praticamente, non usando un array, stai perdendo la capacità di contare, iterare, ecc; può anche diventare impossibile avere una variabile "esterna" all'archivio dei valori-chiave, poiché potrebbe essere sovrascritta da $$foo.

Una volta modificato per utilizzare un array associativo, il codice sarà suscettibile alla soluzione 1. Accesso alla proprietà dell'oggetto indiretto (ad es. $foo->$property_name) può essere risolto con la soluzione 2.

5. isset è molto più facile da digitare di array_key_exists

Non sono sicuro che questo sia veramente rilevante, ma sì, i nomi delle funzioni di PHP possono essere piuttosto prolissi e talvolta incoerenti. Apparentemente, le versioni pre-storiche di PHP utilizzavano la lunghezza del nome di una funzione come una chiave hash, quindi Rasmus creò deliberatamente nomi di funzioni come htmlspecialchars quindi avrebbero un numero insolito di personaggi ...

Comunque, almeno non stiamo scrivendo Java, eh? ;)

6. Le variabili non inizializzate hanno un tipo

Il pagina di manuale sulle basi variabili include questa affermazione:

Le variabili non inizializzate hanno un valore predefinito del loro tipo in base al contesto in cui vengono utilizzate

Non sono sicuro se ci sia qualche idea nel motore di Zend di "tipo non inizializzato ma conosciuto" o se questo sta leggendo troppo nella dichiarazione.

Ciò che è chiaro è che non fa alcuna differenza pratica per il loro comportamento, dal momento che i comportamenti descritti in quella pagina per le variabili non inizializzate sono identici al comportamento di una variabile il cui valore è null. Per scegliere un esempio, entrambi $a e $b in questo codice finirà come intero 42:

unset($a);
$a += 42;

$b = null;
$b += 42;

(Il primo solleverà un avviso relativo a una variabile non dichiarata, nel tentativo di farti scrivere codice migliore, ma non farà alcuna differenza sul modo in cui il codice viene effettivamente eseguito).

99. Rilevamento se una funzione è stata eseguita

(Tenendolo per ultimo, poiché è molto più lungo degli altri, forse lo modificherò più tardi ...)

Considera il seguente codice:

$test_value = 'hello';
foreach ( $list_of_things as $thing ) {
    if ( some_test($thing, $test_value) ) {
        $result = some_function($thing);
    }
}
if ( isset($result) ) {
    echo 'The test passed at least once!';
}

Se some_function può tornare null, c'è una possibilità che il echo non sarà raggiunto anche se some_test tornato true. L'intenzione del programmatore era di rilevare quando $result non era mai stato impostato, ma PHP non consente loro di farlo.

Tuttavia, ci sono altri problemi con questo approccio, che diventano chiari se si aggiunge un ciclo esterno:

foreach ( $list_of_tests as $test_value ) {
    // something's missing here...
    foreach ( $list_of_things as $thing ) {
        if ( some_test($thing, $test_value) ) {
            $result = some_function($thing);
        }
    }
    if ( isset($result) ) {
        echo 'The test passed at least once!';
    }
}

Perché $result non viene mai inizializzato in modo esplicito, assumerà un valore quando passa il primo test, rendendo impossibile stabilire se i test successivi siano passati o meno. Questo è in realtà un bug estremamente comune quando le variabili non sono inizializzate correttamente.

Per risolvere questo problema, dobbiamo fare qualcosa sulla linea in cui ho commentato che manca qualcosa. La soluzione più ovvia è impostare $result a un "valore terminale" che some_function non può mai tornare; se questo è null, quindi il resto del codice funzionerà correttamente. Se non esiste un candidato naturale per un valore terminale perché some_function ha un tipo di ritorno estremamente imprevedibile (che è probabilmente un brutto segno in sé), quindi un valore booleano aggiuntivo, ad es. $found, potrebbe essere usato invece.

Esperimento di pensiero: il very_null costante

PHP potrebbe teoricamente fornire una costante speciale - oltre a null - da utilizzare come valore terminale qui; presumibilmente, sarebbe illegale restituire questo da una funzione, o sarebbe forzato a farlo nulle lo stesso probabilmente si applicherebbe a passarlo come argomento di funzione. Ciò renderebbe leggermente più semplice questo caso molto specifico, ma non appena decideste di ridimensionare il codice, ad esempio per mettere il ciclo interno in una funzione separata, diventerebbe inutile. Se la costante potesse essere passata tra le funzioni, non potevi garantirlo some_function non lo restituirebbe, quindi non sarebbe più utile come valore terminale universale.

L'argomento per rilevare le variabili non inizializzate in questo caso si riduce all'argomento per quella costante speciale: se si sostituisce il commento con unset($result)e trattalo in modo diverso da $result = null, stai introducendo un "valore" per $result che non può essere passato in giro e può essere rilevato solo da specifiche funzioni integrate.

Esperimento di pensiero due: contatore di incarichi

Un altro modo di pensare a ciò che l'ultimo if sta chiedendo è "è qualcosa a cui è stato assegnato un incarico $result? "Piuttosto che considerarlo un valore speciale di $result, potresti forse pensare a questo come "metadati" di la variabile, un po 'come "la contaminazione variabile" di Perl. Quindi piuttosto che isset potresti chiamarlo has_been_assigned_toe piuttosto che unset, reset_assignment_state.

Ma se è così, perché fermarsi a un booleano? Che cosa succede se vuoi sapere quante volte il test è passato; potresti semplicemente estendere i tuoi metadati a un numero intero e avere get_assignment_count e reset_assignment_count...

Ovviamente, l'aggiunta di una tale funzionalità avrebbe un compromesso in termini di complessità e prestazioni della lingua, quindi dovrebbe essere attentamente valutata rispetto alla sua utilità prevista. Come con a very_nullcostante, sarebbe utile solo in circostanze molto strette e sarebbe allo stesso modo resistente al ri-factoring.

La domanda, si spera, ovvia, è perché il motore di runtime di PHP dovrebbe assumere in anticipo che si desidera tenere traccia di tali cose, piuttosto che lasciarlo fare esplicitamente, utilizzando il codice normale.


42
2017-09-05 21:52



A volte mi sento un po 'perso cercando di capire quale operazione di confronto usare in una determinata situazione. isset() si applica solo ai valori non inizializzati o esplicitamente nulli. Passare / assegnare null è un ottimo modo per garantire che un confronto logico funzioni come previsto.

Tuttavia, è un po 'difficile da pensare, quindi ecco una semplice matrice che confronta come diversi valori saranno valutati da diverse operazioni:

|           | ===null | is_null | isset | empty | if/else | ternary | count>0 |
| -----     | -----   | -----   | ----- | ----- | -----   | -----   | -----   |
| $a;       | true    | true    |       | true  |         |         |         |
| null      | true    | true    |       | true  |         |         |         |
| []        |         |         | true  | true  |         |         |         |
| 0         |         |         | true  | true  |         |         | true    |
| ""        |         |         | true  | true  |         |         | true    |
| 1         |         |         | true  |       | true    | true    | true    |
| -1        |         |         | true  |       | true    | true    | true    |
| " "       |         |         | true  |       | true    | true    | true    |
| "str"     |         |         | true  |       | true    | true    | true    |
| [0,1]     |         |         | true  |       | true    | true    | true    |
| new Class |         |         | true  |       | true    | true    | true    |

Per adattarsi al tavolo ho compresso un po 'le etichette:

  • $a; si riferisce a una variabile dichiarata ma non assegnata
  • tutto il resto nella prima colonna si riferisce a un valore assegnato, come:
    • $a = null;
    • $a = [];
    • $a = 0;
    • ...
  • le colonne si riferiscono a operazioni di confronto, come:
    • $a === null
    • isset($a)
    • empty($a)
    • $a ? true : false
    • ...

Tutti i risultati sono booleani, true è stampato e false è omesso.

Puoi eseguire tu stesso i test, controlla questo succo:
https://gist.github.com/mfdj/8165967


21
2017-12-29 07:05



È possibile utilizzare il costrutto del linguaggio compatto per verificare l'esistenza di una variabile nulla. Le variabili che non esistono non verranno visualizzate nel risultato, mentre i valori nulli verranno visualizzati.

$x = null;
$y = 'y';

$r = compact('x', 'y', 'z');
print_r($r);

// Output:
// Array ( 
//  [x] => 
//  [y] => y 
// ) 

Nel caso del tuo esempio:

if (compact('v')) {
   // True if $v exists, even when null. 
   // False on var $v; without assignment and when $v does not exist.
}

Ovviamente per le variabili nell'ambito globale è possibile utilizzare anche array_key_exists ().

B.t.w. personalmente eviterei situazioni come la peste dove c'è una differenza semantica tra una variabile non esistente e la variabile che ha un valore nullo. PHP e la maggior parte delle altre lingue semplicemente non pensano che ci sia.


17
2017-12-28 11:57



Spiegando NULL, logicamente pensando

Immagino che la risposta ovvia a tutto questo sia ... Non inizializzare le variabili come NULL, inizializzarle come qualcosa di rilevante per ciò che sono destinati a diventare.

Tratta NULL correttamente

NULL deve essere considerato come "valore inesistente", che è il significato di NULL. La variabile non può essere classificata come esistente in PHP perché non è stato detto quale tipo di entità sta cercando di essere. Potrebbe anche non esistere, quindi PHP dice semplicemente "Bene, non perché non ha senso in ogni caso e NULL è il mio modo di dirlo".

Un argomento

Discutiamo ora. "Ma NULL è come dire 0 o FALSE o ''.

Wrong, 0-FALSE- '' sono tutti ancora classificati come valori vuoti, ma sono specificati come un tipo di valore o una risposta predeterminata a una domanda. FALSE è la risposta a sì o no,'' è la risposta al titolo di qualcuno inviato, e 0 è la risposta alla quantità o al tempo ecc. Sono impostati come un tipo di risposta / risultato che li rende validi come impostati.

NULL non ha alcuna risposta, ma non ci dice sì o no e non ci dice l'ora e non ci dice che una stringa vuota è stata inviata. Questa è la logica di base nella comprensione di NULL.

Sommario

Non si tratta di creare stravaganti funzioni per aggirare il problema, ma semplicemente di cambiare il modo in cui il tuo cervello guarda NULL. Se è NULL, supponi che non sia impostato come nulla. Se si definiscono le variabili predefinite, pre-definirle come 0, FALSE o "" in base al tipo di utilizzo che si intende utilizzare per esse.

Sentiti libero di citare questo. È al di sopra della mia testa logica :)


15
2018-03-31 10:13



Le proprietà dell'oggetto possono essere verificate per esistenza property_exists

Esempio da un test unitario:

function testPropertiesExist()
{
    $sl =& $this->system_log;
    $props = array('log_id',
                   'type',
                   'message',
                   'username',
                   'ip_address',
                   'date_added');

    foreach($props as $prop) {
        $this->assertTrue(property_exists($sl, $prop),
                           "Property <{$prop}> exists");
    }
}

9
2018-01-24 12:35



In aggiunta a la discussione di greatbigmassive su cosa significhi NULL, considera cosa significa "l'esistenza di una variabile".

In molte lingue, devi dichiarare esplicitamente ogni variabile prima di usarla; questo può determinare il suo tipo, ma soprattutto lo dichiara scopo. Una variabile "esiste" ovunque nel suo campo di applicazione, e da nessuna parte al di fuori di essa - si tratti di un'intera funzione o di un singolo "blocco".

Nel suo ambito, una variabile assegna un significato ad un'etichetta che tu, il programmatore, hai scelto. Al di fuori del suo ambito, quell'etichetta è priva di significato (se si utilizza la stessa etichetta in un ambito diverso è sostanzialmente irrilevante).

In PHP, le variabili non devono essere dichiarate - prendono vita non appena ne hai bisogno. Quando scrivi una variabile per la prima volta, PHP assegna una voce in memoria per quella variabile. Se leggi da una variabile che al momento non ha una voce, PHP considera tale variabile come valore NULL.

Tuttavia, i rilevatori automatici di qualità del codice ti avviseranno in genere se usi una variabile senza prima inizializzarla. In primo luogo, questo aiuta a rilevare errori di battitura, come l'assegnazione a $thingId ma leggendo da $thing_id; ma in secondo luogo, ti costringe a considerare l'ambito su cui tale variabile ha un significato, proprio come farebbe una dichiarazione.

Qualsiasi codice che si preoccupa se una variabile "esiste" fa parte dell'ambito di tale variabile - indipendentemente dal fatto che sia stato inizializzato o meno, voi come programmatori avete dato quel significato di etichetta in quel punto del codice. Dal momento che lo stai usando, in un certo senso deve "esistere" e, se esiste, deve avere un valore implicito; in PHP, questo è il valore implicito null.

A causa del modo in cui funziona PHP, è possibile scrivere codice che tratta lo spazio dei nomi delle variabili esistenti non come un ambito di etichette a cui hai dato un significato, ma come una sorta di archivio di valori-chiave. Ad esempio, puoi eseguire un codice come questo: $var = $_GET['var_name']; $$var = $_GET['var_value'];. Solo perché puoi, non significa che sia una buona idea.

Risulta che PHP ha un modo molto migliore di rappresentare gli archivi di valore-chiave, chiamati array associativi. E sebbene i valori di un array possano essere trattati come variabili, è anche possibile eseguire operazioni sull'array nel suo complesso. Se si dispone di un array associativo, è possibile verificare se contiene una chiave array_key_exists(). 

Puoi anche usare gli oggetti in modo simile, impostando dinamicamente le proprietà, nel qual caso puoi usare property_exists() esattamente nello stesso modo. Ovviamente, se si definisce una classe, è possibile dichiarare quali proprietà ha - puoi anche scegliere tra public, private, e protected scopo.

Sebbene ci sia un tecnico differenza tra una variabile (al contrario di una chiave di array o una proprietà dell'oggetto) che non è stata inizializzata (o che è stata esplicitamente unset()) e uno il cui valore è null, qualsiasi codice che consideri tale differenza significativo sta usando le variabili in un modo in cui non sono pensate per essere utilizzate.


4
2017-09-03 21:11



isset controlla se la variabile è impostata e, in caso affermativo, se la sua valore non è NULL. L'ultima parte è (a mio parere) non nell'ambito di questa funzione. Non esiste una soluzione decente per determinare se una variabile è NULL perché non è impostato o perché è impostato esplicitamente su NULL.

Ecco una possibile soluzione:

$e1 = error_get_last();
$isNULL = is_null(@$x);
$e2 = error_get_last();
$isNOTSET = $e1 != $e2;
echo sprintf("isNOTSET: %d, isNULL: %d", $isNOTSET, $isNULL);

// Sample output:
// when $x is not set: isNOTSET: 1, isNULL: 1
// when $x = NULL:     isNOTSET: 0, isNULL: 1
// when $x = false:    isNOTSET: 0, isNULL: 0

Un'altra soluzione è sondare l'output di get_defined_vars():

$vars = get_defined_vars();
$isNOTSET = !array_key_exists("x", $vars);
$isNULL = $isNOTSET ? true : is_null($x);
echo sprintf("isNOTSET: %d, isNULL: %d", $isNOTSET, $isNULL);

// Sample output:
// when $x is not set: isNOTSET: 1, isNULL: 1
// when $x = NULL:     isNOTSET: 0, isNULL: 1
// when $x = false:    isNOTSET: 0, isNULL: 0

3
2018-01-31 15:32



Non sono d'accordo con il tuo ragionamento su NULLe dicendo che è necessario cambiare idea su NULL è solo strano.

Penso che isset () non sia stato progettato correttamente, isset () dovrebbe dirti se la variabile è stata impostata e non dovrebbe riguardare il valore effettivo della variabile.

Cosa succede se si controllano i valori restituiti da un database e una delle colonne ha un valore NULL, si vuole comunque sapere se esiste anche se il valore è NULL ... nope non si deve fidare di isset () qui.

allo stesso modo

$a = array ('test' => 1, 'hello' => NULL);

var_dump(isset($a['test']));   // TRUE
var_dump(isset($a['foo']));    // FALSE
var_dump(isset($a['hello']));  // FALSE

isset () dovrebbe essere stato progettato per funzionare in questo modo:

if(isset($var) && $var===NULL){....

in questo modo lasciamo al programmatore il compito di controllare i tipi e non lasciarlo su isset () per assumere che non ci sia perché il valore è NULL - è solo un disegno stupido


2
2018-01-28 15:48



Ho intenzione di aggiungere un rapido due centesimi a questo. Uno dei motivi per cui questo problema è confuso è perché questo scenario sembra restituire lo stesso risultato con la segnalazione degli errori non per intero:

$a = null;
var_dump($a); // NULL
var_dump($b); // NULL

Si potrebbe supporre da questo risultato che la differenza tra $a = null e non definire $b niente è niente.

Errore di avvio segnalato:

NULL

Notice: Undefined variable: b in xxx on line n
NULL

Nota: ha generato un errore variabile non definito, ma il valore di output di var_dump è ancora NULL.

PHP ovviamente ha una capacità interna di distinguere tra una variabile nulla e una variabile non definita. Mi sembra che ci dovrebbe essere una funzione incorporata per verificare questo.

Penso che la risposta accettata sia buona per la maggior parte, ma se dovessi implementarla scriverò un wrapper per questo. Come precedentemente menzionato in questa risposta, Devo essere d'accordo sul fatto che non ho effettivamente riscontrato una situazione in cui questo è stato un problema. Mi sembra di finire quasi sempre in uno scenario in cui le mie variabili sono impostate e definite, o non lo sono (indefinito, non impostato, nullo, vuoto, ecc.). Per non dire che una situazione come questa non si verificherà in futuro, ma dato che sembra essere un problema univoco non mi sorprende che gli sviluppatori di PHP non si siano preoccupati di inserire questo.


2
2018-05-22 21:52



Se eseguo il seguente:

echo '<?php echo $foo; ?>' | php

Ottengo un errore:

PHP Notice:  Undefined variable: foo in /home/altern8/- on line 1

Se eseguo il seguente:

echo '<?php if ( isset($foo) ) { echo $foo; } ?>' | php

Non capisco l'errore.

Se ho una variabile che dovrebbe essere impostata, di solito faccio qualcosa di simile al seguente.

$foo = isset($foo) ? $foo : null;

o

if ( ! isset($foo) ) $foo = null;

In questo modo, più avanti nella sceneggiatura, posso tranquillamente usare $ foo e sapere che è "impostato", e che per default è nullo. Più tardi posso if ( is_null($foo) ) { /* ... */ } se ho bisogno e so per certo che la variabile esiste, anche se è nulla.

Il pieno isset documentazione legge poco più di ciò che è stato inizialmente incollato. Sì, restituisce false per una variabile precedentemente impostata ma ora è nulla, ma restituisce anche false se una variabile non è stata ancora impostata (mai) e per qualsiasi variabile che è stata contrassegnata come non impostata. Nota inoltre che il byte NULL ("\ 0") non è considerato nullo e restituirà true.

Determina se una variabile è impostata.

Se una variabile è stata disinserita con   unset (), non sarà più impostato.   isset () restituirà FALSE se si prova a   variabile che è stata impostata su NULL.   Si noti inoltre che un byte NULL ("\ 0") è   non equivalente al PHP NULL   costante.


1
2018-01-06 21:00