Warum hassen viele PHP-Entwickler die Verwendung von isset () und / oder einer ähnlich defensiven PHP-Funktion wie empty ()?

27

Bei Stackoverflow tritt dieses Problem immer wieder auf:

Sogar Pekka (der viele solide PHP-Ratschläge bietet) ist gegen das gefürchtete E_NOTICEMonster gestoßen und hat sich eine bessere Lösung erhofft als die Verwendung von isset(): isset () und empty () machen Code hässlich

Persönlich verwalte ich isset()und empty()an vielen Stellen den Fluss meiner Anwendungen. Beispielsweise:

public function do_something($optional_parameter = NULL) {
    if (!empty($optional_parameter)) {
        // do optional stuff with the contents of $optional_parameter
    }
    // do mandatory stuff
}  

Sogar ein einfaches Snippet wie dieses:

if (!isset($_REQUEST['form_var'])) {
    // something's missing, do something about it.
}

scheint mir sehr logisch. Es sieht nicht nach Aufblähen aus, es sieht aus wie stabiler Code. Aber viele Entwickler starten ihre Anwendungen mit E_NOTICEaktivierten, entdecken eine Menge frustrierender "nicht initialisierter Array-Index" -Nachrichten und verziehen dann das Gesicht, wenn sie nach definierten Variablen suchen und ihren Code mit "verunreinigen" isset().

Ich gehe davon aus, dass andere Sprachen die Dinge anders angehen. Aus Erfahrung ist JavaScript nicht so höflich wie PHP. Eine undefinierte Variable stoppt normalerweise die Ausführung des Skripts. Auch (gesprochen von Unerfahrenheit ) Ich bin sicher , dass Sprachen wie C / C ++ würde einfach zu kompilieren verweigern.

Sind PHP-Entwickler nur faul? (Ich spreche nicht von Ihnen, Pekka. Ich weiß, dass Sie eine alte Anwendung überarbeitet haben.) Oder behandeln andere Sprachen undefinierte Variablen eleganter, als wenn der Programmierer zuerst überprüfen muss, ob sie definiert sind?

(Ich weiß, dass es E_NOTICEneben undefinierten Variablen noch andere Meldungen gibt , aber diese scheinen die ärgerlichsten zu sein.)

Nachtrag
Aus den bisherigen Antworten geht hervor, dass ich nicht der einzige bin, der denkt, dass isset()Code nicht aufgebläht ist. Ich frage mich jetzt, ob es Probleme mit Programmierern in anderen Sprachen gibt, die diese wiederholen. Oder ist das nur eine Frage der PHP-Kultur?

Stephen
quelle
4
Leider habe ich gesehen, dass PHP-Entwickler auch mit deaktivierten "Warnungen" arbeiten.
Viper_Sb
Autsch. Das ist traurig
Stephen
1
Da ich kein PHP-Benutzer bin, frage ich mich: Warum müssen Sie nach undefinierten Variablen suchen?
Winston Ewert
2
@ Winston: Das Problem mit PHP (im Gegensatz zu vielen anderen Sprachen) ist, dass PHP viele Konfigurationskombinationen zulässt. Zum Beispiel kann der Programmierer entscheiden, Warnungen, Hinweise und Verfallsbenachrichtigungen zu ignorieren. Erfahrene Entwickler werden mit error_reporting arbeiten, um alles zu melden. PHP hat auch viele Funktionen, die Fehler auslösen und Statuscodes zurückgeben, anstatt Ausnahmen auszulösen. Man muss mit der Sprache sehr vertraut sein, um defensiv und erfolgreich codieren zu können. Viele andere Sprachen erlauben keine Auswahl. Streng ist normalerweise die Standard- und einzige Option.
Wil Moore III
1
Ich mag isset () nicht, weil es ausführlich ist. Eine bessere Form von @ wäre eine schöne Alternative.
Kzqai

Antworten:

34

Ich codiere nach E_STRICTund sonst nichts.

Die Verwendung von Leer- und Isset-Prüfungen macht Ihren Code nicht hässlich, sondern ausführlicher. In meinen Augen, was ist das Schlimmste, was passieren kann, wenn man sie benutzt? Ich gebe noch ein paar Zeichen ein.

