Zend Framework Tutorial Teil 9: Benutzereingaben filtern mit Zend_Filter_Input

Im achten Teil vom Zend Framework Tutorial haben wir die Zend_Config Komponente für das Laden unsere Konfigurationsdaten verwendet, unsere Bootstrap Datei stark entschlackt und noch ganz nebenbei zwei Bugs aus dem siebten Teil bereinigt. Wenn du die ersten acht Teile noch nicht gelesen hast, hole dies bitte schnell nach.

In diesem neunten Teil des Tutorials widmen wir uns nun dem Filtern der Benutzereingaben mit der Zend Framework Komponente Zend_Filter_Input. Bisher haben wir direkt auf die Daten der globalen $_POST Variable zugegriffen, was zwar funktioniert, aber gewisse Sicherheitsprobleme bringen kann. Wir werden die Komponenten auch mit eigenen Methoden erweitern und uns in einer umfangreichen Übung um die Kommentarfunktion für unser TravelloBlog kümmern.

Wenn du über neue Tutorial Teile informiert werden möchtest, abonniere am besten den Feed dieses Blogs. Dann verpasst du garantiert keinen Teil des Tutorials.

Wichtig: Dieses Tutorial setzt die Zend Framework Preview Version 0.2.0 voraus und kann bei der Verwendung einer aktuelleren Version aus dem SVN unter Umständen nicht zu 100% funktionieren.

Inhaltsverzeichnis

Zend_Filter

Bevor wir uns Zend_Filter_Input widmen möchte ich zuerst die Komponente Zend_Filter vorstellen, da Zend_Filter_Input diese Komponente intensiv verwendet. Für eine erste sehr kurze Einführung empfehle ich wie immer den Blick ins Zend_Filter Kapitel im Manual.

Hinweis

Das Kapitel im Manual über die Zend_Filter Komponente ist stark verbesserungswürdig und entspricht nicht mehr ganz dem aktuellen Stand der ZF 0.2.0 Version. So gibt es in Zend_Filter keine Methode testEmail(). Diese heißt isEmail().

Zend_Filter ist im Prinzip eine Bibliothek mit statischen Methoden für das Filtern von Daten. Es stellt dabei drei Typen von Methoden bereit für unterschiedliche Anwendungsfälle beim Filtern von Daten. Hier wird zwischen dem so genannten Whitelist Filtern, dem Blinden Filtern und dem Blacklist Filtern unterschieden.

Beim Whitelist Filtern wird geprüft, ob die zu prüfenden Daten einem bestimmten Format entsprechen. Sind z.B. nicht erlaubte Zeichen enthalten oder entsprechen die Daten nicht dem Format wird "false" zurückgegeben. Andernfalls die korrekten Daten. Beim blinden Filtern werden nur die erwünschten Zeichen zurückgegeben. Und beim Blacklist Filtern wird geprüft, ob die Daten einem bestimmten Format entsprechen, um sie dann auszuschließen.

Hinweis

Noch ein weiterer Hinweis. Die Methoden in Zend_Filter zum Blacklist Filtern sind im eigentlichen Sinne keine Blacklist Filter, sondern auch blinde Filter, weil sie Zeichen entfernen, die nicht in den zu prüfenden Daten vorkommen dürfen.

Leider sind die Methoden im Manual noch nicht ausführlich dokumentiert. Um einen Überblick über die vorhandenen Methoden zu erhalten, empfehle ich entweder den direkten Blick in den Code von Zend_Filter und in die Api Docs. Dort oben rechts das Paket Zend_Filter auswählen, dann rechts auf "Class trees" klicken und danach auf Zend_Filter klicken. Die Methoden, welche mit "get" beginnen, sind die blinden Filter und die Methoden, welche mit "is" beginnen, sind die Whitelist Filter.

Zend_Filter_Input

Die Komponente Zend_Filter_Input setzt auf Zend_Filter auf und stellt einen guten Ansatz für das Filtern von Benutzereingaben bereit. Auch hier wieder der Hinweis auf das Manual, das ein wenig ausführlicher als das Kapitel zu Zend_Filter ist.

Um Zend_Filter_Input zu verwenden, wird eine Instanz erstellt und dabei ein Array mit Benutzereingaben übergeben. In der Regel handelt es sich dabei um die globale $_POST oder $_GET Variable. Hier ein einfaches Beispiel für die Anwendung:

