Zaawansowane przetwarzanie formularzy przy użyciu PHP i JavaScript.

  1. Dla kogo przeznaczony jest ten artykuł
  2. Wymagana wiedza
  3. Wprowadzenie
  4. Czym jest a czym nie jest JavaScript
  5. Wykorzystanie JavaScript do zmniejszania ruchu na stronie
  6. A co jeśli przeglądarka nie obsługuje JavaScript?
  7. Przekazywanie danych z PHP do JavaScript
  8. Użycie wyrażeń regularnych
  9. Wskazówki - przetwarzanie danych
  10. Wskazówki - projektowanie formularza
  11. Przykłady kodu
  12. Podsumowanie

1. Dla kogo przeznaczony jest ten artykuł

Artykuł ten jest przeznaczony dla średniozaawansowanych programistów PHP, którzy wiedzą jak używać formularzy do zbierania informacji, potrafią je przechowywać w bazie danych lub plikach jednorodnych ale nie mają doświadczenia w sprawdzaniu poprawności tych danych.

2. Wymagana wiedza

  • Znajomość podstaw działania protokołu HTTP.
  • Znajomość podstaw JavaScript.
  • Doświadczenie w tworzeniu formularzy HTML.

3. Wprowadzenie

Budując stronę internetową, wcześniej czy później będziesz potrzebować formularzy, które są najlepszym sposobem na zbieranie informacji od użytkowników. Możesz używać prostych formularzy jak np. do logowania lub rozbudowanych służących np. do rejestracji użytkowników, w których trzeba wpisać dużo danych. Oczywiście im większy formularz, tym więcej informacji jest do przetworzenia i tym większe wyzwanie dla twórcy.

Sprawdzając dane wprowadzone do formularza trzeba pamiętać o dwóch najistotniejszych kwestiach: złośliwych użytkownikach oraz zbieraniu możliwie jak największej ilości danych o nich. Mimo że pojęcia te wydają się sprzeczne ze sobą (z jednej strony chcesz zbierać jak najwięcej informacji, z drugiej zaś nakładasz różne ograniczenia z obawy przed złośliwymi użytkownikami), to można je jednak pogodzić. Wystarczy przedsięwziąć kilka środków ostrożności aby wyeliminować 95% niebezpieczeństw, jednocześnie zmuszając użytkowników do wprowadzenia do formularza potrzebnych nam informacji.

Istnieje wiele narzędzi służących walidacji danych przekazywanych za pomocą formularza. Są to narzędzia działające zarówno po stronie serwera jak i po stronie klienta. Do najbardziej rozpowszechnionych narzędzi działających po stronie klienta należą języki skryptowe, a w szczególności JavaScript, która umożliwia przetwarzanie danych przed wysłaniem ich do serwera.

Po stronie serwera wystarczy PHP. Ale należy pamiętać o tym, że niektóre pospolite błędy w kodzie PHP mogą mieć fatalne skutki. Więcej szczegółów na ten temat można znaleźć w artykułach na stronie zend.com, zatytułowanych: Coding Mistakes Part I, II, III.

4. Czym jest a czym nie jest JavaScript

JavaScript jest bardzo popularnym jezykiem skryptowym działającym po stronie klienta, używanym do kontrolowania obiektów na stronach www. Kod JavaScript dołącza się bezpośrednio do kodu HTML. JavaScript przerywa swoje działanie dopiero w momencie wysłania nowego zapytania do serwera. Efekty działania skryptu widoczne są do momentu wysłania do serwera - dlatego jest to język typu client-side (działający po stronie klienta). Fakt, że przy pomocy JavaScript nie można uzyskać dostępu do systemu plików na maszynie klienta, sprawia, że jest to język skryptowy a nie programistyczny. JavaScript używany jest tylko do obsługi obiektów na stronach www.

JavaScript nie jest narzędziem bezpieczeństwa ponieważ kod zostaje wysłany w całości do klienta. JavaScript używany jest natomiast do oszczędzania zasobów serwera. Skrypty wykonywane po stronie klienta i bezpieczeństwo to dwie przeciwności z założenia.

Zasady są skuteczne tak długo jak długo się ich przestrzega. Zasady JavaScript zostały przygotowane dla użytkowników, którzy nie mają złych intencji. Ale, jeśli trafi się złośliwy użytkownik, który bez skrupółów zechce się wedrzeć do twojego systemu, to wykorzysta on wszelkie luki, o których zapomniałeś w trakcie tworzenia strony.

