2010-12-14 8 views
7

Ist es in Ordnung, @ zu verwenden, wenn ein möglicherweise fehlender Wert aus einem PHP-Array extrahiert wird? Beispiel:

$value = @$array['possibly_missing_key']; 

Das gewünschte Verhalten:

if (isset($array['possibly_missing_key'])) { 
    $value = $array['possibly_missing_key']; 
} else { 
    $value = null; 
} 

ich wissen will, bevor das Nutzungsmuster zu verbreiten.

+5

Bin ich der einzige, der [array_key_exists] (http://ca.php.net/manual/en/function.array-key-exists.php) anstelle von isset für diese Art von Sachen verwendet? – AlexV

+1

* (sidenote) * 'isset' erkennt keinen * wahrscheinlich fehlenden Schlüssel *. Verwenden Sie dafür 'array_key_exists'. Versuchen Sie '$ arr = array ('notMissing' => NULL);' mit 'isset' – Gordon

+1

@AlexV @Gordon: Ich glaube nicht, dass es wichtig ist, da der Standardwert sowieso NULL ist: P – BoltClock

Antwort

8

Der Operator @ unterdrückt Fehlermeldungen, und die Verwendung potenziell richtet Ihren Code für andere Fehler und unerwartetes Verhalten ein, die am Ende schwer zu finden sind. Es ist also sicher ein Antipattern.

Daher würde ich das zweite Bit sehr bevorzugen. Es macht es viel klarer

  • , dass es nicht in der Anordnung vorhanden sein können, und
  • was der Standardwert ist, wenn es nicht vorhanden
  • ist

Um es Ihnen die ternären können prägnanter zu machen bedingter Operator ?:, wie in Mark Baker's answer zu sehen. Etwas weniger Code und mehr Symbole, aber die Bedeutung ist gut erkannt.

+1

Ich verstehe. Die Verwendung von safe @ könnte andere Entwickler dazu verleiten, sie an falschen Orten zu verwenden. –

4

Oder

$value = (isset($array['possibly_missing_key'])) ? $array['possibly_missing_key']: null; 
+1

+1 Wenn Sie PHP> = 5.3 verwenden, können Sie die neue kürzere Form verwenden: 'isset ($ array ['possible_missing_key'])?: Null;' – webbiedave

+4

@webbiedave: Nein, das würde das Ergebnis von 'isset (.. .) 'und nicht der tatsächliche Array-Wert. – BoltClock

+0

@webbiedave: Wird diese kurze Version in diesem Fall funktionieren? Wird es nicht den Wert von "isset()" (dh wahr oder falsch) zurückgeben, anstatt die Variable selbst? – Spudley

1

Warnungen ignorieren, ist auf jeden Fall ein Antipattern; Also ja, es ist ein Anti-Muster (und ich kann garantieren, dass, wenn du lernst, Warnungen zu unterdrücken, einer von ihnen zurückkommt und dich in den hinteren Teil beißt, wenn nicht schlimmer).

Auch während die zweite Version ausführlicher ist, gibt es der nicht initialisierten Variable einen bekannten Zustand (oder kann verwendet werden, um das Problem zu behandeln, wenn die Variable gefüllt werden soll).

1

Die dritte Option:

$value = (isset($array['key']) ? $array['key'] : null); 

Ich weiß, dass dies nicht direkt die Frage beantworten; Ich hätte es als Kommentar formuliert, außer dass es wirklich formatiert werden musste.

Die Idee hier ist, dass, wenn Sie versuchen, Ihren Code kürzer zu machen, indem Sie einen Einliner statt eines Wenn-Else-Block verwenden, dann können Sie es immer noch in eine prägnante Einzeiler mit einem ternären Operator, Ihnen das Beste aus beiden Welten geben.

+0

Das ist nicht wirklich eine dritte Option, das ist eine andere Formatierung von Option 2 (da sie funktional identisch ist). Würden Sie sagen, dass 'if (x) {something}' und 'if (! X) {} else {something}' zwei verschiedene Lösungen sind, weil sie nicht auf die gleiche Weise geschrieben sind? – Piskvor

+0

@Piskvor - hm, das ist ein bisschen wählerisch. Es ist eine andere Syntax, also würde ich sagen, dass es eine dritte Option ist, auch wenn sie tatsächlich mit seinem ursprünglichen Code identisch ist. Aber mein Punkt war es, einen One-Liner-Weg zu bieten, ohne '@' zu verwenden, da dies der Punkt zu sein schien, an dem seine Frage lag. – Spudley

+0

Nun, ich bin irgendwie auf dem Zaun darüber. Die Syntax ist anders, aber es macht dasselbe. Sie haben Recht, dass es weniger ausführlich ist, während die Funktionalität beibehalten wird. (Ich denke, es sagt mehr über meine nitpicking drängt als über die Frage zur Hand;)) – Piskvor

1

Der zweite Codeblock (oder Mark Bakers Alternative, der genau gleich funktioniert) ist besser. Ich bin mir über PHP nicht ganz sicher, aber in vielen anderen Programmiersprachen würde das einfache Ignorieren einer Variablen einen Fehler auslösen. Zumindest mit dem zweiten Block initialisierst du die Variable auf einen Wert oder Speicherplatz.

Die Fehlerunterdrückung sollte häufiger verwendet werden, wenn Sie erwarten, dass eine Funktion einen erwarteten Fehler im Endprodukt verursacht (dies ist jedoch meistens nicht der Fall).

Viel Glück!
Dennis M.

6

Eigentlich ist die isset Variante das Anti-Pattern.Wenn Sie einfach isset($var)?$var:NULL mit der Absicht verwenden, den "Fehler" zu unterdrücken, dann haben Sie nichts erreicht, anstatt die richtige Syntax zum Unterdrücken von Fehlern zu verwenden. Es hat das gleiche Ergebnis, ist aber weniger lesbar.

Die Leute streiten sich wegen der wahrgenommenen "Sauberkeit" und weil die Verwendung von Isset eine Mikrooptimierung ist. Vermeiden @ und Verwendung von Isset als syntaktischer Salzersatz ist nur Cargocult Programmierung.

+0

"Cargo-Kult-Programmierung" lol – BoltClock

+0

Danke für die Erwähnung einer Contrarian Ansicht. –

+0

@IvoDanihelka: Eigentlich möchte ich mich zurückziehen, und fügen Sie eine große ** alles hängt davon ab **. Es gibt kein einziges Muster, das allen Anwendungsfällen entspricht. Seien Sie flexibel und nicht religiös gegenüber isset/@, verwenden Sie das beste Werkzeug für Ihre Aufgabe. – mario