Filtrowanie i walidacja

Współczesne strony internetowe oferują swoim odwiedzającym możliwość interakcji, która polega na wprowadzaniu różnego rodzaju danych czy przesyłania plików. Typy wprowadzanych informacji można podzieć ze względu na ich odzwierciedlenie np. imię musi zawierać tylko litery, z kolei numer telefonu powinien zawierać tylko i wyłącznie cyfry (bez uwzględnienia numeru kierunkowego, który może zawierać '+’). W przypadku witryn internetowych wymuszanie od użytkownika podania informacji przed dalszym przetwarzaniem we właściwej formie jest bardzo istotne w kontekscie prawidłowego jej funkcjonowania oraz potencjalnego dostępu do wrażliwych danych. Aby mieć pewność że nasz system będzie funkcjonował prawidłowo oraz co ważniejsze – będzie odporny na potencjalne ataki, należy zapoznać się z tytułowymi określeniami, którymi są WALIDACJA oraz FILTROWANE.

Warto wskazać różnicę pomiędzy terminami – oba odnoszą się do zagadnienia związanego z prawidłowo podawanymi informacjami, jednak pojęcia te z punktu widzenia programistycznego nie są tożsame. Walidacja polega na weryfikacji podanych informacji porównując je ze swojego rodzaju schematem – wyrażeniem regularnym lub pod kątem wspełnienia określonych wymogów. Stosowanie wyrażeń regularnych jest bardziej zawansowaną czynnością, zatem kurs ten nie będzie ich obejmował. Proste mechanizmy walidacji dostracza HTML, bowiem tworząc dowolne pole (input) musimy określić czy będzie ono typu tekstowego, numerycznego czy mailowego, jendak najczęściej nie jest to wystarczające, zatem należy się wspomóc językiem PHP, który zawiera funkcję 'filter_var()’.

Wykorzystanie funkcji prezentuje się następująco: filter_var(’sprawdzanyCiagZnakow’, stała), gdzie 'stała’ może przyjmować wartości, które określają weryfikację poprawności dla:

  • FILTER_VALIDATE_EMAIL – adresu e-mail,
  • FILTER_VALIDATE_FLOAT – liczby zmiennoprzecinkowej,
  • FILTER_VALIDATE_INT – liczby całkowitej,
  • FILTER_VALIDATE_IP – adresu IP,
  • FILTER_VALIDATE_URL – adresu WWW

Sprawdźmy jak funkcja działa w praktyce, do tego celu posłużymy się prostym przykładem, który opierać się będzie na weryfikacji adresu internetowego, do wglądu w zwracaną wartość wykorzystajmy funkcję var_dump(…).

        <?php
            $adresWWW='http://septemonline.com';
            var_dump(filter_var("$adresWWW", FILTER_VALIDATE_URL));

            //Wynik zwrócony przez funkcję
            string(23) "http://septemonline.com"
        ?>
    

Teraz przetestujmy scenariusz błędnego podania adresu WWW.

        <?php
            $adresWWW='http:\\septemonline,com';
            var_dump(filter_var("$adresWWW", FILTER_VALIDATE_URL));

            //Wynik zwrócony przez funkcję
            bool(false)
        ?>
    

Fitracja natomiast opiera się na unieszkodliwieniu wprowadzonych przez użytkownika potencjalnie niebezpiecznych ciągów znaków. Stosowną czynność zapewni nam już poznana we wcześniejszej częsci kursu funkcja. Poniżej zaprezentowane zostało przykładowe użycie.

        <?php
            $adresMailowy='jankowalski@domena.pl';
            var_dump(filter_var("$adresMailowy", FILTER_SANITIZE_EMAIL));

            //Wynik zwrócony przez funkcję
            string(21) "jankowalski@domena.pl"
        ?>
    

Sprawdźmy co się stanie, gdy do adresu mailowego dopiszemy htmlowski tag, który odpowiedzialny jest ze przejście do nowej lini:

        <?php
            $adresMailowy='jankowalski@domena.pl';
            var_dump(filter_var("$adresMailowy", FILTER_SANITIZE_EMAIL));

            //Wynik zwrócony przez funkcję
            string(23) "jankowalski@domena.plbr"
        ?>
    

Jak więc widzimy, neutralizacja tagu została przeprowadzona po przez usunięcie jego kluczowych elementów, dodatkowo warto zauważyć, iż nieprawidłowy adres mailowy zostałby zapisany w bazie danych.

Innym sposobem na przefiltrowanie lub zwalidowanie informacji przed dalszym przetwarzaniem jest funkcja filter_input($typ, $informacja, $filtr, $opcje) gdzie:

  • $typ – określa metodę przekazania informacji: INPUT_GET lub INPUT_POST, dostępne są także INPUT_COOKIE ,INPUT_SERVER oraz INPUT_ENV
  • $informacja – zmienna, której wartość ma zostać poddana procesowi filtracji,
  • $filtr – stała, określająca rodzaj zastosowanego filtru (przykładowe filtry zostały zaprezentowane we wcześniejszej części kursu)
  • $opcje – opcjonalne, dodatkowe parametry.

Jak można wywnioskować metoda filter_input(…), oprócz przefiltrowania pozwala także na przechwycenie wartości, co umożliwia zredukowanie ilości kodu czyniąc go bardziej czytelnym.

Spróbujmy wypróbować funkcję filter_input na przykładzie. Po pierwsza stworzymy maksymalnie prosty formularz.

        
            <form method="POST">
                <input type="text" name="exampleInput" value="" />
                <input type="submit" value="Wyślij" />
            </form>
        
    

Wykorzystamy ten formularz aby przesłać dane do analizowanych funkcji. W formularzu wpiszemy wartość liczbową „123” a następnie pobierzemy i sprawdzimy czy jest to wartość liczbowa oraz czy jest to poprawny adres url.

        
            var_dump(filter_input(INPUT_POST,'exampleInput', FILTER_VALIDATE_FLOAT));
            //float(123)
            var_dump(filter_input(INPUT_POST,'exampleInput', FILTER_VALIDATE_URL));
            //bool(false)
        
    

Jak napisać własny filtr – kod pocztowy

Kluczem do niestandardowego filtra jest FILTER_CALLBACK. Możemy pisać własne filtry wedle własnych potrzeb. Do tego celu potrzebna będzie wcześniej nabyta wiedza o wykorzystaniu funkcji w PHP.

W tym przykładzie spróbujemy sobie napisać własny filtr sprawdzający czy użytkownik wpisał poprawnie kod pocztowy. Zacznijmy od stworzenia funkcji.

        
            function checkZip(string $zip) {
                $numbers = [0,1,3,4,5];
                if($zip[2] != '-'){
                    return false;
                }
                foreach($numbers as $index){
                    if(!is_numeric($zip[$index])){
                        return false;
                    }
                }
                return $zip;
            }
        
    

Po kolei. Tworzymy funkcję o nazwie checkZip która pobiera parametr w postaci ciągu znaków.

Ciąg znaków to nic innego jak tablica znaków, tak więc najprostszym sposobem będzie sprawdzenie po kolei jakie znaki wypisał użytkownik. Definiujemy w tablicy które znaki z ciągu powinny być liczbami, zakładamy też że na drugi miejscu w ciągu powinien być myślini ponieważ spodziewamy się że użytkownik wpisza kod w postaci „00-000” czyli dwie liczby, myślnik, trzy liczby.

Sprawdzamy czy myślnik jest we właściwym miejscu, jeśli nie to zwracamy false jak to ma miejsce w przypadku innych filtrów standardowych. Dalej puszczamy pętlę po indeksach ciągu wcześniej zdefiniowanych i w podobny sposób sprawdzamy każdy znak.

Jeśli pierwsze sześć znaków to kod pocztowy to zwracamy te znaki ucinając wszystko co jest dalej.

Teraz spróbujmy wykorzystać funkcję w naszym filtrze:

        
            $zip = filter_input(INPUT_POST, 'exampleInput', FILTER_CALLBACK, ['options' => 'checkZip']);
            var_dump($zip);
        
    

Powyższy przykład zadziała w następujący sposób:

  1. Jeśli wpiszemy nieprawidłowy ciąg znaków to zwróci nam „false”
  2. Jeśli wpiszemy na początku poprawny kod a dalej zbędne znaki to zostaną one obcięte
  3. Jeśli wpiszemy poprawny kod pocztowy to po porstu pobierzemy ten kod

Co dalej?

To by było na tyle w tej części.

Jak dla mnie to gdzieś tak jedna trzecia z tematu filtrowania i pobierania danych z formularzy, jednak w większosci przypadkó może okazać się wystarczająca. Za dwie lekcje w części o bazach dowiemy się po co te danne filtrować a za trzy lekcje w części o obsłudze wyjątków dowiemy się jak to lepiej obsłużyć. Good luck.