PHP:
  1. <?php
  2.     $filterPost = new Zend_Filter_Input($_POST);
  3.    
  4.     if ($alphaName = $filterPost->testAlpha('name')) {
  5.         /* $alphaName enthält nur Buchstaben. */
  6.     } else {
  7.         /* $alphaName evaluiert als FALSE. */
  8.     }
  9. ?>

Nach der Übergabe wird die $_POST bzw. $_GET Variable übrigens auf "null" gesetzt, so dass man fortan nur noch über das Zend_Filter_Input Objekt auf diese Daten zugreifen kann. Es bietet sich also an, ein Zend_Filter_Input Objekt im Objektspeicher abzulegen, so dass man von überall aus darauf zugreifen kann. Möchtest du das "auf null setzen" von $_POST bzw. $_GET vermeiden, musst du an den Konstruktor als zweiten Parameter "false" übergeben.

Leider sind die Methoden von Zend_Filter_Input im Manual ebenfalls noch nicht im Detail dokumentiert. Um einen Überblick über die vorhandenen Methoden zu erhalten, empfehle ich entweder den direkten Blick in den Code von Zend_Filter_Input und in die Api Docs. Dort oben rechts das Paket Zend_Filter auswählen, dann rechts auf "Class trees" klicken und danach auf Zend_Filter_Input klicken. Die Methoden, welche mit "get" beginnen, sind die blinden Filter und die Methoden, welche mit "test" beginnen, sind die Whitelist Filter.

Zend_Filter_Input Objekt erstellen

Um ein Zend_Filter_Input Objekt verwenden zu können, müssen wir es erst erstellen und dann im Objektspeicher ablegen, damit wir uns unseren Controller Klassen auf die Daten zugreifen können. Öffne also nun die Datei "settings.php" im Verzeichnis "/application/config" und füge ans Ende folgende Zeilen ein:

PHP:
  1. <?php
  2. [...]
  3.  
  4. $post = new Zend_Filter_Input($_POST);
  5. Zend::register('post', $post);
  6. ?>

Für unser TravelloBlog brauchen wir vorerst nur ein Filter Objekt für die $_POST Daten. Du kannst aber auf die gleiche Weise auch ein Filter Objekt für die $_GET Daten anlegen.

Das war es auch schon und wir können uns direkt ums Filtern der Eingabedaten in unseren Controller Klassen kümmern.

ArticleController ändern

Bisher greifen wir im ArticleController nur in den Methoden validateAction und doDeleteAction auf die $_POST Variable zu. Also müssen wir diese Methoden überarbeiten.

Öffne nun die Datei "ArticleController.php" im Verzeichnis "/application/controllers/" und suche nach der validateAction Methode. Ändere nun die ersten Zeilen wie folgt ab:

