7.2. Zend_Filter_Input

7.2.1. Wprowadzenie

Klasa

Zend_Filter_Input dostarcza proste metody, które zapewniają poważne potraktowanie filtrowania danych przychodzących. Jej przeznaczenie jest różnorodne, ponieważ zaspokaja ona potrzeby trzech różnych grup ludzi:

  • Programiści

    Chociaż filtrowanie danych wejściowych nigdy nie może być tak łatwe jak nierobienie niczego, programiści potrzebują zapewnić integralną czystość swoim danym nie dodając w tym celu niepotrzebnej złożoności kodu. Zend_Filter_Input oferuje proste metody, które mogą być użyte w większości przypadków, przy zachowaniu sporej elastyczności w przypadkach skrajnych. Metody mają określone ścisłe konwencje nazewnictwa co sprzyja pisaniu przejrzystego kodu.

  • Menadżerzy

    Menadżerzy którzy chcą zachować kontrolę nad dużą grupą programistów mogą narzucić gotowy sposób filtrowania danych wejściowych, a także mogą wyeliminować dostęp to niefiltrowanych danych wejściowych.

  • Audytorzy

    Ci, którzy sprawdzają kod aplikacji potrzebują szybko i solidnie sprawdzić kiedy i gdzie używane są dane wejściowe w czystej postaci. Zasady, które sprzyjają pisaniu przejrzystego kodu wspierają także audytorów zapewniając im jasne odróżnienie pomiędzy różnymi sposobami filtrowania danych wejściowych.

Jest wiele różnych zdań na temat filtrowania danych przychodzących i jest wiele różnych metod, których programiści mogą użyć. Filtrowanie whitelist, filtrowanie blacklist, wyrażenia regularne, wyrażenia warunkowe oraz natywne funkcje PHP są tylko kilkoma przykładami filtrowania danych przychodzących. Zend_Filter_Input łączy te metody w jedno API o jednolitym działaniu oraz o sztywnych konwencjach nazewnictwa. Wszystkie metody działają według prostej zasady - jeśli dane są prawidłowe, są one zwracane, w przeciwnym wypadku zwracana jest wartość FALSE. Jest to maksymalnie proste.

7.2.1.1. Filtrowanie Whitelist

Metody filtrowania whitelist poprzedzone są przedrostkiem test, na przykład testAlpha() czy testEmail(). Te metody sprawdzają dane według zdefiniowanych kryteriów i zwracają dane tylko wtedy gdy są zgodne. Jeśli nie są, zwracana jest wartość FALSE. Oto prosty przykład:

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST);
    
    if ($alphaName = $filterPost->testAlpha('name')) {
        /* $alphaName zawiera tylko litery. */
    } else {
        /* $alphaName ma wartość FALSE. */
    }
    
    ?>
            

To powoduje wystąpienie błędu podczas zamiany zwróconej przefiltrowanej wartości na wartość logiczną. Jeśli chcesz porównać wartości, które w PHP zostają zamienione na wartość FALSE (na przykład liczba 0 czy pusty łańcuch znaków), możesz przeprowadzić ścisłe porównanie z FALSE:

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST);
    $alphaName = $filterPost->testAlpha('name');
    
    if ($alphaName !== FALSE) {
        /* $alphaName zawiera tylko litery. */
    } else {
        /* $alphaName === FALSE */
    }
    
    ?>
            

7.2.1.2. Filtrowanie blind

Metody filtrowania blind poprzedzone są przedrostkiem get, na przykład getAlpha() czy getDigits(). Te metody nie sprawdzają danych, natomiast zwracają tylko te części które spełniają kryteria. Na przykład metoda getAlpha() zwraca tylko litery, jeśli jakieś istnieją w filtrowannych danych. (Jeśli nie istnieją zwracany jest pusty łańcuch.) Oto prosty przykład:

    <?php
    
    /* $_POST['username'] = 'John123Doe'; */
    
    $filterPost = new Zend_Filter_Input($_POST);
    $alphaUsername = $filterPost->getAlpha('username');
    
    /* $alphaUsername = 'JohnDoe'; */
    
    ?>
            