Verse die Konsequenzen ihrer Nichtverwendung, zumindest Warnungen.

Josh K
quelle
7
Meine Entwicklungsumgebung ist auch E_STRICT. Ich unterdrücke alle Fehler in der Produktion, aber das soll nur sicherstellen, dass in der Entwicklung nichts an mir vorbei rutscht.
Stephen
2
+1 Josh, mir geht es genauso. Wenn Sie in E_STRICT programmieren, wissen Sie , dass Sie in Ihrem Code niemals Überraschungen erleben werden. Nur so zu fliegen, imo.
EricBoersma
3
@Stephen: Fehler für die Produktion immer ausschalten. Das ist aber nur ein Sicherheitsnetz. Entwicklung sollte (IMO) immer sein E_STRICT. Schreiben Sie Code und beheben Sie alle Warnungen und Fehler.
Josh K
Willst du mich papageien? :)
Stephen
@ Stephen: Ich stimme zu. :)
Josh K
17

Ich denke, die Hinweise auf unbekannte Elemente sind ein Designfehler in PHP. Ich bin nicht sicher , dann ist es möglich , den Fehler jetzt zu beheben, aber es produziert eine Menge Standardcode wie if(isset($foo['abc']) && $foo['abc'] == '123')- dieser Code soll nicht haben isset, da die Absicht , wenn es zu überprüfen ist , ist ‚123‘ in bestimmten Stelle $foound wenn es nichts gibt es definitiv nicht "123". Der einzige Grund, warum Sie dort doppelt so viel Code schreiben müssen, ist dieser unglückliche Designfehler in PHP. Und Hinweise sind in PHP leider sehr teuer, daher ist das Deaktivieren keine Option für den Code, bei dem die Leistung von Bedeutung ist.

Also ja, es macht den Code meiner Meinung nach hässlich und nervt mich. Und es liegt nicht an mangelnder Erfahrung - ich benutze PHP seit 1998 und erinnere mich, als es eine .php3Erweiterung gab und es bedeutete "es ist nicht PHP 2". Vielleicht bin ich faul :) Aber Faulheit - zumindest eine bestimmte Art - ist eine Tugend für einen Programmierer.

Andererseits ist eine gültige Verwendung von issetund empty- genau wie in der ursprünglichen Veröffentlichung - in Ordnung. Ich denke nur, PHP ist zu eifrig in Bezug auf Warnungen an Orten, an denen sie isset/emptynicht wirklich benötigt werden.

STASM
quelle
3
Recht. Es ist eine Frage der Ausführlichkeit. $eg = isset($_GET['eg'])? $_GET['eg'] : null;ist lächerlich wortreich. Ich wünschte wirklich, es gäbe einen anderen Operator, der nicht per se "Fehlerunterdrückung" ist, der für die Kurzbedeutung von $eg = @$_GET['eg'];"Akzeptiere-die-Nichtexistenz-dieses-Array-Schlüssels-als-Null" steht. Ich neige heutzutage dazu, eine kurze Funktion zu verwenden.
Kzqai
7
Einverstanden. 4 Jahre später, geben Sie den Null Coalesce Operator ein: wiki.php.net/rfc/isset_ternary und geben Sie uns$eg = $_GET['eg'] ?? null;
Steve
Oder machen Sie es jetzt einfach mit dem Fehlerunterdrückungsoperator, z $eg = @$_GET['eg'] ?: null;. Ich verwende es im Allgemeinen nicht, aber in diesem Fall erwarten wir diesen Fehler ausdrücklich und beschließen, ihn zu ignorieren. Es ist ein Zeichen länger als die Null-Vereinigung und es ist nicht so gut (es unterdrückt alle Fehler, und es kann sein, dass ein ArrayAccess funky Sachen macht, nicht nur ein Array), aber im Allgemeinen erledigt es den Job.
El Yobo,
12

Ich glaube, dass PHP als freie Sprache, die im Web interpretiert und verwendet wird, einen sehr hohen Anteil an nicht professionellen, ungeübten Programmierern hat, die nicht genau wissen, warum sie defensiv codieren sollten, und die Warnungen lediglich als einen weiteren unnötigen Fehler ansehen .