5. Wykorzystanie JavaScript do zmniejszania ruchu na stronie

JavaScript pozwala na kontrolowanie obiektów HTML na stronie www, włączając w to formularze. Dzięki JavaScript można zminimalizować zużycie transferu serwera.

Pomyśl o takiej sytuacji: masz stronę internetową, na której znajduje się formularz służący do logowania użytkowników, składający się z dwóch pól: nazwa użytkownika i hasło - żądne z nich nie może być krótsze niż 6 znaków. Masz dwa wyjścia: albo najpierw sprawdzić wprowadzane dane przy użyciu JavaScript a potem posłużyć się jeszcze PHP lub wszystko zrobić przy pomocy PHP. Rozważ następująca sytuację, w której użytkownik wpisał 5 znaków w pole username.

JavaScript + PHP


Serwer wysyła do klienta stronę HTML zawierającą kod JavaScript

Użytkownik wypełnia formularz

JavaScript sprawdza dane i wyświetla ostrzeżenie

Klient poprawia dane

Klient wysyła ponownie dane do serwera
PHP

Serwer wysyła strone www do klienta

Klient wypełnia formularz

Klient wysyła wypełniony formularz do serwera

Interpreter PHP sprawdza poprawność danych i znajduje błąd

Serwer z powrotem wysyła stronę do klienta z komunikatem o błędzie

Klient poprawia błąd

Klient wysyła formularz z powrotem do serwera

Ruch pomiędzy serwerem a klientem nastąpił w czterech miejscach (1, 3, 5, 7) przy użyciu samego PHP i tylko w dwóch miejscach przy użyciu PHP i JavaScript. (patrz przykład kodu nr 4)

Czy obciążenie serwera ma znaczenie? Jeśli PHP pracuje jako CGI to za każdym wywołaniem skryptu tworzony jest plik wykonywalny co zużywa pamięć oraz zajmuje moc obliczeniową procesora. Po zakończeniu wykonywania skryptu, plik ten jest niszczony a zasoby zostają zwolnione. Wykonywanie kilku skryptów PHP jednocześnie zazwyczaj nie powoduje przeładowania serwera, chyba że istnieje ogromna liczba uruchomionych jednocześnie instancji PHP. Czas potrzebny do wykonania skryptów PHP mierzony jest w milisekundach, a zużycie zasobów można obserwować przy użyciu menedżera zadań w Windows lub przy pomocy komendy ps -ef | grep php w systemach unixowych.

Wydajność serwera należy wziąść pod uwagę gdy:

  • przewiduje się wielu użytkowników na stronie jednocześnie,
  • dysponuje się ograniczonymi zasobami (ograniczenia sprzętowe, parametry hostingu itd.)

W przypadku serwerów o średnich parametrach, wydajność nie jest problemem. Dzięki czemu, użycie JavaScript nie ma wpływu na obciążenie serwera. Najważniejszym czynnikiem mającym wpływ na funkcjonowanie strony ma transfer.

6. A co jeśli przeglądarka nie obsługuje JavaScript?

Mimo, że JavaScript nie jest obsługiwany przez każdą przeglądarkę, to jest on jednak dostępny we wszystkich nowoczesnych aplikacjach. Problem w tym, że można go łatwo wyłączyć z powodów bezpieczeństwa. Co się stanie gdy JavaScript zostanie wyłączony lub użytkownik w jakiś sposób oszuka skrypt (np. wysyłając dane pomijając formularz)?

Przed dopuszeczniem do wysłania danych należy zawsze upewnić się czy:

  • formularz został wyświetlony i wypełniony
  • JavaScript sprawdził wszystkie dane wprowadzone do formularza

Jeżeli przeglądarka nie obsługuje JavaScript to formularz nadal będzie wyświetlany ale procedury JavaScript nie zadziałają. Aby zabezpieczyć się przed tego typu sytuacjami można użyć znacznika HTML <noscript>, w którym określa się co ma być wyświetlone przez przeglądarki nieobsługujące skryptów. Przy pomocy tego znacznika można wyeliminować zarówno użytkowników korzystających z bardzo starych przeglądarek jak i tych, którzy celowo wyłączyli obsługę JavaScript.

