Was ist der sauberste Weg, Validierungsfehler mit PHP zu behandeln?

8

Ich habe nach besseren Möglichkeiten für die Validierung gesucht, solange ich Webanwendungen entwickle. Es ist häufig notwendig, mehrere Validierungsfehler zu erfassen. Daher wollte ich wissen, ob es einen besseren Weg als den folgenden gibt.

Im Moment habe ich eine assert -Methode in einem Framework, das ich selbst entwickelt habe. Ein Beispiel für die Methode ist dies:

assert(($foo == 1), 'Foo is not equal to 1');

Wenn die Bedingung im ersten Argument falsch ist, wird die Fehlermeldung im zweiten Argument zu einem $errors -Array hinzugefügt (das in eine Klasse eingebettet ist (auf die unten mit $eh verwiesen wird), die Komfortfunktionen wie% bietet. co_de%).

Diese Methode funktioniert, ist aber in der Praxis unordentlich. Betrachten Sie diesen Code:

%Vor%

Dies ist etwas ziemlich häufig. Ich möchte zwei Bedingungen überprüfen, bevor ich weitergehe, und wenn diese bestanden sind, überprüfe eine dritte Bedingung, bevor ich endlich das mache, was ich tun möchte. Wie Sie sehen können, hängen die meisten Zeilen in diesem Code mit der Validierung zusammen. In einer realen Anwendung wird es mehr Validierung und möglicherweise mehr verschachtelte if-Anweisungen geben.

Hat jemand eine bessere Struktur für die Validierung der Validierung? Wenn es Frameworks gibt, die dies eleganter handhaben, was sind sie und wie erreichen sie das? Mehrere verschachtelte if-Anweisungen scheinen eine solche Brute-Force-Lösung für das Problem zu sein.

Nur eine Anmerkung, ich verstehe, dass es wahrscheinlich eine gute Idee wäre, einige allgemeine Validierungsfunktionen in eine Klasse zu integrieren, so dass ich die Länge, das String-Format usw. durch Aufrufen dieser Funktionen überprüfen kann. Was ich verlange, ist eine sauberere Herangehensweise an die Code-Struktur, nicht wie ich die Fehler überprüfe.

Danke!

    
Logan Serman 19.05.2012, 02:53
quelle

6 Antworten

6

Überprüfen Sie Respect \ Validation . Es ist eine Bibliothek, die für diesen Zweck gebaut wurde. Es kann sehr einfach mit mehreren Regeln umgehen und verwendet Ausnahmen für Fehler. Hier ist ein schnelles Beispiel:

%Vor%

Jetzt mit Ausnahmen:

%Vor%

Im obigen Beispiel wäre die Variable $errors etwa so:

%Vor%

Ich habe zwei vorher erklärte Regeln mit "foo # bar" gebrochen: Es hat Leerzeichen und es hat ein Nicht-Alnum-Zeichen. Für jede Regel, die nicht besteht, wird eine Nachricht zurückgegeben. Da "Länge" in Ordnung ist, ist die Fehlermeldung null.

Die Dokumentation enthält mehrere weitere Beispiele, einschließlich verschachtelter, hierarchischer Regeln und besserer Ausnahmebehandlung. Hat auch eine umfangreiche Liste von Proben für alle der 30 eingebauten Validatoren.

Hoffe das hilft!

    
alganet 28.05.2012, 17:06
quelle
4

Wie wäre es mit Ausnahmen? Sie können Exceptions explizit mit try / catch-Blöcken abfangen und / oder sie mit set_exception_handler()

abfangen

Es gibt eine Reihe von nützlichen Ausnahmetypen, die in PHP definiert sind und die Sie zu Ihrem Vorteil verwenden können, wenn Sie bei der Ausnahmebehandlung Granularität benötigen. Außerdem können Sie benutzerdefinierte Ausnahmen definieren.

Ссылка http://www.php.net/manual/en/spl.exceptions.php

BEARBEITEN

Um Ihre Frage zu beantworten, wie einige andere Frameworks dieses Problem angehen, scheint eine vernünftige Verwendung von Ausnahmen ziemlich üblich. Das Nützliche an der Verwendung ist, dass Sie eine bestimmte Methode haben, die eine Reihe verschiedener Validierungen durchführt, die möglicherweise fehlerhaft sind - Sie können in jedem Fall eine entsprechende Ausnahme auslösen, aber Sie müssen nicht mit den verschiedenen möglichen Ausnahmen umgehen diese Methode. Stattdessen können Sie, je nachdem, wie Sie Ihren Code strukturieren, zulassen, dass die Ausnahme an einem zentralen Ort in Ihrem Code erscheint, an dem Sie sie abfangen und entsprechend behandeln können.

BEARBEITEN 2

Um meinen letzten Kommentar zu filter_input_array()

zu erläutern

Basierend auf einem wirklich einfachen Beispiel mit POSTed-Benutzerdaten. Erstellen Sie zuerst eine Definition:

%Vor%

Verwenden Sie dann eine generische Validierungsklasse (Klassendefinition unten):

%Vor%

Eine sehr einfache (und ungetestete) Implementierung eines FormValidators.

