Aus den isset()
Dokumenten :
isset() will return FALSE if testing a variable that has been set to NULL.
isset()
Überprüft grundsätzlich nicht, ob die Variable überhaupt gesetzt ist, sondern ob sie auf etwas anderes als gesetzt ist NULL
.
Was ist angesichts dessen der beste Weg, um tatsächlich zu prüfen, ob eine Variable vorhanden ist? Ich habe so etwas versucht wie:
if(isset($v) || @is_null($v))
(das @
ist notwendig, um die Warnung zu vermeiden, wenn $v
es nicht gesetzt ist), is_null()
hat aber ein ähnliches Problem wie isset()
: Es gibt bei nicht gesetzten TRUE
Variablen zurück! Es scheint auch, dass:
@($v === NULL)
funktioniert genau so @is_null($v)
, also ist das auch raus.
Wie sollen wir zuverlässig prüfen, ob in PHP eine Variable vorhanden ist?
Bearbeiten: Es gibt eindeutig einen Unterschied in PHP zwischen Variablen, die nicht festgelegt sind, und Variablen, die festgelegt sind auf NULL
:
<?php
$a = array('b' => NULL);
var_dump($a);
PHP zeigt, dass es $a['b']
existiert und einen NULL
Wert hat. Wenn Sie hinzufügen:
var_dump(isset($a['b']));
var_dump(isset($a['c']));
Sie können die Mehrdeutigkeit sehen, über die ich mit der isset()
Funktion spreche . Hier ist die Ausgabe aller drei var_dump()s
:
array(1) {
["b"]=>
NULL
}
bool(false)
bool(false)
Weiter bearbeiten: zwei Dinge.
Erstens ein Anwendungsfall. Ein Array wird in die Daten einer SQL- UPDATE
Anweisung umgewandelt, wobei die Schlüssel des Arrays die Spalten der Tabelle und die Werte des Arrays die Werte sind, die auf jede Spalte angewendet werden sollen. Jede Spalte der Tabelle kann einen NULL
Wert enthalten, der durch Übergabe eines NULL
Werts im Array gekennzeichnet ist. Sie benötigen eine Möglichkeit, zwischen einem nicht vorhandenen Array-Schlüssel und dem Wert eines Arrays zu unterscheidenNULL
. Das ist der Unterschied zwischen dem Nicht-Aktualisieren des Spaltenwerts und dem Aktualisieren des Spaltenwerts auf NULL
.
Zweitens Zoredache Antwort , array_key_exists()
funktioniert einwandfrei , für meinen oben Anwendungsfall und für alle globalen Variablen:
<?php
$a = NULL;
var_dump(array_key_exists('a', $GLOBALS));
var_dump(array_key_exists('b', $GLOBALS));
Ausgänge:
bool(true)
bool(false)
Da das richtig fast überall Griffe kann ich dort sehen ist , jede Zweideutigkeit zwischen Variablen , die nicht existieren und Variablen, die gesetzt sind NULL
, bin ich rufe array_key_exists()
den offiziellen einfachste Weg , in PHP wirklich für die Existenz einer Variablen zu überprüfen .
(Nur ein anderer Fall, den ich mir vorstellen kann , betrifft Klasseneigenschaften, für die es gibt property_exists()
, die laut ihren Dokumenten ähnlich funktionieren, array_key_exists()
indem sie richtig zwischen Nicht-Setzen und Setzen auf unterscheiden NULL
.)
register_globals
, bin ich kämpfen nach wie vor einer Situation zu denken , wo , dass auch eine solche Unterscheidung erfordern würde, da alles von der HTTP - Anforderung registriert immer ein String sein würde, nichtnull
.Antworten:
Wenn sich die zu überprüfende Variable im globalen Bereich befindet, können Sie Folgendes tun:
quelle
$defined_vars = get_defined_vars();
und dann über testenarray_key_exists('v', $defined_vars);
.isset($foo[$bar])
wirdarray_key_exists($bar, $foo)
property_exists
scheint vielversprechend, außer dies:> Die Funktion property_exists () kann keine Eigenschaften erkennen, auf die mit der magischen Methode __get magisch zugegriffen werden kann.Versuch, einen Überblick über die verschiedenen Diskussionen und Antworten zu geben:
Es gibt keine einzige Antwort auf die Frage, die alle Verwendungsmöglichkeiten ersetzen
isset
kann. Einige Anwendungsfälle werden von anderen Funktionen behandelt, während andere der Prüfung nicht standhalten oder über Code-Golf hinaus einen zweifelhaften Wert haben. Weit davon entfernt, "kaputt" oder "inkonsistent" zu sein, zeigen andere Anwendungsfälle, warumisset
die Reaktion aufnull
das logische Verhalten ist.Echte Anwendungsfälle (mit Lösungen)
1. Array-Schlüssel
Arrays können wie Sammlungen von Variablen behandelt werden, mit
unset
undisset
behandelt sie , als ob sie waren. Da sie jedoch iteriert, gezählt usw. werden können, ist ein fehlender Wert nicht mit einem Wert identisch, dessen Wert istnull
.Die Antwort in diesem Fall ist zu verwenden ,
array_key_exists()
stattisset()
.Da das Array als Funktionsargument überprüft werden muss, gibt PHP weiterhin "Benachrichtigungen" aus, wenn das Array selbst nicht vorhanden ist. In einigen Fällen kann mit Recht argumentiert werden, dass jede Dimension zuerst initialisiert werden sollte, damit die Benachrichtigung ihre Aufgabe erfüllt. In anderen Fällen würde eine "rekursive"
array_key_exists
Funktion, die nacheinander jede Dimension des Arrays prüft, dies vermeiden, wäre aber im Grunde dieselbe wie@array_key_exists
. Es ist auch etwas tangential zum Umgang mitnull
Werten.2. Objekteigenschaften
In der traditionellen Theorie der "objektorientierten Programmierung" sind Kapselung und Polymorphismus Schlüsseleigenschaften von Objekten; in einer klassenbasierten OOP Implementierung wie PHP, werden die eingekapselten Eigenschaften als Teil der Klassendefinition deklarieren, und gegebenen Zugriffsebene (
public
,protected
oderprivate
).Mit PHP können Sie einem Objekt jedoch auch dynamisch Eigenschaften hinzufügen, wie Sie es für ein Array tun würden, und einige Benutzer verwenden klassenlose Objekte (technisch gesehen Instanzen des integrierten Objekts)
stdClass
, das keine Methoden oder privaten Funktionen enthält) in ähnlicher Weise Weg zu assoziativen Arrays. Dies führt zu Situationen, in denen eine Funktion möglicherweise wissen möchte, ob dem ihr zugewiesenen Objekt eine bestimmte Eigenschaft hinzugefügt wurde.Wie bei Array-Schlüsseln ist in der Sprache eine Lösung zum Überprüfen von Objekteigenschaften enthalten, die vernünftigerweise aufgerufen wird
property_exists
.Nicht vertretbare Anwendungsfälle mit Diskussion
3.
register_globals
und andere Verschmutzung des globalen NamespaceDie
register_globals
Funktion fügte dem globalen Bereich Variablen hinzu, deren Namen durch Aspekte der HTTP-Anforderung (GET- und POST-Parameter sowie Cookies) bestimmt wurden. Dies kann zu fehlerhaftem und unsicherem Code führen, weshalb er seit PHP 4.2, veröffentlicht im August 2000, standardmäßig deaktiviert und in PHP 5.4, veröffentlicht im März 2012, vollständig entfernt wurde . Es ist jedoch möglich, dass einige Systeme noch mit aktivierter oder emulierter Funktion ausgeführt werden. Es ist auch möglich, den globalen Namespace mit demglobal
Schlüsselwort oder$GLOBALS
Array auf andere Weise zu "verschmutzen" .Erstens
register_globals
ist es unwahrscheinlich , dass selbst unerwartet einenull
Variable erzeugt wird, da die GET-, POST- und Cookie-Werte immer Zeichenfolgen sind (wobei''
immer nochtrue
von zurückgegeben wirdisset
) und die Variablen in der Sitzung vollständig unter der Kontrolle des Programmierers stehen sollten.Zweitens ist die Verschmutzung einer Variablen mit dem Wert
null
nur dann ein Problem, wenn dadurch eine vorherige Initialisierung überschrieben wird. Das "Überschreiben" einer nicht initialisierten Variablen mitnull
wäre nur dann problematisch, wenn Code irgendwo anders zwischen den beiden Zuständen unterscheiden würde. Diese Möglichkeit allein ist also ein Argument gegen eine solche Unterscheidung.4.
get_defined_vars
undcompact
Mit einigen in PHP selten verwendeten Funktionen wie
get_defined_vars
undcompact
können Sie Variablennamen so behandeln, als wären sie Schlüssel in einem Array. Für globale Variablen ermöglicht das superglobale Array$GLOBALS
einen ähnlichen Zugriff und ist häufiger. Diese Zugriffsmethoden verhalten sich anders, wenn eine Variable nicht im entsprechenden Bereich definiert ist.Sobald Sie sich entschieden haben, eine Reihe von Variablen mithilfe eines dieser Mechanismen als Array zu behandeln, können Sie dieselben Operationen wie bei jedem normalen Array ausführen. Folglich siehe 1.
Funktionen, die nur existierten, um vorherzusagen, wie sich diese Funktionen verhalten werden (z. B. "Gibt es einen Schlüssel 'foo' in dem von zurückgegebenen Array
get_defined_vars
?") , Sind überflüssig, da Sie die Funktion einfach ausführen und ohne negative Auswirkungen herausfinden können.4a. Variable Variablen (
$$foo
)Obwohl dies nicht ganz mit Funktionen identisch ist, die eine Reihe von Variablen in ein assoziatives Array verwandeln, kann und sollte in den meisten Fällen die Verwendung von "Variablenvariablen" ("Zuweisen einer Variablen, die auf der Grundlage dieser anderen Variablen benannt ist") geändert werden, um stattdessen ein assoziatives Array zu verwenden .
Ein Variablenname ist im Grunde die Bezeichnung, die ein Wert vom Programmierer erhält. Wenn Sie es zur Laufzeit bestimmen, ist es nicht wirklich ein Label, sondern ein Schlüssel in einem Schlüsselwertspeicher. Praktischer gesagt, wenn Sie kein Array verwenden, verlieren Sie die Fähigkeit zu zählen, zu iterieren usw.; Es kann auch unmöglich werden, eine Variable "außerhalb" des Schlüsselwertspeichers zu haben, da sie möglicherweise von überschrieben wird
$$foo
.Nach der Änderung zur Verwendung eines assoziativen Arrays kann der Code für Lösung 1 verwendet werden. Der indirekte Zugriff auf Objekteigenschaften (z. B.
$foo->$property_name
) kann mit Lösung 2 behandelt werden.5.
isset
ist so viel einfacher zu tippen alsarray_key_exists
Ich bin mir nicht sicher, ob dies wirklich relevant ist, aber ja, die Funktionsnamen von PHP können manchmal ziemlich langwierig und inkonsistent sein. Anscheinend haben prähistorische Versionen von PHP die Länge eines Funktionsnamens als Hash-Taste verwendet, daher hat Rasmus absichtlich Funktionsnamen so erfunden,
htmlspecialchars
dass sie eine ungewöhnliche Anzahl von Zeichen haben würden ...Zumindest schreiben wir kein Java, oder? ;)
6. Nicht initialisierte Variablen haben einen Typ
Die Handbuchseite zu Variablengrundlagen enthält folgende Anweisung:
Ich bin mir nicht sicher, ob es in der Zend Engine eine Vorstellung von "nicht initialisiertem, aber bekanntem Typ" gibt oder ob dies zu viel in die Aussage einliest.
Klar ist, dass es keinen praktischen Unterschied zu ihrem Verhalten macht, da die auf dieser Seite beschriebenen Verhaltensweisen für nicht initialisierte Variablen mit dem Verhalten einer Variablen identisch sind, deren Wert ist
null
. Um ein Beispiel auszuwählen, werden beide$a
und$b
in diesem Code als Ganzzahl angezeigt42
:(Der erste wird einen Hinweis auf eine nicht deklarierte Variable auslösen, um Sie dazu zu bringen, besseren Code zu schreiben, aber es macht keinen Unterschied, wie der Code tatsächlich ausgeführt wird.)
99. Erkennen, ob eine Funktion ausgeführt wurde
(Behalte dieses letzte, da es viel länger ist als die anderen. Vielleicht werde ich es später bearbeiten ...)
Betrachten Sie den folgenden Code:
Wenn zurückkehren
some_function
kannnull
, besteht die Möglichkeit, dass dasecho
nicht erreicht wird, obwohl essome_test
zurückgegeben wirdtrue
. Der Programmierer wollte erkennen, wann$result
noch nie eingestellt wurde, aber PHP erlaubt es ihnen nicht.Es gibt jedoch andere Probleme mit diesem Ansatz, die deutlich werden, wenn Sie eine äußere Schleife hinzufügen:
Da
$result
es nie explizit initialisiert wird, nimmt es beim Bestehen des ersten Tests einen Wert an, sodass nicht festgestellt werden kann, ob nachfolgende Tests bestanden wurden oder nicht. Dies ist tatsächlich ein äußerst häufiger Fehler, wenn Variablen nicht richtig initialisiert werden.Um dies zu beheben, müssen wir etwas in der Zeile tun, in der ich kommentiert habe, dass etwas fehlt. Die naheliegendste Lösung besteht darin
$result
, einen "Endwert"some_function
festzulegen, der niemals zurückkehren kann. wenn das istnull
der Fall ist, funktioniert der Rest des Codes einwandfrei. Wenn es keinen natürlichen Kandidaten für einen Endwert gibt, weil ersome_function
einen extrem unvorhersehbaren Rückgabetyp hat (was an sich wahrscheinlich ein schlechtes Vorzeichen ist)$found
, könnte stattdessen ein zusätzlicher boolescher Wert verwendet werden, z .Gedankenexperiment eins: das
very_null
KonstantePHP könnte theoretisch eine spezielle Konstante - sowie
null
- zur Verwendung als Endwert hier bereitstellen ; vermutlich wäre es illegal, dies von einer Funktion zurückzugeben, oder es würde dazu gezwungen werdennull
, und dasselbe würde wahrscheinlich für die Übergabe als Funktionsargument gelten. Das würde diesen sehr spezifischen Fall etwas einfacher machen, aber sobald Sie sich entschieden haben, den Code neu zu faktorisieren - zum Beispiel um die innere Schleife in eine separate Funktion zu setzen - würde er unbrauchbar werden. Wenn die Konstante zwischen Funktionen übergeben werden könnte, könnten Sie nicht garantieren, dasssome_function
sie nicht zurückgegeben wird, sodass sie als universeller Terminalwert nicht mehr nützlich wäre.Das Argument zum Erkennen nicht initialisierter Variablen in diesem Fall läuft auf das Argument für diese spezielle Konstante hinaus: Wenn Sie den Kommentar durch einen anderen ersetzen
unset($result)
und diesen anders behandeln$result = null
, führen Sie einen "Wert" für ein$result
, der nicht weitergegeben werden kann und nur sein kann von bestimmten eingebauten Funktionen erkannt.Gedankenexperiment zwei: Zuweisungszähler
Eine andere Art, darüber nachzudenken, was der Letzte
if
fragt, ist: "Hat irgendetwas eine Aufgabe gemacht$result
?" Anstatt es als einen besonderen Wert von zu betrachten$result
, könnten Sie sich dies vielleicht als "Metadaten" über die Variable vorstellen, ähnlich wie Perls "Variable Tainting". Also anstattisset
Sie es nennen könntehas_been_assigned_to
, und nichtunset
,reset_assignment_state
.Aber wenn ja, warum bei einem Booleschen aufhören? Was ist, wenn Sie wissen möchten, wie oft der Test bestanden wurde ? Sie können Ihre Metadaten einfach auf eine Ganzzahl erweitern und haben
get_assignment_count
undreset_assignment_count
...Offensichtlich würde das Hinzufügen eines solchen Merkmals einen Kompromiss in Bezug auf Komplexität und Leistung der Sprache haben, so dass es sorgfältig gegen seinen erwarteten Nutzen abgewogen werden müsste. Wie bei einer
very_null
Konstante wäre sie nur unter sehr engen Umständen nützlich und wäre ähnlich widerstandsfähig gegen Re-Factoring.Die hoffentlich offensichtliche Frage ist, warum die PHP-Laufzeit-Engine im Voraus davon ausgehen sollte, dass Sie solche Dinge im Auge behalten möchten, anstatt sie explizit mit normalem Code ausführen zu lassen.
quelle
Manchmal verliere ich mich ein wenig, um herauszufinden, welche Vergleichsoperation in einer bestimmten Situation verwendet werden soll.
isset()
gilt nur für nicht initialisierte oder explizit nullwerte. Das Übergeben / Zuweisen von Null ist eine gute Möglichkeit, um sicherzustellen, dass ein logischer Vergleich wie erwartet funktioniert.Trotzdem ist es ein wenig schwierig, darüber nachzudenken. Hier ist eine einfache Matrix, in der verglichen wird, wie unterschiedliche Werte durch unterschiedliche Operationen bewertet werden:
Um auf den Tisch zu passen, habe ich die Etiketten etwas komprimiert:
$a;
bezieht sich auf eine deklarierte, aber nicht zugewiesene Variable$a = null;
$a = [];
$a = 0;
$a === null
isset($a)
empty($a)
$a ? true : false
Alle Ergebnisse sind boolesch,
true
werden gedruckt undfalse
weggelassen.Sie können die Tests selbst ausführen. Überprüfen Sie diese Liste:
https://gist.github.com/mfdj/8165967
quelle
"0"
zur Vollständigkeit und Klarheit derempty
Operation zur Tabelle hinzufügenSie können das kompakte Sprachkonstrukt verwenden, um die Existenz einer Nullvariablen zu testen. Nicht vorhandene Variablen werden im Ergebnis nicht angezeigt, während Nullwerte angezeigt werden.
Im Fall Ihres Beispiels:
Natürlich können Sie für Variablen im globalen Bereich auch array_key_exists () verwenden.
Übrigens würde ich Situationen wie die Pest vermeiden, in denen es einen semantischen Unterschied zwischen einer nicht existierenden Variablen und einer Variablen mit einem Nullwert gibt. PHP und die meisten anderen Sprachen glauben einfach nicht, dass es das gibt.
quelle
NULL
. SemantischNULL
sollte "keine Ressource" bedeuten, aber das Nichtdefinieren einer Variablen ist ein Programmiererfehler.undefined
undnull
so selten brauchte, dass ich sie nicht vermisse. IMHO ist die Hauptverwendung fürundefined
"Programmiererfehler in einer nicht strengen Sprache". Wenn ich in einer strengen Sprache einen bestimmten Zustand für benötigeclient did not state a value
, erkläre ich einen der Situation entsprechenden Wert und teste ihn. Im schlimmsten Fall muss eine separate Flag-Variable hinzugefügt werden. Aber das selten zu tun ist besser, als IMMER mit ZWEI verschiedenen Nicht-Wert-Zuständen fertig zu werden !!NULL erklären, logisch denken
Ich denke, die offensichtliche Antwort auf all dies ist ... Initialisieren Sie Ihre Variablen nicht als NULL, sondern als etwas, das für das relevant ist, was sie werden sollen.
Behandle NULL richtig
NULL sollte als "nicht existierender Wert" behandelt werden, was die Bedeutung von NULL ist. Die Variable kann nicht als in PHP vorhanden klassifiziert werden, da nicht mitgeteilt wurde, um welche Art von Entität es sich handelt. Es kann auch nicht existieren, also sagt PHP nur "Gut, es tut es nicht, weil es sowieso keinen Sinn hat und NULL ist meine Art, dies zu sagen".
Ein Argument
Lassen Sie uns jetzt streiten. "Aber NULL ist wie 0 oder FALSE oder '' zu sagen.
Falsch, 0-FALSE- '' werden immer noch als leere Werte klassifiziert, aber sie werden als Werttyp oder vorgegebene Antwort auf eine Frage angegeben. FALSE ist die Antwort auf Ja oder Nein, '' ist die Antwort auf den Titel, den jemand eingereicht hat, und 0 ist die Antwort auf Menge oder Zeit usw. Sie werden als eine Art von Antwort / Ergebnis festgelegt, die sie als festgelegt gültig macht.
NULL ist einfach keine Antwort, es sagt uns nicht Ja oder Nein und es sagt uns nicht die Zeit und es sagt uns nicht, dass eine leere Zeichenfolge gesendet wurde. Das ist die Grundlogik für das Verständnis von NULL.
Zusammenfassung
Es geht nicht darum, verrückte Funktionen zu erstellen, um das Problem zu umgehen, sondern nur darum, wie Ihr Gehirn NULL betrachtet. Wenn es NULL ist, nehmen Sie an, dass es nicht als irgendetwas festgelegt ist. Wenn Sie Variablen vordefinieren, definieren Sie sie je nach Art der Verwendung, die Sie für sie beabsichtigen, als 0, FALSE oder "" vordefinieren.
Fühlen Sie sich frei, dies zu zitieren. Es ist aus meinem logischen Kopf :)
quelle
isset($a['x'])
die Ihnen falsch sagt, wenn siex
null sind, und dennoch in ...count($a)
angezeigtcompact
wird. Funktioniert für alle festgelegten Variablen, einschließlichnulls
und so weiter.Objekteigenschaften können von property_exists auf Existenz überprüft werden
Beispiel aus einem Unit Test:
quelle
Als Ergänzung zu greatbigmassives Diskussion darüber, was NULL bedeutet , was "die Existenz einer Variablen" tatsächlich bedeutet.
In vielen Sprachen müssen Sie jede Variable explizit deklarieren, bevor Sie sie verwenden . Dies kann seinen Typ bestimmen, aber was noch wichtiger ist, es erklärt seinen Umfang . Eine Variable "existiert" überall in ihrem Geltungsbereich und nirgendwo außerhalb - sei es eine ganze Funktion oder ein einzelner "Block".
Innerhalb ihres Bereichs weist eine Variable einer Bezeichnung, die Sie als Programmierer ausgewählt haben , eine Bedeutung zu . Außerhalb seines Geltungsbereichs ist dieses Etikett bedeutungslos (ob Sie dasselbe Etikett in einem anderen Geltungsbereich verwenden, ist grundsätzlich irrelevant).
In PHP müssen Variablen nicht deklariert werden - sie werden lebendig, sobald Sie sie benötigen. Wenn Sie zum ersten Mal in eine Variable schreiben, weist PHP dieser Variablen einen Speichereintrag zu. Wenn Sie aus einer Variablen lesen, die derzeit keinen Eintrag hat, betrachtet PHP diese Variable als wertvoll
NULL
.Automatische Codequalitätsdetektoren warnen Sie jedoch im Allgemeinen, wenn Sie eine Variable verwenden, ohne sie zuerst zu "initialisieren". Erstens hilft dies dabei, Tippfehler zu erkennen, z. B. das Zuweisen von,
$thingId
aber das Lesen von$thing_id
; aber zweitens zwingt es Sie, den Umfang zu betrachten, über den diese Variable Bedeutung hat, genau wie es eine Deklaration tun würde.Jeder Code, der sich darum kümmert, ob eine Variable "existiert", ist Teil des Gültigkeitsbereichs dieser Variablen. Unabhängig davon, ob sie initialisiert wurde oder nicht, haben Sie als Programmierer dieser Bezeichnung an dieser Stelle des Codes eine Bedeutung gegeben. Da Sie es verwenden, muss es in gewissem Sinne "existieren", und wenn es existiert, muss es einen impliziten Wert haben. In PHP ist dieser implizite Wert
null
.Aufgrund der Funktionsweise von PHP ist es möglich, Code zu schreiben, der den Namespace vorhandener Variablen nicht als Bereich von Bezeichnungen behandelt, denen Sie eine Bedeutung gegeben haben, sondern als eine Art Schlüsselwertspeicher. Sie können beispielsweise Code wie folgt ausführen :
$var = $_GET['var_name']; $$var = $_GET['var_value'];
. Nur weil du kannst, heißt das nicht, dass es eine gute Idee ist.Es stellt sich heraus, dass PHP Schlüsselwertspeicher, sogenannte assoziative Arrays, viel besser darstellen kann. Obwohl die Werte eines Arrays wie Variablen behandelt werden können, können Sie auch Operationen für das gesamte Array ausführen. Wenn Sie ein assoziatives Array haben, können Sie mit testen, ob es einen Schlüssel enthält
array_key_exists()
.Sie können Objekte auch auf ähnliche Weise verwenden und Eigenschaften dynamisch festlegen. In diesem Fall können Sie sie
property_exists()
genauso verwenden. Natürlich, wenn Sie eine Klasse definieren, können Sie erklären , welche Eigenschaften es hat - Sie können sogar die Wahl zwischenpublic
,private
undprotected
Anwendungsbereich.Obwohl es einen technischen Unterschied zwischen einer Variablen (im Gegensatz zu einem Array-Schlüssel oder einer Objekteigenschaft) gibt, die nicht initialisiert wurde (oder die explizit angegeben wurde
unset()
), und einer Variablennull
, deren Wert ist , gibt jeder Code, der diesen Unterschied für sinnvoll hält verwendet Variablen so, dass sie nicht verwendet werden sollen.quelle
isset()
verhält es sich so?".null
. Ob dieser Wert existiert, bevor Sie ihn betrachten, ist eine Frage für Philosophen, aber was beobachtbares Verhalten betrifft, ist der Wert konsistentnull
.isset
prüft, ob die Variable gesetzt ist und wenn ja, ob ihr Wert nicht NULL ist. Der letzte Teil fällt (meiner Meinung nach) nicht in den Geltungsbereich dieser Funktion. Es gibt keine angemessene Problemumgehung, um festzustellen, ob eine Variable NULL ist, weil sie nicht festgelegt ist oder weil sie explizit auf NULL festgelegt ist .Hier ist eine mögliche Lösung:
Eine andere Problemumgehung besteht darin, die Ausgabe von
get_defined_vars()
:quelle
Ich stimme Ihrer Argumentation zu NULL nicht zu , und zu sagen, dass Sie Ihre Einstellung zu NULL ändern müssen, ist einfach seltsam.
Ich denke, isset () wurde nicht richtig entworfen. Isset () sollte Ihnen mitteilen, ob die Variable gesetzt wurde, und es sollte sich nicht um den tatsächlichen Wert der Variablen handeln.
Was ist, wenn Sie Werte überprüfen, die von einer Datenbank zurückgegeben wurden, und eine der Spalten einen NULL-Wert hat? Sie möchten dennoch wissen, ob dieser vorhanden ist, auch wenn der Wert NULL ist. Nein, vertrauen Sie isset () hier nicht.
gleichfalls
isset () sollte so konzipiert sein, dass es so funktioniert:
Auf diese Weise überlassen wir es dem Programmierer, die Typen zu überprüfen, und überlassen es nicht isset (), anzunehmen, dass es nicht vorhanden ist, weil der Wert NULL ist - es ist einfach dummes Design
quelle
array_key_exists
. Sie sollten sich niemals in einer Situation befinden, in der Sie zur Laufzeit nicht wissen, ob eine tatsächliche Variable vorhanden ist.register_globals
, dann ist Ihre Antwort keine Änderung anisset()
. Das PHP-Handbuch erwähnt "es ist im Allgemeinen eine gute Programmierpraxis, Variablen zuerst zu initialisieren", was gelöst wirdregister_globals
eher zur Entwurfszeit als zur Laufzeit gelöst wird. Es gibt auch einen FAQ-Eintrag , der eineunregister_globals()
Funktion zur Bearbeitung zur Laufzeit enthält.Ich werde dem schnell zwei Cent hinzufügen. Ein Grund für dieses verwirrende Problem ist, dass dieses Szenario das gleiche Ergebnis zu liefern scheint, wenn die Fehlerberichterstattung nicht vollständig ist:
Sie könnten von diesem Ergebnis annehmen, dass der Unterschied zwischen
$a = null
und nicht definiert$b
nichts ist.Kurbelfehlermeldung:
Hinweis: Es wurde ein undefinierter Variablenfehler ausgegeben, aber der Ausgabewert von
var_dump
ist immer nochNULL
.PHP hat offensichtlich die interne Fähigkeit, zwischen einer Nullvariablen und einer undefinierten Variablen zu unterscheiden. Es scheint mir, dass es eine eingebaute Funktion geben sollte, um dies zu überprüfen.
Ich denke, die akzeptierte Antwort ist größtenteils gut, aber wenn ich sie implementieren würde, würde ich einen Wrapper dafür schreiben. Wie bereits in dieser Antwort erwähnt , muss ich zustimmen, dass ich nicht auf eine Situation gestoßen bin, in der dies ein Problem war. Ich scheine fast immer in einem Szenario zu enden, in dem meine Variablen entweder gesetzt und definiert sind oder nicht (undefiniert, nicht gesetzt, null, leer usw.). Um nicht zu sagen, dass eine solche Situation in Zukunft nicht mehr auftreten wird, aber da es ein ziemlich einzigartiges Problem zu sein scheint, wundert es mich nicht, dass sich die PHP-Entwickler nicht die Mühe gemacht haben, dies zu tun.
quelle
Wenn ich Folgendes ausführe:
Ich erhalte eine Fehlermeldung:
Wenn ich Folgendes ausführe:
Ich verstehe den Fehler nicht.
Wenn ich eine Variable habe, die gesetzt werden soll, mache ich normalerweise Folgendes.
oder
Auf diese Weise kann ich später im Skript sicher $ foo verwenden und wissen, dass es "gesetzt" ist und standardmäßig null ist. Später kann ich
if ( is_null($foo) ) { /* ... */ }
wenn ich muss und sicher wissen, dass die Variable existiert, auch wenn sie null ist.Die vollständige Isset-Dokumentation enthält etwas mehr als nur das, was ursprünglich eingefügt wurde. Ja, es gibt false für eine Variable zurück, die zuvor festgelegt wurde, jetzt aber null ist, aber es gibt auch false zurück, wenn eine Variable noch nicht festgelegt wurde (je) und für jede Variable, die als nicht festgelegt markiert wurde. Es wird auch darauf hingewiesen, dass das NULL-Byte ("\ 0") nicht als null betrachtet wird und true zurückgibt.
quelle
Versuchen Sie es mit
Es scheint, dass eine Variable nur dann nicht gesetzt wird, wenn sie spezifisch nicht gesetzt ist ($ v). Es hört sich so an, als ob Ihre Bedeutung von "Existenz" sich von der Definition von PHP unterscheidet. NULL ist sicherlich vorhanden, es ist NULL.
quelle
Ich muss sagen, dass ich in all meinen Jahren der PHP-Programmierung nie ein Problem mit der
isset()
Rückgabe von false für eine Nullvariable hatte. OTOH, ich habe Probleme mitisset()
einem Fehler bei einem Null-Array-Eintrag festgestellt - aberarray_key_exists()
funktioniert in diesem Fall ordnungsgemäß.Zum Vergleich definiert Icon eine nicht verwendete Variable explizit als Rückgabe,
&null
sodass Sie den is-null-Test in Icon verwenden, um auch nach einer nicht gesetzten Variablen zu suchen. Das macht die Sache einfacher. Andererseits hat Visual BASIC mehrere Zustände für eine Variable, die keinen Wert hat (Null, Leer, Nichts, ...), und Sie müssen häufig nach mehr als einem suchen. Dies ist als Fehlerquelle bekannt.quelle
Gemäß dem PHP-Handbuch für die Funktion empty () gilt: "Bestimmen Sie, ob eine Variable als leer betrachtet wird. Eine Variable wird als leer betrachtet, wenn sie nicht vorhanden ist oder wenn ihr Wert gleich FALSE ist. Leer () generiert keine Warnung, wenn die Variable existiert nicht. " (Meine Betonung.) Das bedeutet, dass die Funktion empty () gemäß dem Titel Frage als "beste Möglichkeit zum Testen der Existenz einer Variablen in PHP" gelten sollte.
Dies ist jedoch nicht gut genug, da die Funktion empty () durch eine vorhandene Variable getäuscht werden kann, die auf NULL gesetzt ist.
Ich unterbreche meine frühere Antwort, um etwas Besseres zu präsentieren, da dies weniger umständlich ist als meine ursprüngliche Antwort (die zum Vergleich auf diese Unterbrechung folgt).
Zwei einfache Codezeilen können die obige Funktion verwenden, um festzustellen, ob eine Variable undefiniert ist:
Sie können diesen beiden Zeilen mit allen geeigneten Elementen folgen, z. B. diesem Beispiel:
Ich wollte den Aufruf von ob_start () und ($ testvar === null) innerhalb der Funktion setzen und die Variable einfach an die Funktion übergeben, aber es funktioniert nicht. Selbst wenn Sie versuchen, die Variable "Referenz übergeben" der Variablen zu verwenden, wird die Variable definiert, und die Funktion kann niemals erkennen, dass sie zuvor undefiniert war. Was hier vorgestellt wird, ist ein Kompromiss zwischen dem, was ich tun wollte und dem, was tatsächlich funktioniert.
Das Vorstehende impliziert, dass es eine andere Möglichkeit gibt, immer zu vermeiden, dass die Fehlermeldung "Undefinierte Variable" angezeigt wird. (Die Annahme hier ist, dass Sie verhindern möchten, dass eine solche Meldung getestet wird, um festzustellen, ob eine Variable undefiniert ist.)
Rufen Sie einfach diese Funktion auf, bevor Sie etwas mit Ihrer $ testvar tun:
Der Wert der neu instanziierten Variablen wird natürlich auf null gesetzt!
(Unterbrechung endet)
Nach einigem Lernen und Experimentieren funktioniert hier garantiert etwas:
Die Erklärung: Eine Variable $ er wird mit dem Standardwert "no error" initialisiert. Eine "Handlerfunktion" ist definiert. Wenn die $ testvar (die Variable, die wir wissen möchten, ob sie undefiniert ist oder nicht) den vorläufigen Funktionstest empty () besteht, führen wir den gründlicheren Test durch. Wir rufen die Funktion set_error_handler () auf, um die zuvor definierte Handlerfunktion zu verwenden. Dann führen wir einen einfachen Identitätsvergleich mit $ testvar durch, der, wenn er nicht definiert ist, einen Fehler auslöst. Die Handlerfunktion erfasst den Fehler und prüft speziell, ob der Grund für den Fehler darin besteht, dass die Variable undefiniert ist. Das Ergebnis wird in die Fehlerinformationsvariable $ er eingefügt, die wir später testen können, um zu tun, was wir wollen, da wir sicher wissen, ob $ testvar definiert wurde oder nicht. Da wir die Handlerfunktion nur für diesen eingeschränkten Zweck benötigen, stellen wir die ursprüngliche Fehlerbehandlungsfunktion wieder her. Die Funktion "myHndlr" muss nur einmal deklariert werden. Der andere Code kann an die für $ testvar oder jede andere Variable, die wir auf diese Weise testen möchten, geeigneten Stellen kopiert werden.
quelle
inst
Funktion ähnelt im Grunde dem@
Fehlerunterdrückungsoperator: "Ich weiß, dass ich hier etwas falsch mache, aber ich möchte nur, dass diese Nachricht verschwindet, ohne die Funktionsweise meines Codes in irgendeiner Weise zu ändern."Ich denke, die einzige vollständige Lösung besteht darin , Mitteilungen mit zu melden
Sie müssen jedoch alle Benachrichtigungen korrigieren, die unter anderem durch undefinierte Variablen, Konstanten, Array-Schlüssel und Klasseneigenschaften generiert werden. Sobald Sie dies getan haben, müssen Sie sich keine Gedanken mehr über den Unterschied zwischen null und nicht deklarierten Variablen machen, und die Mehrdeutigkeit verschwindet.
Aktivieren der Benachrichtigungsberichterstattung möglicherweise nicht in allen Situationen eine gute Alternative, aber es gibt gute Gründe, dies zu aktivieren:
Warum sollte ich E_NOTICE-Fehler beheben?
In meinem Fall war es mehr als ein Jahr, in einem Projekt ohne es zu arbeiten, aber ich war es gewohnt, vorsichtig mit der Deklaration von Variablen umzugehen, sodass der Übergang schnell ging.
quelle
Der einzige Weg zu wissen, ob eine Variable im aktuellen Bereich definiert
$GLOBALS
ist ( nicht vertrauenswürdig), istarray_key_exists( 'var_name', get_defined_vars() )
.quelle
Ich bevorzuge es, nicht leer als beste Methode zu verwenden, um zu überprüfen, ob eine Variable existiert, die a) existiert und b) nicht null ist.
quelle
empty()
nicht zu überprüfen , ob die Variable Null ist, es überprüft , ob es falsch-y ist, beispielsweise nicht einer der""
(eine leere Zeichenkette),0
(0 als eine ganze Zahl),0.0
(0 als float),"0"
(0 als String)NULL
,FALSE
,array()
(ein leeres Array) und$var;
(eine deklarierte Variable, jedoch ohne Wert). Angenommen, Sie haben ein erforderliches Funkfeld in einer Form mit zwei Eingängen mit den Werten0
und1
. Wenn Sieempty()
zur Validierung verwenden und der Benutzer0
dasjenige auswählt , wird versehentlich der Fehler "Erforderliches Feld darf nicht leer sein" angezeigt. Siehe das Handbuch php.net/manual/en/function.empty.php