Ich höre diese Punkte ständig von Nachwuchsentwicklern und autodidaktischen Skriptcodierern:

  • Warum eine Variable initialisieren, wenn sie trotzdem entsteht?
  • Warum sollten wir prüfen, ob etwas existiert, bevor wir es verwenden?
  • Wenn ich @ als Präfix setze, wird mein Code dann repariert, warum kompliziert?

Wenn sie noch nie eine stark typisierte Sprache erlebt haben oder die Fallstricke von nicht deklarierten / nicht fundierten Variablen erlebt haben, dann sind sie davon überzeugt. Ich stelle fest, dass sie normalerweise nachgeben, sobald sie das Vergnügen erlebt haben, Code für ungefähr eine Stunde zu debuggen.

Der andere starke Faktor ist die Verwendung von PHP in der Webbranche, bei der es eher um den Durchsatz als um die Sicherheit und die Codequalität geht.

Orbling
quelle
10
"Ich glaube, PHP [...] hat einen sehr hohen Anteil an nicht-professionellen, ungeübten Programmierern." Als engagierter PHP-Entwickler kann ich Ihnen nicht mehr zustimmen. +1
Stephen
@Stephen Nun, ich programmiere in letzter Zeit hauptsächlich in PHP und jQuery, obwohl ich eine formale Ausbildung habe, aber der Code, den Sie als Profi ansehen, für den Sie verantwortlich sind, widerspricht manchmal dem Glauben. ;-)
Orbling
1
Ich denke, das ist ein echtes Problem mit PHP. Abgesehen von einigen Macken in der Sprache (die sie in jeder neuen Version langsam lösen), strahlt sie Amateurismus aus. Ich kann mir vorstellen, dass es manchmal frustrierend sein kann, ein professioneller PHP-Entwickler zu sein, weil man Sie mit dem Neffen des Chefs um die Ecke vergleicht.
Erik van Brakel
1
@Erik PHP war vor zehn Jahren ein ziemlich schlechter Verwandter von Perl. Es ist jetzt eine ziemlich vernünftig interpretierte Sprache, insbesondere für die Verwendung im Web. Es gibt einen Grund, warum Unternehmen wie Facebook es verwenden. Da es jedoch überall erhältlich ist, wird es vom Amateurset ausgiebig verwendet, was den Ruf beeinträchtigt.
Orbling
5

Ja, sie sind faul. Viele von ihnen sowieso ...

Leider ist die Mentalität vieler PHP-Codierer: "Es macht keinen Sinn, defensiv zu codieren, wenn Sie das gleiche Endergebnis schneller erhalten, indem Sie sich auf die Sprache verlassen, um Fehler zu behandeln, die durch fehlende Variablen usw. usw. verursacht werden." Ich weiß, ich habe mit mehreren von ihnen gearbeitet.

Sie sind in der Regel auch diejenigen, die sich auf mysteriöse Weise auf den Weg zu einem frühen Mittagessen machen, wenn ihr Mangel an korrekter Fehlerbehandlung und -meldung die Live-Server für mehrere Stunden ausschaltet ...

Gruffputs
quelle
5
-1 für die subjektive Meinung zu PHP-Codierern.
Josh K
4
@Josh, der seit 4 1/2 Jahren ein älterer PHP-Programmierer ist und seit 1999 PHP ein- und ausschaltet, fürchte ich, dass ich etwas subjektiv bin. Ich hätte mich qualifizieren sollen mit "Andererseits sind die erfahreneren PHP-Codierer nicht faul und machen die Dinge richtig" ...
Gruffputs
1
Das solltest du haben.
Josh K
5

Ich versuche, die Verwendung von isset () und empty () zu vermeiden, indem ich die Verwendung von Arrays als Datenübertragungsobjekte vermeide. Erstellen Sie eine Klasse, die so konfiguriert werden kann, dass sie einen begrenzten Satz von Eigenschaften mit vernünftigen Standardwerten akzeptiert, und überprüfen Sie die Eingabe für diese Eigenschaften. Es kann sogar die ArrayAccess-Schnittstelle implementieren, sodass Sie sie wie ein Array verwenden können. Auf diese Weise können Sie in Ihren Methodensignaturen auch Typhinweise verwenden, um Fehler abzufangen, wenn jemand versucht, den falschen Entitätstyp an Ihre Methode zu übergeben.