Der grundlegende Anwendungsfall besteht darin, die entsprechende Methode für die Anforderungsmethode aufzurufen, nach der gefiltert werden soll. Dies wiederum überprüft die zurückgegebenen Werte und entscheidet, ob die Eingabe gültig ist.

Dies könnte eine Menge Liebe gebrauchen - besonders die filterInput -Methode, weil Sie möglicherweise einige Tests durchführen müssen, um sicherzustellen, dass Sie die Werte 'truthy' oder 'falsy' entsprechend behandeln. Ich denke Checkbox Typ Werte. Ein Straight Up in_array Check für false könnte es nicht wie hier implementiert schneiden. Aber es gibt eine Menge von Flags, die Sie mit der Definition übergeben können.

Ich denke, Sie könnten auch nach fehlenden Eingaben suchen, indem Sie eine Zählung des resultierenden $values -Arrays und der Definition durchführen, um sicherzustellen, dass sie übereinstimmen. Zusätzliche Eingaben, die nicht in der Definition enthalten sind, werden herausgefiltert (Sie sollten das überprüfen, aber ich bin mir ziemlich sicher, dass das nicht ganz klar ist).

%Vor%

Wie auch immer, würde ich sagen, refactor und testet die bejayzis aus dieser Klasse heraus (oder ändere sie sogar komplett), aber hoffentlich umreißt es die Grundidee: für jeden Inputtyp eine Definition erstellen und dann eine generische Validierungsklasse verwenden filtern und die Gültigkeit sicherstellen.

Hoffe, das hilft. filter_input und filter_input_array rock:)

    
Darragh Enright 19.05.2012 02:57
quelle
2

Wenn Sie "Validierung" sagen - gehe ich davon aus, dass Sie Benutzereingaben überprüfen, bevor Sie eine Aktion ausführen. Ich benutze das oft, wenn ich Daten mit AJAX von jQuery sende oder wenn ich von einem Web-Service antworte.

Wenn ja, können Sie sich meine sehr einfache Validierungsklasse ansehen.

%Vor%

Sie können damit Daten validieren, solange sie in Array-Form vorliegen. Nicht nur $ _POST / $ _ GET Arrays.

    
Xeoncross 22.05.2012 21:11
quelle
1

Wir haben eine Anzahl verschiedener Frameworks erstellt und verwendet. Die Formularverarbeitung ist normalerweise ein wesentlicher Bestandteil der Erstellung von Webanwendungen. Um Ihre Frage zur Fehlerbehandlung zu beantworten, würde ich vorschlagen, die Frage weiter zu betrachten.

Damit Sie alles validieren können, benötigen Sie Eingabedaten und eine Art Definition der Eingabedaten. Als nächstes haben Sie ein Formular oder planen Sie eine zentralisierte Validierung für mehr als ein Formular. Wenn das Erstellen eines allgemeinen Validierungsobjekts sinnvoll ist,

%Vor%

Okay, damit der Validator gut funktioniert, muss er wissen, was zu validieren ist und wie. Hier kommen wir zurück auf die Frage, wie Sie Formulare erstellen - sind diese dynamisch, basierend auf Modellen, oder sind sie einfach HTML. Wenn das Formular auf Model basiert, sind normalerweise alle Felder definiert, und normalerweise sind die meisten Validierungsregeln bereits auf der Modellebene vorhanden. In diesem Fall ist es sinnvoll, Ihrem Validierer beizubringen, Felder von Modellbeispielen zu lernen, z. B.

%Vor%

alternativ, wenn Sie keine Modelle verwenden und Formular ist einfach HTML, macht das einfache Array von Feldern und Validatoren am sinnvollsten:

%Vor% Mit dem obigen Ansatz können Sie definierte Validierer (einen oder mehrere) definieren, und jeder Validierer kann zusätzliche Parameter enthalten. In diesem Fall würde Ihr Validator wie folgt aussehen:

%Vor%

Coole Sache ist, dass Sie Ihre nächsten Validatoren als neue Methoden der Validator-Klasse auf folgende Weise hinzufügen können:

%Vor%

Wenn Sie diesen Ansatz verwenden, haben Sie eine Validator-Klasse, die leicht erweitert werden kann. Sie können mehrere Parameter für die Validatoren haben und Validatoren können Regex / Filter oder eine andere Methode zur Validierung der Felder verwenden. Schließlich enthält $this->errors array ein assoziatives Array mit Feldern und Fehlern. Außerdem nur ein Fehler pro Feld, um den Benutzer nicht zu verwirren. und natürlich können Sie nur Arrays oder Modelle verwenden, die auf der Umgebung basieren, in der die Validierung stattfindet.

    
jancha 26.05.2012 08:43
quelle
0

Um Ihnen zu helfen, sich zu entspannen, egal, was Sie tun, werden Sie mit der gleichen grundlegenden Prozedurschleife enden, die Sie beschreiben. Sie können die Verschachtelung leicht entfernen (siehe unten), aber nicht viel.