Następna rzecz, o której należy pamiętać,to żeby nie używać przycisku typu SUBMIT do wysyłania formularza:

<input type="submit" value="ok" onClick= "check_form(this);">

Bo jeżeli tak zrobimy to formularz zostanie wysłany bez względu na to co zwróci JavaScript. Lepiej jest używać obiektu BUTTON z odpowiednią obsługą zdarzeń przypisaną do właściwej funkcji:

<input type="button" value="ok" onClick="check_form(this);">

Zapis taki spowoduje wywołanie funkcji sprawdzającej dane i wysyłającej je do serwera tylko w przypadku gdy nie zawierają one żadnych błędów.

Aby sprawdzić czy formularz został rzeczywiście wypełniony, a nie wysłany przez jakąś inną aplikację lub ręcznie, można użyć metody obrazkowej. (Zobacz stronę rejestracyjną na hotmail.com). Na stronie Zend.com znajduje się tutorial dotyczący tej techniki.

! W walce z wszelkiego rodzaju intruzami twoim najlepszym przyjacielem jest zawsze PHP. Nawet jeśli zastosowałeś JavaScript, nigdy nie pomijaj PHP, który jest najbardziej niezawodnym sposobem sprawdzania danych.

7. Przekazywanie danych z PHP do JavaScript

Czasami zachodzi potrzeba ponownego użycia danych po stronie klienta. Istnieją dwa sposoby na przekazanie ich z PHP do JavaScript. Pierwszy sposób to wstawienie kodu PHP do znacznika <noscript>:

<?php
$user_id
= $_GET["uid"];
?>


<script language="JavaScript1.2">
var user_id=<?php echo($user_id);?>;
alert("Twój identyfikator to:" + user_id);
</script>

Drugi sposób to wstawienie do formularza pola ukrytego i ustawienie jego wartości przy pomocy PHP. JavaScript może odwoływać się do tej wartości.

<?php
$user_id
= $_GET["uid"];
?>


<script language="JavaScript1.2">
    // Dzięki id masz bezpośredni dostęp do wartości obiektu
    alert("Twój identyfikator to:" + p2j.value);
</script>

<body bgcolor="#ffffff">
<input type="hidden" id= "p2j" value=" <?php echo ($user_id); ?> ">

8. Użycie wyrażeń regularnych

Bardzo często, przy przetwarzaniu danych z formularza, zachodzi konieczność wykonywania skomplikowanych operacji na łańcuchach znaków. Wyrażenia regularne (regexp w skrócie) są potężnym narzędziem służącym do wyszukiwania części ciągów i ich modyfikacji. Wyrażenia regularne dostępne są w prawie każdym środowisku, od PHP po JavaScript i od MySQL po sam UNIX. Wyrażenia te, mimo że różnią się sposobem implementacji, ogólnie rzecz biorąc są do siebie bardzo podobne pod względem logiki. Więcej informacji na temat wyrażeń regularnych można znaleźć w odpowiednich dokumentacjach.

Zazwyczaj, stosowanie wyrażeń regularnych wiąże się z podaniem większej ilości danych, ale wykonywanie bardzo skomplikowanych modyfikacji łańcuchów znaków, które normalnie wymagałyby użycia wielu bloków kodu z pętlami itd., można zapisać w kilku linijkach. Z drugiej jednak strony, użycie zbyt wielu wyrażeń regularnych może spowodować nadmierne obciążenie serwera. Dlatego właśnie tak ważna jest umiejętność rozpoznawania sytuacji, w których należy ich używać.

W PHP dostępne są dwa rodzaje wyrażeń regularnych: wyrażenia w stylu Perl i wyrażenia w stylu POSIX 1003.2. Wyrażenia w stylu Perl mają kilka zalet w porównaniu z wyrażeniami w stylu POSIX.

Tworzenie obiektów regexp w JavaScript podobne jest do tworzenia definicji zmiennych. Zapisanie zmiennej pomiędzy znakami slash oznacza, że ma być ona przechowywana jako objekt regexp i można na niej wykonywać wszelkie operacje dostępne dla tego typu obiektów. Innym sposobem jest utworzenie instancji klasy theYes. Objekt RegExp.

Składnia wyrażenia regularnego w JavaScript przedstawia się następująco:

regexp.test(string);