7.2.1.3. Filtrowanie blacklist

Metody filtrowania blacklist poprzedzone są przedrostkiem no, na przykład noTags() czy noPath(). Te metody działają identycznie jak metody blind, z wyjątkiem tego, że tutaj kryteria mówią o tym jakie dane są nieprawidłowe, a nie o tym jakie są prawidłowe. Dane nieprawidłowe są usuwane, a pozostałe dane (uznane za prawidłowe) są zwracane. Oto prosty przykład:

    <?php
    
    /* $_POST['comment'] = '<b>Kocham PHP!</b>'; */
    
    $filterPost = new Zend_Filter_Input($_POST);
    $taglessComment = $filterPost->noTags('comment');
    
    /* $taglessComment = 'Kocham PHP!'; */
    
    ?>
            

7.2.2. Opis działania

Zend_Filter_Input łączy kilka różnych podejść do filtrowania danych przychodzących w jedno API o jednolitym działaniu oraz o sztywnych konwencjach nazewnictwa. (zobacz Sekcja 7.2.1, „Wprowadzenie”).

Obsługiwane są dwa typy składni. W domyślnym sposobie do konstruktora przekazywany jest pojedynczy argument - tablica która ma być filtrowana:

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST);
    $email = $filterPost->testEmail('email');
    
    ?>
        

Zend_Filter_Input zmienia wartość tablicy, która została przekazana ($_POST) na NULL, więc bezpośredni dostęp do niej nie jest już możliwy. (Dostęp do niefiltrowanych danych jest jedynie możliwe za pomocą metody getRaw(), która jest dużo łatwiejsza do kontrolowania)

W sposobie opcjonalnym, wartość FALSE jest przekazywana jako drugi argument do konstruktora:

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST, FALSE);
    $email = $filterPost->testEmail('email');
    
    ?>
        

Użycie filtra jest identyczne, ale Zend_Filter_Input nie ustawia wartości oryginalnej tablicy ($_POST) na NULL, więc dalej jest możliwy bezpośredni dostęp do danych. Ten sposób nie jest polecany, polecany jest sposób pierwszy.

Zend_Filter_Input jest zaprojektowany głównie w celu filtrowania tablic. Duża część danych wejściowych pochodzi z superglobalnych tablic PHP ($_GET, $_POST, $_COOKIE, itp.), a tablice także są najczęstszą strukturą używaną do przechowywania danych wejściowych pochodzących z innych źródeł. Jeśli potrzebujesz filtrować wartości skalarne (nietablicowe) zobacz Rozdział 7, Zend_Filter.

7.2.3. Przykłady użycia

Ścisłe filtrowanie whitelist (preferowane):

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST);
    
    if ($email = $filterPost->testEmail('email')) {
        /* $email jest prawidłowym adresem email. */
    } else {
        /* $email nie jest prawidłowym adresem email. */
    }
    
    ?>
        

Ścisłe filtrowanie blind:

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST);
    $alphaName = $filterPost->getAlpha('name');
    
    ?>
        

Ścisłe filtrowanie blacklist:

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST);
    $taglessComment = $filterPost->noTags('comment');
    
    ?>
        

Nieścisłe filtrowanie whitelist:

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST, FALSE);
    
    if ($email = $filterPost->testEmail('email')) {
        /* $email jest prawidłowym adresem email. */
    } else {
        /* $email nie jest prawidłowym adresem email. */
    }
    
    ?>
        

Nieścisłe filtrowanie blind:

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST, FALSE);
    $name = $filterPost->getAlpha('name');
    
    ?>
        

Nieścisłe filtrowanie blacklist:

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST, FALSE);
    $comment = $filterPost->noTags('comment');
    
    ?>