PHP:
  1. <?php
  2.     public function validateAction()
  3.     {
  4.         $post = Zend::registry('post');
  5.        
  6.         if (!$post->keyExists('button_save'))
  7.         {
  8.             $url = getRewriteBase() . '/';
  9.            
  10.             $this->_redirect($url);
  11.         }
  12.        
  13.         [...]
  14. ?>

Als erstes holen wir uns das Zend_Filter_Objekt zurück aus dem Objektspeicher. Dann prüfen wir, ob der Schlüssel "button_save" vorhanden ist, d.h. ob der Speicherbutton angeklickt worden ist. Falls der Schlüssel nicht vorhanden ist, leiten wir auf die Startseite unseres TravelloBlogs um, um direkte Aufrufe der validateAction Methode zu verhindern.

Als nächstes passen wir den Codeblock an, in dem die übertragenen Daten an unser $data Array übergeben werden, damit diese später gespeichert werden können. Ändere also die folgenden Zeilen wie folgt ab:

PHP:
  1. <?php
  2.     public function validateAction()
  3.     {
  4.         [...]
  5.  
  6.         $data = array();
  7.        
  8.         if ($post->keyExists('art_id'))
  9.         {
  10.             $data['art_id'] = $post->getDigits('art_id');
  11.         }
  12.        
  13.         $data['art_title' ] = $post->getRaw('art_title');
  14.         $data['art_teaser'] = $post->getRaw('art_teaser');
  15.         $data['art_text'  ] = $post->getRaw('art_text');
  16.        
  17.         $data['art2cat_cat_id'] = $post->keyExists('art2cat_cat_id')
  18.                                 ? $post->getDigits('art2cat_cat_id')
  19.                                 : null;
  20.        
  21.         $data['art2tag_tag_id'] = $post->keyExists('art2tag_tag_id')
  22.                                 ? $post->getDigits('art2tag_tag_id')
  23.                                 : null;
  24.        
  25.         [...]
  26. ?>

Hier prüfen wir zuerst, ob ein Wert für "art_id" übergeben worden ist, und falls ja, werden alle Zeichen, die keine Ziffern sind, gefiltert. Das heißt also, dass ein Aufruf von Zend_Filter_Input::getDigits() nur Ziffern zurück liefert.

Für die Felder "art_title", "art_teaser" und "art_text" lassen wir uns erst einmal die rohen Daten zurück geben, da wir diese gleich noch detaillierter testen möchten. Für die beiden Felder "art2cat_cat_id" und "art2tag_tag_id" verwenden wir wieder Zend_Filter_Input::getDigits() und sehen, dass die Funktion sogar auf Arrays angewendet werden kann.

Jetzt wird in validateAction schon mal nicht mehr direkt auf die $_POST Variable zugegriffen. Wir können aber die Daten noch weiter prüfen und gegen nicht erwünschte Eingaben prüfen. Dafür ändern wir den nächsten Codeabschnitt nun wie folgt:

PHP:
  1. <?php
  2.     public function validateAction()
  3.     {
  4.         [...]
  5.  
  6.         $errors = array();
  7.        
  8.         if (strlen($data['art_title']) == 0)
  9.         {
  10.             $errors['art_title'] = 'Please enter a title!';
  11.         }
  12.         elseif ($post->testRegex('art_title', '=[^[:alnum:]\ \-\.\,\!\?\/]='))
  13.         {
  14.             $errors['art_title'] = 'Only letters, digits, spaces and the following signs allowed: -/.,!?';
  15.         }
  16.        
  17.         if ($post->testRegex('art_teaser', '=[^[:alnum:]\ \-\.\,\!\?\/]='))
  18.         {
  19.             $errors['art_teaser'] = 'Only letters, digits, spaces and the following signs allowed: -/.,!?';
  20.         }
  21.        
  22.         if (strlen($data['art_text']) == 0)
  23.         {
  24.             $errors['art_text'] = 'Please enter a text!';
  25.         }
  26.         elseif ($data['art_text'] != $post->noTags('art_text'))
  27.         {
  28.             $errors['art_text'] = 'No tags allowed!';
  29.         }
  30.                
  31.         [...]
  32. ?>

Für die beiden Felder "art_title" und "art_teaser" führen wir nun eine weitere Prüfung mit Hilfe eines regulären Ausdrucks ein, der auf Buchstaben, Ziffern, Leerzeichen und ausgewählte Satzzeichen prüft. Für das Feld "art_text" prüfen wir zudem, ob HTML Tags im Text vorhanden sind und geben dann eine entsprechende Fehlermeldung aus.

Rufe nun einmal in deinem Browser das TravelloBlog auf und ändere einen Artikel. Gebe dort bewusst Daten ein, welche die Fehlermeldungen hervorrufen sollen und klicke dann auf Speichern. Dies könnte dann in etwa wie folgt aussehen:

Artikel validieren

Das funktioniert also schon einmal sehr gut. Eine Sache ist aber noch ein wenig störend. Wenn wir unseren regulären Ausdruck zum Prüfen von "art_title" und "art_teaser" ändern möchte, um z.B. ein weiteres Zeichen zu den erlaubten hinzuzufügen, müssen wir das schon an zwei Stellen ändern. Verwenden wir den regulären Ausdruck auch in anderen Controllern wird es schnell unübersichtlich.

Du fragst dich nun also sicher, ob du nicht auch Zend_Filter_Input anpassen kannst, um den regulären Ausdruck dort zentral für Prüfungen ablegen zu können. Kannst du, also lies schnell weiter!

Zend_Filter und Zend_Filter_Input erweitern

Um unseren regulären Ausdruck nicht nur in Zend_Filter_Input, sondern auch bei der direkten Verwendung von Zend_Filter verwenden zu können, müssen wir beide Klassen erweitern.

Wir beginnen mit Zend_Filter und erstellen nun im Verzeichnis "/library/zf/Travello" die Datei "Filter.php" mit folgendem Code:

PHP:
  1. <?php
  2. class Travello_Filter extends Zend_Filter
  3. {
  4.     public static function isTitle($value)
  5.     {
  6.         return (bool) preg_match('=[^[:alnum:]\ \-\.\,\!\?\/]=', $value);
  7.     }
  8.    
  9. }
  10. ?>

Das war es schon? Ja, das war es schon. Der Name ist vielleicht nicht ganz glücklich gewählt, aber mir ist an dieser Stelle nichts besseres eingefallen. Um diese Methoden nun auch mit unserer Zend_Filter_Input Instanz verwenden zu können, müssen wir auch diese Klasse erweitern.

Erstelle nun also das Verzeichnis "/library/zf/Travello/Filter" und lege dort die Datei "Input.php" mit folgendem Code an:

PHP:
  1. <?php
  2. class Travello_Filter_Input extends Zend_Filter_Input
  3. {
  4.     public function testTitle($key)
  5.     {
  6.         if (!$this->keyExists($key)) {
  7.             return false;
  8.         }
  9.         if (Travello_Filter::isTitle($this->_source[$key])) {
  10.             return $this->_source[$key];
  11.         }
  12.  
  13.         return FALSE;
  14.     }
  15. }
  16. ?>

In der Methode Travello_Filter_Input::testTitle() wird zuerst geprüft, ob ein Wert für den Schlüssel vorhanden ist. Danach wird die Travello_Filter::isTitle() Methode aufgerufen und bei erfolgreicher Prüfung der Wert zurückgegeben.

Um unsere erweiterten Klassen verwenden zu können, müssen wir nun die Instantiierung in der "settings.php" Datei entsprechend anpassen:

PHP:
  1. <?php
  2. [...]
  3.  
  4. $post = new Travello_Filter_Input($_POST);
  5. Zend::register('post', $post);
  6. ?>

Und zum Schluss passen wir nun noch die validateAction Methode in unserem ArticleController an, indem wir den Aufruf von testRegex() durch testTitle() ersetzen:

PHP:
  1. <?php
  2.     public function validateAction()
  3.     {
  4.         [...]
  5.  
  6.         elseif ($post->testTitle('art_title'))
  7.         {
  8.             $errors['art_title'] = 'Only letters, digits, spaces and the following signs allowed: -/.,!?';
  9.         }
  10.        
  11.         if ($post->testTitle('art_teaser'))
  12.         {
  13.             $errors['art_teaser'] = 'Only letters, digits, spaces and the following signs allowed: -/.,!?';
  14.         }
  15.        
  16.         [...]
  17. ?>

Prüfe das Ganze nun noch einmal in deinem Browser und es sollte weiterhin wie gewünscht funktionieren. Du kannst natürlich Travello_Filter und Travello_Filter_Input auch um weitere Methoden für zusätzliche Filter ergänzen.

Da die Methode Zend_Filter::isEmail() derzeit noch nicht implementiert ist, übernehmen wir das nun, da wir eine Prüfung auf eine E-Mail Adresse später noch brauchen werden. Füge also in Travello_Filter nun noch folgende zweite Methode hinzu:

PHP:
  1. <?php
  2. class Travello_Filter extends Zend_Filter
  3. {
  4.     [...]
  5.  
  6.     public static function isEmail($value)
  7.     {
  8.         return (bool) preg_match('=^[a-z0-9][\._a-z0-9-]*@[a-z0-9][\.a-z0-9-]*(\.[a-z]{2,6})$=i', $value);
  9.     }
  10. }
  11. ?>

Dies ist natürlich keine, auch nur annähernd perfekte Prüfung auf eine gültige E-Mail Adresse, aber für unsere Zwecke reicht es. Wer Langeweile hat kann gerne RFC 2822 komplett implementieren und den Code dann der Zend Framework Community zur Verfügung stellen.

In Travello_Filter_Input musst du nun noch den Aufruf unser eigenen isEmail Methode einfügen:

PHP:
  1. <?php
  2. class Travello_Filter_Input extends Zend_Filter_Input
  3. {
  4.     [...]
  5.  
  6.     public function testEmail($key)
  7.     {
  8.         if (!$this->keyExists($key)) {
  9.             return false;
  10.         }
  11.         if (Travello_Filter::isEmail($this->_source[$key])) {
  12.             return $this->_source[$key];
  13.         }
  14.  
  15.         return FALSE;
  16.     }
  17. ?>

Weitere Controller ändern

Bevor wir uns TagController und CategoryController widmen, müssen wir noch die Abfrage in doDeleteAction wie bei validateAction entsprechen anpassen:

PHP:
  1. <?php
  2.     public function doDeleteAction()
  3.     {
  4.         $post = Zend::registry('post');
  5.        
  6.         if (!$post->keyExists('button_delete'))
  7.         {
  8.             $url = getRewriteBase() . '/';
  9.            
  10.             $this->_redirect($url);
  11.         }
  12.        
  13.         [...]
  14. ?>

Auf die gleiche Weise kannst du auch die Methoden doDeleteAction im TagController und im CategoryController anpassen.

Für Tags möchten wir nur Buchstaben, das Leerzeichen und das kaufmännische Und zulassen. Du kannst für diese Prüfung gerne auch eine eigene Methode in Travello_Filter einführen. Die Methode validateAction im TagController ändere also wie folgt ab:

PHP:
  1. <?php
  2.     public function validateAction()
  3.     {
  4.         $post = Zend::registry('post');
  5.        
  6.         if (!$post->keyExists('button_save'))
  7.         {
  8.             $url = getRewriteBase() . '/tag/';
  9.            
  10.             $this->_redirect($url);
  11.         }
  12.        
  13.         $data = array();
  14.        
  15.         if ($post->keyExists('tag_id'))
  16.         {
  17.             $data['tag_id'] = $post->getDigits('tag_id');
  18.         }
  19.        
  20.         $data['tag_name'] = $post->getRaw('tag_name');
  21.        
  22.         $errors = array();
  23.        
  24.         if (strlen($data['tag_name']) == 0)
  25.         {
  26.             $errors['tag_name'] = 'Please enter a name for the tag!';
  27.         }
  28.         elseif ($post->testRegex('tag_name', '=[^[:alpha:]\ \&]='))
  29.         {
  30.             $errors['tag_name'] = 'Only letters, spaces and ampersand allowed';
  31.         }
  32.  
  33.         [...]
  34. ?>

Für Kategorien möchten wir nur Buchstaben, Ziffern, den Bindestrich und das Leerzeichen zulassen. Du kannst für diese Prüfung gerne auch eine eigene Methode in Travello_Filter einführen. Die Methode validateAction im CategoryController ändere also wie folgt ab:

PHP:
  1. <?php
  2.     public function validateAction()
  3.     {
  4.         $post = Zend::registry('post');
  5.        
  6.         if (!$post->keyExists('button_save'))
  7.         {
  8.             $url = getRewriteBase() . '/category/';
  9.            
  10.             $this->_redirect($url);
  11.         }
  12.        
  13.         $data = array();
  14.        
  15.         if ($post->keyExists('cat_id'))
  16.         {
  17.             $data['cat_id'] = $post->getDigits('cat_id');
  18.         }
  19.        
  20.         $data['cat_name'] = $post->getRaw('cat_name');
  21.        
  22.         $errors = array();
  23.        
  24.         if (strlen($data['cat_name']) == 0)
  25.         {
  26.             $errors['cat_name'] = 'Please enter a name for the category!';
  27.         }
  28.         elseif ($post->testRegex('cat_name', '=[^[:alnum:]\ \-]='))
  29.         {
  30.             $errors['cat_name'] = 'Only letters, digits, spaces and hyphens allowed';
  31.         }
  32.        
  33.         [...]
  34. ?>

Übung: Kommentarfunktion

Die heutige Übung ist etwas umfangreicher als sonst und hat nicht ausschließlich etwas mit den heute vorgestellten Komponente Zend_Filter_Input zu tun. Auch wenn du dabei natürlich Zend_Filter_Input bzw. unsere erweiterte Klasse verwenden sollst.

Bitte implementiere nun die Kommentarfunktion für Artikel und setze dabei diese Punkte um:

  • Ausgabe aller vorhandenen Kommentare bei einem Artikel (ältester oben)
  • Hinzufügen von neuen Kommentaren zu einem Artikel
  • Ändern und Löschen bestehender Kommentare
  • Ausgabe der ersten 40 Zeichen der 5 letzten Kommentaren in der Box 2 auf der rechten Seite (neuester oben)

Diese Übung ist wie gesagt deutlich umfangreicher als die bisherigen Übungen. Da wir aber im letzten Teil sowieso keine Übung dabei hatten und mit dieser Übung noch einmal alles bisher Gelernte angewandt werden muss, ist diese Übung sehr sinnvoll.

Damit du nicht vollkommen verloren bist, hier ein paar Tipps, wie du die Sache angehen könntest:

  • Als erstes brauchst du natürlich eine neue Model Klasse für Kommentare sowie Templates für Kommentare zur Darstellung eines Formulars.
  • Als nächstes musst du den CommentController mit den Methoden buildForm, saveData, changeAction, validateAction, deleteAction und doDeleteAction ausstatten.
  • Dann benötigst du noch zwei Templates: eines zum Anzeigen des Kommentarformulars und eines zum Löschen eines Kommentars.
  • Nach dem Anlegen, Ändern und Löschen eines Kommentars solltest du per Redirect auf den entsprechenden Artikel umleiten, zu dem der Kommentar gehört.
  • Die Anzeige der letzten Kommentare in der Box 2 lässt sich ähnlich wie die Tagwolke erledigen.
  • Zusätzlich könntest du noch ein wenig Hand an unsere CSS Datei anlegen, damit die Ausgabe der Kommentare etwas besser aussieht.
  • Und nicht vergessen die Methode ArticleController::doDeleteAction so anzupassen, dass beim Löschen eines Artikels auch die zugehörigen Kommentare gelöscht werden.

Zur Kontrolle lade dir den aktuellen Stand des Tutorials runter. Dann kannst du deine Ergebnisse damit vergleichen.

Download

Der aktuelle Stand des Tutorials nach diesem sechsten Teil kann herunter geladen werden. Hier sind auch alle Templates enthalten. Die Textdateien "empty.txt" in einigen Verzeichnissen habe ich nur angelegt, weil mein Winzip keine leeren Verzeichnisse im Zip Archiv anlegt:

Die Zip Datei enthält nicht die aktuelle Version des Zend Frameworks. Dies musst du bitte selber in das entsprechende Verzeichnis kopieren.

Zusammenfassung

In diesem neunten Teil des Zend Framework Tutorials haben wir die Zend_Filter und Zend_Filter_Input Komponenten kennen gelernt und für die Prüfung der Eingabedaten durch die Nutzer verwendet. Wir haben die beiden Klassen auch um eigene Funktionen erweitert, so dass wir fortan an ein gutes, zentrales Werkzeug für das Filtern von Benutzereingaben haben.

Im nächsten Teil des Tutorials werden wir uns dem Cachen von diversen Daten kümmern und die Zend_Cache Komponente kennen lernen.

Change Log

An dieser Stelle werden Änderungen an diesem Tutorial Teil zusammengefasst, die nach dem Ersterscheinen (16.10.2006) notwendig waren, z.B. durch neuere Versionen des Zend Frameworks oder Änderungen am Konzept des Tutorials oder den Anforderungen an unser TravelloBlog.

  • 05.11.2006: Tutorial für Release 0.2.0 aktualisiert

Navigation

7 Antworten für “Zend Framework Tutorial Teil 9: Benutzereingaben filtern mit Zend_Filter_Input”

  1. Ralfs PHP Blog » Zend Framework Tutorial Teil 10: Sinnvoll cachen mit Zend_Cache sagt:

    [...] Im neunten Teil vom Zend Framework Tutorial haben wir die Zend_Filter Komponente für das Filtern von Benutzereingaben kennen und anwenden gelernt. Zudem hast du in einer umfangreicheren Übung (so hoffe ich zumindest) die Kommentarfunktion für unser TravelloBlog realisiert. Wenn du die ersten neun Teile noch nicht gelesen hast, hole dies bitte schnell nach. [...]

  2. Ralfs PHP Blog » Zend Framework Tutorial Teil 1: Einführung und Anforderungen sagt:

    [...] Benutzereingaben filtern mit Zend_Filter_Input [...]

  3. Ralfs PHP Blog » Zend Framework Tutorial Teil 8: Konfiguration mit Zend_Config sagt:

    [...] Tutorial, Zend Framework, Zend Framework Tutorial, Zend Config Bookmark: del.icio.us yigg.de mister-wong.de  [...]

  4. thomas sagt:

    Moin, also ich sitze heute schon den halben nachmittag und grübel wo hier der Fehler liegt.

    meine Funktion

    public static function isTextField($value)
    {
    return (bool) preg_match('=[^[:alnum:]\ \-\.\,\&\!\?\/]=', $value);
    }

    irgendwas verplane ich hier gerade. pregmatch liefert doch bei übereinstimming mit dem muster true zurück, bzw den übereinstimmenden Integer wert. Bei dieser funktion ist es genau andersrumm, d.h. wenn ein char gefunden wird, der nicht im muster vorkommt, dann wird true ausgegeben.

    Des problem welches ich jetzt habe ist folgenes.

    public function testEmail($key)
    {
    if (!$this->keyExists($key)) {
    return false;
    }
    if (Travello_Filter::isTextField($this->_source[$key])) {
    return $this->_source[$key]; // hier gelange ich nur im fehler fall hinnein weil Fehler -> true
    }
    return FALSE;
    }

    ok nun mein Problem

    public static function isEmail($value)
    {
    return (bool) preg_match('=^[a-z0-9][\._a-z0-9-]*@[a-z0-9][\.a-z0-9-]*(\.[a-z]{2,6})$=i', $value);

    }

    liefert allerdings genau das Gegenteil zurück. Wenn eine mail exact dem muster entspricht wird true zurück geliefert. Fehlt zum beispiel das @ zeichen bekomme ich ein false. Das ist im Prinzip kein problem, denn mit !preg_match('=^[a-z0-9][\._a-z0-9-]*@[a-z0-9][\.a-z0-9-]*(\.[a-z]{2,6})$=i', $value); lässt dich das beheben. Doch was ist nun richtig ? Fehler in der reg exp?

    Gruß Thomas

  5. Maik sagt:

    Hallo,

    die Zend_Filter* und Zend_Validate* Sachen bei ZF 1.0 sind komplett überarbeitet worden, das Kapitel hier kann für die aktuelle Version leider nicht mehr verwendet werden. Es gibt keine Methoden keyExists() oder getRaw()/getDigits mehr.

    Stattdessen muss man folgendermaßen vorgehen:

    Man erstellt Filter/Validatoren aus den existierenden Klassen Zend_Filter*/Zend_Validate*:

    $fdigit = new Zend_Filter_Digits();
    $vdigit = new Zend_Validate_Digits();
    $vnotempty = new Zend_Validate_NotEmpty();

    Nun erstellt man für Filter und Validatoren jeweils ein Array, das als Index den Feldnamen und als Value den entsprechenden Filter bzw. Validator verwendet. Als Beispiel dient hier mal die art_id, welche gesetzt ist, wenn man einen bestehenden Artikel verändert:

    $filters = array(
    'art_id' => $fdigit
    );

    $validators = array(
    'art_id' => array(
    $vdigit,
    $vnotempty
    )
    );

    Nun kann man eine Instanz von Zend_Filter_Input holen, die Filter und Validatoren übergeben und anschließend die Felder prüfen:

    $post = new Zend_Filter_Input($filters, $validators, $_POST);

    if($post->isValid('art_id')) {
    $data['art_id'] = $post->getUnescaped('art_id');
    }

    Vielleicht hilft das dem einen oder anderen, der hier nicht weiter kommt.

    Um die Regulären Ausdrücke von Ralf auch verwenden zu können, muss man abstrahierte Klassen von Zend_Validate_Abstract bzw. Zend_Filter_Interface erstellen. Bei Interesse poste ich gerne die Codes von meinen.

  6. Carsten sagt:

    Hallo Maik,

    Seit ZF 1.0 existiert ja die Methode "keyExists()" nicht mehr.
    Wie kann man nun in ZF 1.5 testen, ob der Schlüssel "button_save" vorhanden ist bzw. ob der Speicherbutton angeklickt worden ist ?

    Es wäre nett, wenn jemand den kompletten Code der "ArticleController"-Funktion "validateAction()" für ZF 1.0 oder ZF 1.5 posten könnte.

  7. Maik Greubel sagt:

    Hallo,

    im aktuellen ZF 1.5 sind die Zend_Form Komponenten hinzugekommen. Im aktuellen PHP Journal (Ausgabe Mai/Juni) ist ein sehr guter Artikel zu dieser Thematik. Dort wird auch beschrieben, wie man Felder auf "required" setzt. Das Zend_Form Framework ist deshalb so gut, weil damit eine Möglichkeit ähnlich wie bei PEAR::QuickForm gegeben wird, Formulare mittels PHP-Klassen zu erstellen.

    Am Wochenende werde ich dafür mal ein paar Beispiele geben.

    Grüße

    Maik

Hinterlasse eine Antwort