Niezalogowany (Zaloguj się)

Kategorie

Vanilla 1.0.3 jest produktem Lussumo. Więcej informacji: Dokumentacja, Forum.

    • CommentAuthoradmirau
    • CommentTimeDec 27th 2006 zmieniony
     
    Ten przykład pokazuje, jak w PHP sprawdzić poprawność wypełnienia formularza HTML, a w razie błędnego wypełnienia, poinformować o tym użytkownika.

    1. Klasa PHP potrzebna do sprawdzania poprawności
    ---
    plik: Validate.php

    <code lang="php">
    <?php

    /**
    Projekt: Validate Class
    Plik: Validate.class.php
    Klasa do walidacji formularzy HTML

    Do sprawdzania poprawności, wykorzystuje zmodyfikowane funkcje z klasy SmartyValidate,
    których autorem jest Monte Ohrt.
    http://www.phpinsider.com/php/code/SmartyValidate/
    /*
    * @package Validate
    * @version 0.1
    */

    class Validate {

    function Validate(){
    $this->path='validators/';
    if (!session_id()) trigger_error ("Validate: Przed użyciem tej klasy,
    musisz wcześniej wykonać session_start()", E_USER_ERROR);
    }

    function setPath($path){
    $this->path=$path;
    }

    function connect($reset=false){
    if ($reset) unset($_SESSION['Validate']);
    }

    function disconnect(){
    unset($_SESSION['Validate']);
    }

    public function isValid($posted){
    $fields=$_SESSION['Validate']['fields'];

    $this->validateErrors=array();

    foreach($fields as $field=>$data){

    $criteria=$data['criteria'];
    $empty=$data['empty'];
    $params=$data['params'];
    $modifiers=$data['modifiers'];

    $value=$posted[$field];

    // tu można dorobić obsługę modyfikatorów

    $modarray=explode('|',$modifiers);
    foreach($modarray as $modifier)
    {
    switch(trim($modifier)){
    case 'stripslashes':
    $value=stripslashes($value);
    break;
    case 'striptags':
    $value=strip_tags($value);
    break;
    case 'quotes':
    $value=preg_replace("%(?<!\\\\)'%", "\\'", $value);
    break;
    default:
    }
    }

    // wstawienie do sesji zmiennych z post
    $fields[$field]['criteria']=$criteria;
    $fields[$field]['empty']=$empty;
    $fields[$field]['value']=$value;


    require_once ($this->path.'validate_criteria.'.$criteria.'.php');
    $function='validate_criteria_'.$criteria;

    $poprawne=$function($value,&$params,$empty);

    $fields[$field]['vaild']=$poprawne;
    if (!$poprawne==true) {
    $errors++;
    $this->ValidFields[]=$field;
    } else {
    $this->InvalidFields[]=$field;
    }
    $this->Errors[$field]=$poprawne;
    $this->Values[$field]=$value;
    }
    $_SESSION['Validate']['fields']=$fields;
    if($errors==0) return true;
    else return false;
    }

    function registerField($fieldname,$criteria,$params,$modifiers,$empty=true){
    $tab=$_SESSION['Validate'];
    $tab['fields'][$fieldname]['criteria']=$criteria;
    $tab['fields'][$fieldname]['empty']=$empty;
    $tab['fields'][$fieldname]['params']=$params;
    $tab['fields'][$fieldname]['modifiers']=$modifiers;
    $tab['fields'][$fieldname]['params']=$params;
    $tab['fields'][$fieldname]['modifiers']=$modifiers;
    $_SESSION['Validate']=$tab;
    if (empty($this->Errors[$fieldname])) $this->Errors[$fieldname]=true;
    if (empty($this->Values[$fieldname])) $this->Values[$fieldname]='';
    }

    function getData(){
    return $_SESSION['Validate'];
    }

    function setData(){
    $_SESSION['Validate']=$this->_data;
    }

    }

    // uwaga: klasa nie ma obsługi błędów,
    // jeśli jest Ci potrzebna, musisz ją dopisać sam

    ?>
    </code>

    Funkcja 'isValid' wykorzystuje zewnętrzne pliki, które trzymam w katalogu /validators/ w tym samym miejscu co klasę Validate.php

    Przykład takiego pliku wygląda tak:


    ---
    plik: validate_criteria.isEmail.php

    <code lang="php">
    <?php
    function validate_criteria_isEmail($value, &$params, $empty) {

    if(strlen($value) == 0)
    return $empty;

    // można podać kilka adresów oddzielonych znakami nowej linii
    $_addresses = preg_split('![\n\r]+!', $value);

    foreach($_addresses as $_address) {
    $_is_valid = !(preg_match('!@.*@|\.\.|\,|\;!', $_address) ||
    !preg_match('!^.+\@(\[?)[a-zA-Z0-9\.\-]+\.([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$!', $_address));

    if(!$_is_valid)
    return false;
    }
    return true;
    }

    ?>
    </code>

    lub tak:

    ---
    plik: validate_criteria.isRegExp

    <code lang="php">

    <?php
    function validate_criteria_isRegExp($value, &$params, $empty) {
    if(isset($params['field2'])) {
    $_exp = $params['field2'];
    } elseif (isset($params['expression'])) {
    $_exp = $params['expression'];
    } else {
    trigger_error("SmartyValidate: [isRegExp] brakuje parametru 'expression'");
    return false;

    }
    if(strlen($value) == 0)
    return $empty;

    return (preg_match($_exp, $value));
    }
    </code>

    Czyli mam następującą strukturę plików:

    _lib/PHPTAL.php
    _lib/Validate.php
    _lib/validators/validate_criteria.isEmail.php
    _lib/validators/validate_criteria.isRegExp.php


    Można bardzo łatwo rozszerzyć funkcjonalność tej klasy,
    dodając kolejne funkcje zwracające true/false do katalogu validators.

    Uwaga: nazwy plików powinny mieć następujący format:

    validate_criteria.NazwaKryterium.php

    a nazwy funkcji:

    function validate_criteria_NazwaKryterium($value, &$params, $empty){
    };


    Resztę funkcji możesz przygotować sam,
    lub przerobić te, które są dostarczane razem ze SmartyValidate
    • CommentAuthoradmirau
    • CommentTimeDec 27th 2006
     
    cd.

    2. Plik formularza HTML

    plik: formularz5.php

    <code lang="xml">
    <?xml version="1.0"?>
    <html>
    <head>
    <title>
    przykladowy
    </title>
    </head>
    <body>
    <form id="formularz" name="formularz" method="post" action="">

    <label for="imie">Imię: </label>
    <input id="imie" name="imie" type="text" value="" />
    <br />

    <label for="email">E-mail: </label>
    <input id="email" name="email" type="text" value="" />
    <br />

    <label for="www">WWW: </label>
    <input id="www" name="www" type="text" value="" />
    <br />

    <label for="gg">numer gg: </label>
    <input id="gg" name="gg" type="text" value="" />
    <br />

    <label for="data">data: </label>
    <input id="data" name="data" type="text" value="" />
    <br />

    <input type="submit" name="submint" value="OK" />

    </form>
    </body>

    </html>
    </code>

    Przerabiamy plik, na szablon PHPTAL, dodając znaczniki tal, w ten sposób,
    aby po powtórnym wyświetleniu formularza, znalazły się w nim już wpisane wcześniej wartości (value):

    <code lang="xml">
    <?xml version="1.0"?>
    <html>
    <head>
    <title tal:content="title">
    przykladowy
    </title>
    </head>
    <body>
    <form id="formularz" name="formularz" method="post" action="">

    <label for="imie">Imię: </label>
    <input tal:attributes="value values/imie" id="imie" name="imie" type="text" value="" />
    <br />

    <label for="email">E-mail: </label>
    <input tal:attributes="value values/email" id="email" name="email" type="text" value="" />
    <br />

    <label for="www">WWW: </label>
    <input tal:attributes="value values/www" id="www" name="www" type="text" value="" />
    <br />

    <label for="gg">numer gg: </label>
    <input tal:attributes="value values/gg" id="gg" name="gg" type="text" value="" />
    <br />

    <label for="data">data: </label>
    <input tal:attributes="value values/data" id="data" name="data" type="text" value="" />
    <br />

    <input type="submit" name="submint" value="OK" />

    </form>
    </body>

    </html>
    </code>

    Teraz jeszcze musimy dodać wyświetlanie informacji w przypadku błędnego wyświetlania formularza.

    Czyli dla każdego pola formularza, wstawiamy warunek tal:condition

    <code lang="xml">
    <span tal:condition="not: errors/data">nieprawidłowa data w formacie dd-mm-rrrr</span>
    </code>

    Czyli ostatecznie,
    nasz przykładowy szablon będzie wyglądał tak:

    ---
    plik: formularz5.php
    <code lang="xml">
    <?xml version="1.0"?>
    <html>
    <head>
    <title tal:content="title">
    przykladowy
    </title>
    </head>
    <body>

    <form id="formularz" name="formularz" method="post" action="">

    <label for="imie">Imię: </label>
    <input tal:attributes="value values/imie" id="imie" name="imie" type="text" value="" />
    <span tal:condition="not: errors/imie">2-25 znaków</span>
    <br />

    <label for="email">E-mail: </label>
    <input tal:attributes="value values/email" id="email" name="email" type="text" value="" />
    <span tal:condition="not: errors/email">nieprawidłowy email</span>
    <br />

    <label for="www">WWW: </label>
    <input tal:attributes="value values/www" id="www" name="www" type="text" value="" />
    <span tal:condition="not: errors/www">nieprawidłowy adres www</span>
    <br />

    <label for="gg">numer gg: </label>
    <input tal:attributes="value values/gg" id="gg" name="gg" type="text" value="" />
    <span tal:condition="not: errors/gg">nieprawidłowy numer gg</span>
    <br />

    <label for="data">data: </label>
    <input tal:attributes="value values/data" id="data" name="data" type="text" value="" />
    <span tal:condition="not: errors/data">nieprawidłowa data w formacie dd-mm-rrrr</span>
    <br />

    <input type="submit" name="submint" value="OK" />

    </form>
    </body>

    </html>
    </code>
    • CommentAuthoradmirau
    • CommentTimeDec 27th 2006
     
    cd...

    3. Ostatnia rzecz - zebranie wszystkiego razem

    ---
    plik: formularz5.php

    <code lang="php">
    <?php
    session_start();

    require_once 'PHPTAL_config.php';

    require_once 'PHPTAL.php';

    require_once 'Validate.php';

    function printr($var){

    // bardzo przydatna funkcja do czytelnego drukowania tablic

    echo '<pre>';
    print_r($var);
    echo '</pre>';
    }


    class PHPTALx extends PHPTAL

    // rozszerzenie do klasy PHPTAL dodające nową fukcję ułatwiającą wyświetlanie szablonu
    // i ewentualną obsługę błędów

    {

    public function DisplayTemplate(){
    // wyświetlenie szablonu i ewentualne przechwycenie błędu
    // dorobić: info mailem do admina w razie draki
    try {
    echo $this->execute();
    }
    catch (Exception $e){
    echo $e;
    }
    }

    }

    define('FORM_TEMPLATE','formularz5.html');

    $template = new PHPTALx(FORM_TEMPLATE);

    $template->title="strona testowa";

    $validate=new Validate;

    if(empty($_POST) OR empty($_SESSION['Validate'])) {
    $validate->connect();
    // uwaga! - wyrażenia nieregularne w delimiterach / /
    $validate->registerField('imie','isRegExp',array('expression'=>'/^[a-zA-ZęóąśłżźćńĘÓĄŚŁŻŹĆŃ_-]{2,25}$/'),'stripslashes',false);
    // zarejestrowanie pól formularza i kryteriów sprawszania
    // registerField('nazwa_pola','nazwa_kryterium',parametry,modyfikatory,czy_wymagane);
    // false znaczy, że pole nie może być puste
    $validate->registerField('email','isEmail',$params,'stripslashes',false);
    $validate->registerField('data','isDate',$params,'stripslashes',false);
    $validate->registerField('www','isURL',$params,'stripslashes',false);
    $validate->registerField('gg','isNumber',$params,'stripslashes',false);
    $template->errors=$validate->Errors;
    $template->values=$validate->Values;
    $template->DisplayTemplate();
    } else {
    $validate->connect();
    if ($validate->isValid($_POST)){;
    $validate->disconnect();
    echo 'ok';
    } else {
    // błędy w walidacji
    $template->errors=$validate->Errors;
    $template->values=$validate->Values;
    // wyświetlenie pól prawidłowo wypełnionych
    //echo "prawidłowe<br />";
    //printr($validate->ValidFields);

    // wyświetlenie pól wypełnionych nieprawidłowo
    //echo "nieprawidłowe<br />";
    //printr($validate->InvalidFields);
    $template->DisplayTemplate();
    }
    }

    ?>
    </code>