Aneurysma9
quelle
Ein sehr interessanter Ansatz.
Toby
2

Eine der in Frage gestellten Fragen ist meine, lassen Sie mich das wiederholen.

Viele Entwickler verwechseln das Vorhandensein von viel isset()als Qualitätsmerkmal. Es wirkt zuverlässig und wird von manchen sogar als Sicherheitsmerkmal angesehen.

Sie müssen jedoch berücksichtigen, dass PHP keine kompilierte Sprache ist. Es ist eine Skriptsprache mit einem dynamischen Typsystem. E_NOTICE-Fehler sind nur Fehler nach Namen. Und wenn viele von issetihnen mit der alleinigen Absicht verwendet werden , die Hinweise zu unterdrücken, codieren Sie tatsächlich nur gegen die Sprache .

Sind PHP-Entwickler nur faul?

Das ist in der Tat der Fall, wenn Sie eine Fülle von Hinweisen und Warnungen sehen. Viele Neulinge interessieren sich nicht für Mitteilungen, und es ist normalerweise das Ergebnis einer vollständig behinderten Person error_reporting(0).

Sie irren sich jedoch, dass andere Entwickler E_NOTICEs nicht erkannt haben, nur weil sie nicht @ oder isset-unterdrückt waren. Zumindest war das meine Absicht hinter der Frage der Aufbewahrungsschreiben . Sie sind nicht etwas loszuwerden, aber gelegentlich wichtige Debug-Informationen.

Wie bei allen Verallgemeinerungen führt die rücksichtslose Verwendung von isset nicht zu einem optimalen Code. Es ist wichtig zu unterscheiden , wo issetund emptynotwendig sind und wo sie sind syntaktische Salz .

Oder ist das nur eine Frage der PHP-Kultur?

Nein, undefinierte Variablen "Errors" sind nicht nur ein PHP-Problem. Bash, TCL und Perl oder JavaScript erlauben die Verwendung von undefinierten Variablen. Dieses immanente Sprachmerkmal wird dort jedoch nicht als Mangel angesehen. Es gibt ähnliche Sprachkonstrukte, um nach undefinierten Werten zu suchen. Sie werden jedoch nicht so häufig verwendet wie in PHP, da undef-Werte nicht als "Fehler" bezeichnet werden.

Mario
quelle
1

Interessant. Isset () verwende ich selten. Mein PHP-Code befindet sich selten in einem Zustand, in dem ich nicht weiß, ob überhaupt eine Variable gesetzt wurde. Auf jede verwendete GET- oder POST-Variable wird über eine Funktion zugegriffen, die sie standardmäßig bereitstellt, wenn sie nicht vorhanden ist. Standardwerte in Funktionsaufrufen werden normalerweise explizit auf 0 oder leere Zeichenfolgen festgelegt.

GroßmeisterB
quelle
+1. Die Übergabe an eine Funktion oder eine Klassenmethode ist eine gute Lösung. Ich eigentlich DO dies zu tun, aber in einer Prise meiner obigen Beispiele sehen immer noch sauber und un-aufgebläht zu mir.
Stephen
0

Ich benutze isset und leere viel. Aber meistens sind es Stellen, die Sie erwähnen, wie die Verarbeitung von $ _REQUEST, falls jemand mit den Parametern herumgespielt hat. In Fällen, in denen ich die Kontrolle über alle herumfliegenden Variablen habe, stelle ich fest, dass ich sie normalerweise nicht benötige.

Tesserex
quelle
0

Ich mag es nicht, isset zu verwenden, aber wenn es eine Menge Code gibt, der von einem anderen gemacht wird, dann kann es eine Rettungsgnade sein. Ich habe den folgenden Code geschrieben, um dieses Problem zu lösen. Statt isset () wird isseter ($ a, $ b) $ b zurückgeben, wenn $ a nicht definiert oder leer ist, oder die Funktion gibt eine Null zurück. Verbesserungen, willkommen:

//returns var or NULL (if undefined)
//$reserve optional second value is returned as $default if undefined
function isseter(&$default,&$reserve=NULL)
{
$default = isset($default) ? $default : NULL;
$reserve = isset($reserve) ? $reserve : NULL;
if ((!$default) && ($reserve)) $default=$reserve;
return $default;
}
bigal
quelle