Gdzie regexp jest łańcuchem, na którym zostanie wykonana operacja. Metoda ta sprawdza czy w podanym łańcuchu istnieje określony wzór i zwraca true jeśli prawda lub false w przeciwnym przypadku (zobacz przykładowy kod 3).

9. Wskazówki - przetwarzanie danych

Sprawdzając dane wprowadzone przez użytkownika, należy pamiętać, że ilość znaków nie jest jedynym kryterium (spacje też są traktowane jako znaki). Aby mieć lepszą kontrole nad wprowadzanymi danymi:

  • Wielokrotne spacje zamieniaj zawsze na pojedyncze przy użyciu wyrażeń regularnych. Zasada ta jest szczególnie ważna gdy dane umieszczane są w tablicy przy użyciu funkcji explode, gdzie znakiem rozdzielającym jest właśnie spacja. Wielokrotne spacje spowodują powstanie kluczy z pustymi wartościami (zobacz przykładowy kod 1 i 2).
  • Na porównywanych ciągach zawsze używaj funkcji trim przed rozpoczęciem porównywania. W JavaScript nie ma funkcji trim. Zobacz funkcje przedstawione poniżej. (przykładowy kod 5).
  • Sprawdzaj typ danych w polach. W PHP dostępne są bardzo użyteczne funkcje do tego służące, np.: is_numeric, is_string, is_integer itd.
  • Cudzysłowy i inne znaki specjalne (procent, podkreślenie, średnik itd.) mogą powodować problemy z komendami SQL. Należy zawsze używać funkcji PHP addslashes przed wysłaniem zapytania SQL, jako że w JavaScript funkcja taka nie jest dostępna. Funkcja addslashes dodaje ukośniki ("/") do znaków specjalnych (łącznie z wartością null), dzięki czemu traktowane są one jak zwykłe znaki. W systemach baz danych zarezerwowano nie tylko znaki specjalne ale także niektóre słowa, np.: CREATE, DROP, ALTER, DELETE, GRANT, REVOKE.
  • Ogólną zasadą programowania jest, zatrzymywanie wszelkich wyjątków w kodzie, czyli nie należy dopuszczać do sytuacji, w której użytkownik widzi na monitorze wiadomość o błędzie. Aby zmylić niedoświadczonych włamywaczy, można zastosować wyświetlanie informacji przypominających te wyświetlane przez system operacyjny:

    $db_conn = mysql_query('localhost', 'u', 'p') or die ( 'ADO Connection Error 0x80000922: Microsoft Jet Engine couldn\'t be started'); // Co do diabła robi tutaj ADO?

    $recs = @mysql_query($sql, $db_conn) or die ('ADO Recordset Error 0x800A0BCD: Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record.');
  • Jedną z oznak próby włamania jest napływ danych, przy użyciu nieoczekiwanych metod. Nieoczekiwane zmienne też nie należą do rzeczy przyjemnych. Zamiast pisać $zmienna lepiej jest posługiwać się wersją: $_POST['zmienna'] lub $_REQUEST['zmienna']. Zawsze należy określać metodę przechowywania danych. Czasami może się zdarzyć, że metod tych jest więcej niż jedna. W takim przypadku należy ustawić je w kolejności:

    // Jeśli dostępne są dane z metody POST to należy ich użyć, w przeciwnym wypadku użyj danych z metody GET
    $name = isset ($POST['name'] ) ? trim ( $_POST['name'] ) : trim ($_GET[ 'name'] );
  • Jeśli nie zostało zaznaczone jakieś pole to funkcja isset zwróci wartość false. Dlatego zawsze przed sprawdzeniem wartości pola należy sprawdzić czy zostało ono wogóle wypełnione.

    if (isset($_POST['Przeczytaj licencję'])) {
        if ($_POST['Przeczytaj licencję'] == "Y") {
             echo "Użytkownik zaakceptował postanowienia licencji.";

10. Wskazówki - projektowanie formularza

  • Zawsze określaj maksymalną ilość znaków, które można wpisać do pola tekstowego. Dzięki temu unikniesz niespodziewanych błędów.
  • Jeśli chcesz aby wartość pola była wyświetlona bez możliwości jej zmiany przez użytkownika, stosuj atrybut READONLY oraz ustaw wartość atrybutu TABINDEX na -1. (Jeśli zastosujesz pole typu HIDDEN to nie zostanie ono wogóle wyświetlone).

    <input type="text" name= "price" readonly tabindex= "-1">
  • Jeśli w formularzu znajdzie się kilka pól o tej samej nazwie, to PHP zaakceptuje to pole, które występuje w kodzie jako ostatnie. W przypadku gdy chcesz utworzyć tablicę wartości, umieszczaj nawiasy kwadratowe "[ ]" (bez cudzysłowów) po atrybucie "name" każdego pola. (Zobacz przykładowy kod 6).

11. Przykłady kodu

  1. Zamienianie ciągów przy użyciu wyrażeń regularnych w PHP.

    <?php
    // Zamienianie wielokrotnych spacji na pojedyncze

    $result = ereg_replace ( "\s+", " ", $_POST ['sentence']);
    echo ('Old String:'.$_POST['sentence'] . '\n');
    echo ('New String:'.$result. '\n');
    ?>

  2. Zamienianie ciągów przy użyciu wyrażeń regularnych w JavaScript.

    <SCRIPT LANGUAGE="JavaScript1.2">
    var r, re;

    // Ciąg znaków do sprawdzenia
    var s= "23th  University  Summer  Olympic   Games  is  going  to  be  organized  by   city  of  Izmir  in  2005." ;

    // Wyrażenie regularne. Maskuje co najmniej jedną spację w zakresie globalnym.
    re = /\ s+/g ;

    // Zamień wielokrotne spacje na pojedyncze.
    r = s.replace(re, " ");

    // Wyświetl wyniki
    alert("Old string:\n"+s);
    alert("New string:\n"+r);
    </SCRIPT>

    Uwaga: Pamiętaj, aby po końcowym znaku slash (/) zawsze dodawać "g" (global search), jeśli chcesz zamienić wszystkie pasujące do warunku ciągi. Jeśli tego nie zrobisz, to funkcja replace zamieni tylko pierwsze pasujące wyrażenie.
  3. Dopasowywanie ciągów przy użyciu wyrażeń regularnych w JavaScript.

    <SCRIPT LANGUAGE="JavaScript1.2">
    // Pierwszy sposób definiowania wyrażeń regularnych
    // Widzisz parametry za drugim slashem ?
    // i: i g:global search
    // To wyrażenie regularne oznacza 5 znaków numerycznych
    var re_zip1 = /[0-9]{5}/ig;

    // ... i drugi.
    var re_zip2 = new RegExp("/[0-9]{5}/", "ig");

    // Testowanie. Proszę o uwagę.
    alert(re_zip1.test("35140"));  // prawda (true). Wszystkie numeryczne i 5 cyfr.
    alert(re_zip1.test("3510"));   // fałsz. Wszystkie numeryczne ale tylko 4 cyfry.
    alert(re_zip2.test("a5140" ));   // fałsz. 5 znaków ale nie wszystkie numeryczne.
    </SCRIPT>

  4. Typowy kod HTML i JavaScript służący do sprawdzania danych przed wysłaniem.

    <HTML>
    <
    HEAD>
        <
    TITLE>Sample Form</TITLE>
    </
    HEAD>

    <
    SCRIPT LANGUAGE="JavaScript1.2">
        
    //Obiekt formularza
        
    var f=document.forms(0);
        
    // Boolen to track if error found
        
    var foundErr;
        
    // Numer elementu formularza, w którym wystąpił pierwszy błąd.
        
    var focusOn;
        
        function
    check_form() {
            
    foundErr = false; focusOn = -1;
            
    // Pole "Nazwa użytkownika" musi składać się z conajmniej 6 znaków
            
    if (f.user.value.length<6) {
                
    alert ("Za krótka nazwa użytkownika.");
                
    foundErr = true; focusOn = 0;
            }
        
            
    // Hasło musi składać się z co najmniej 6 znaków.
            
    if (f.pass.value.length<6) {
                
    alert("Za krótkie hasło");
                
    foundErr = true;
                if (
    focusOn==-1) focusOn=1;
            }
        
            
    // Czy wystąpił jakiś błąd?
            
    if (foundErr) {
                
    //Tak. Skup się na pierwszym napotkanym.
                
    f.elements.focus(focusOn);
            } else {
                
    // Nie. Wyślij formularz.
                
    f.submit();
            }
        }
    </SCRIPT>

    <BODY BGCOLOR="#FFFFFF">    
        <
    FORM ACTION="check.php" METHOD="post">
        <
    TABLE BORDER="0" WIDTH="100%" CELLSPACING="0" CELLPADDING="0">
            <
    TR>
                <
    TD WIDTH="30%" ALIGN="right">Username</TD>
                <
    TD WIDTH="70%">: <INPUT TYPE="text" NAME="user"></TD>
            </
    TR>
            <
    TR>
                <
    TD ALIGN="right">Password</TD>
                <
    TD>:<INPUT TYPE="password" NAME="pass"></TD>
            </
    TR>
            <
    TR>
                <
    TD>&nbsp;</TD>
                <
    TD><INPUT TYPE="button" VALUE="Submit" onClick="check_form();"></TD>
            < /
    TR>
        </
    TABLE>
        </
    FORM>
    </
    BODY>
    </
    HTML>

  5. Przykład użycia funkcji "trim" w JavaScript.

    <SCRIPT LANGUAGE="JavaScript1.2">
    function
    trimmer(pVal) {
        
    TRs=0;
        for (
    i=0; i<pVal.length; i++) {
            if (
    pVal.substr(i,1)==" ") {TRs++;} else {break;}
        }

        
    TRe=pVal.length-1;
        for (
    i=TRe; i>TRs-1;i--) {
            if (
    pVal.substr(i,1)==" ") {TRe--;} else {break;}
        }

        return (
    pVal.substr(TRs, TRe-TRs+1));
    }
    </SCRIPT>

  6. Zaisywanie wartości wielu pól typu checkbox do tablicy jeśli nazwy nie są w nawiasach;

    ...
    <INPUT TYPE="checkbox" NAME="s" VALUE="A" CHECKED>Checkbox 1<BR>
    <
    INPUT TYPE="checkbox" NAME="s" VALUE="B">Checkbox 2<BR>
    <
    INPUT TYPE="checkbox" NAME="s" VALUE="C">Checkbox 3<BR>
    ...

    skrypt przetwarzający

    <?php
    echo '<PRE>('.(gettype($_POST['s']).') ';
    print_r($_POST['s']);
    ?>

    zwróci:

    (string) A

    Ale jeśli dodasz [] po nazwie każdego elementu,

    ...
    <INPUT TYPE="checkbox" NAME="s[]" VALUE="A" CHECKED>Checkbox 1<BR>
    <
    INPUT TYPE="checkbox" NAME="s[]" VALUE="B">Checkbox 2<BR>
    <
    INPUT TYPE="checkbox" NAME="s[]" VALUE="C">Checkbox 3<BR>
    ...

    ten sam kod zwróci:

    (array)
    Array (
        [
    0] => A
        
    [1] => B
        
    [2] => C
    )

    gdzie widać, że wszystkie trzy pola są zaznaczone.

Podsumowanie

Jednym z najgorszych błędów, jakie można popełnić przy przetwarzaniu danych z formularza jest niesprawdzenie ich poprawności. Błędy dzielą się na dwie kategorie:

  • Błędy pospolite: to błędy popełniane w wyniku nieuwagi, bezmyślności lub przeoczenia. Jeśli wiesz, że 2 + 2 = 4, a na egzaminie napiszesz 5 to jest to właśnie błąd pospolity.
  • Błędy logiczne: są zazwyczaj rezultatem ignorancji, niedouczenia lub złośliwego działania. Jeśli rzeczywiście myślisz, że 2 + 2 = 5 to popełniasz błąd logiczny.

Powyższa klasyfikacja błędów odnosi się także do wypełniania forumlarzy. Zwykli odwiedzający zapewne będą popełniać błędy pospolite, które można wyeliminować przy użyciu JavaScript. Nie należy jednak oczekiwać nic więcej od JavaScript poza wstępnym przygotowaniem danych do wysłania. Aby obronić się przed błędami logicznymi, w szczególności powodowanymi przez złośliwych użytkowników, musisz użyć PHP.

Metody i wskazówki pokazane w tym artykule są tylko wstępem do bardziej zaawansowanych technik przetwarzania formularzy. Podczas tworzenia bardziej złożonych formularzy będziesz potrzebować więcej metod sprawdzania danych. Nie zapomnij podzielić się nimi z innymi!


Autor: Mehmet Avsar
Data: 6.08.2003
Tłumaczenie: Łukasz Piwko
Oryginalna wersja artykułu znajduje się pod adresem http://www.zend.com/zend/tut/tutorial-mehmet2.php