Für die Validierung benötigen Sie einen prozeduralen Ablauf, den Sie haben. Es kann zu subtilen Variationen kommen (so wie Sie die kombinatorischen Validatoren auch dann tun, wenn einige andere Felder falsch sind), aber dies ist der prozedurale Ablauf.

%Vor%

Um es aus einer Codierungs-Perspektive effizienter zu machen, können Sie fast jeder der Antworten dort folgen - fügen Sie "Feld" -Klassen hinzu und durchlaufen Sie diese oder eine Reihe von Validierungsbedingungen und durchlaufen Sie diese. Sie können "validators classes" hinzufügen (aber Sie benötigen zwei Typen - einen Typ an das Feld angehängt, einen Typ an das Formular angehängt) und Sie können Ausnahmen verwenden, um Sie zurück in die obige Schleife zu werfen - aber diese Basisprozedurschleife sind besorgt, dass sich nie ändern wird.

Aber um passender zu antworten, wie ich arbeite (bei größeren Projekten), habe ich ein:

  1. "Field Validator" -Klasse, die den Feldtyp, die Länge, die Pflicht usw. validiert.
  2. "Form Validator" -Klasse, die bestimmte Kombinationen von Daten usw. validiert.
  3. "Form" -Klasse, die die Aktionen des Formulars steuert. Dies ist auch nützlich, da verschiedene Arten von Formularklassen eine Verbindung zu einer Datenbank herstellen können (ähnlich VB / C # .Net) und Feldvalidierung aus den Feldtypen ableiten und die Standardfunktionen "Bearbeiten", "Hinzufügen" und "Löschen" haben / li>
  4. "Feld" -Klasse, die die Aktionen des Feldes steuert. Das Feld kann auch mit einem DB verbunden sein, der mit anderen Feldern usw. verknüpft ist.

Das Formular wird mit genau der gleichen prozeduralen Struktur validiert, außer dass es die Feldobjekte (nicht rohe Felder) durchläuft und Ausnahmen in die Schleife zurückspuckt, die die Fehler gegen das Formular speichert (wie von Darragh vorgeschlagen). Mit Klassen ist es nur mehr strukturiert und einfacher hinzufügen / bearbeiten usw.

Für schnelle Projekte (eine Seite Formulare) ohne Überhang des Frameworks verwende ich Ihren Code mit spezifischen Validierungen. (Das ist eine persönliche Entscheidung - andere werden sagen, dass Sie das Framework auch für kleine Projekte verwenden sollten; beide Optionen sind gültig und keine Diskussion für hier. Manchmal würde ich einfach eine Mid-Level-Option verwenden. Welches Projekt auch immer passt.)

Aber egal, was - die Basisprozedurschleife ist die gleiche. Nichts, was Sie tun, als das ist, was erforderlich ist.

    
Robbie 29.05.2012 00:44
quelle
0

Nachstehend habe ich ein Beispiel geschrieben, das Ihnen zeigt, wie Sie Exceptions im Allgemeinen (nicht spezifisch für Ihre Situation) und weiter unten etwas, das für Sie spezifischer ist, verwenden (immer noch Ausnahmen verwenden). Diese ersten beiden Beispiele behandeln jeweils einen Fehler. Das dritte Beispiel, das ich zur Verfügung gestellt habe, zeigt ein Beispiel für die Behandlung mehrerer Fehler und Ausnahmen.

Die meisten Erklärungen finden sich in den Kommentaren des Codes. Schauen Sie also gründlich durch:)

Allgemeine Ausnahmebehandlung

%Vor%

Standard Exception Klassenkonstruktor:

%Vor%

Benutzerdefinierte Ausnahmen

Wenn Sie das nun auf Ihr Beispiel beziehen, könnten Sie etwas in diese Richtung tun:

%Vor%

Ссылка

Ausgabe des obigen Codes:

  

Error String: assert (): Assertion fehlgeschlagen

     

Fehlernummer: 2

     

Datei mit Fehler: 18

     

Zeile mit Fehler: /var/www/test2.php

Sie können die Konzepte der Verschachtelung von try / catch -Anweisungen im ersten Codebeispiel mit diesem zweiten Beispiel für benutzerdefinierte Fehlerbehandlung anwenden.

Behandlung mehrerer Fehler / Ausnahmen

%Vor%

Natürlich können Sie die errorLogger -Klasse ändern und anpassen, um sie Ihren Bedürfnissen anzupassen.

Ausgabe des obigen Codes:

  

Es gibt 5 Fehler:

     

Array (

%Vor%      

)

Der obige Code ermöglicht Ihnen:

  • Ausnahmen werfen und zum errorLogger hinzufügen
  • Behandle alle unbehandelten Situationen von zufälligen Funktionen, die normalerweise Fehler anzeigen würden
  • Fügen Sie Ihre eigenen Fehler manuell hinzu
  • Triggerfehler ( Ссылка )

Sie können dann zu einem späteren Zeitpunkt alle Fehler anzeigen / protokollieren / was auch immer.

Hinweis: Der gesamte obige Code kann direkt kopiert und eingefügt werden, um Ihnen etwas zu geben, mit dem Sie experimentieren können

    
vimist 22.05.2012 19:57
quelle

Tags und Links