Kontrola formulářových údajů v PHP

4. dubna 2003

Pokud požíváte na svých webech formuláře, víte, jak je mnohdy pracné všechny zadané údaje kontrolovat. Nabízím vám PHP třídu, která tuto „otrockou“ práci udělá za vás. Vy jen zadáte pravidla.

A co všechno to umí?

Třída provádí se vstupními daty tyto operace:

  • Převod na potřebný formát (například konverze data v českém národním formátu na ISO).
  • Kontrola, zda má údaj správný formát (například správný formát emailové adresy).
  • Předání upravených dat a případných chyb k dalšímu zpracování.

Popis metod a vlastností

getUserData

Hlaví metodou celé třídy je getUserData([array idata]). Má jeden nepovinný parametr „idata“, ve kterém se předávají vstupní data. Pokud parametr nezadáte, berou se data z globální proměnné $_REQUEST.

data

Po zavolání metody getUserData se toto asociativní pole naplní zpracovanými údaji. Jako klíč se použije název parametru a hodnotou je hodnota parametru.

errors

Pokud vstupní data nemají správný formát, naplní se toto pole informacemi o chybách. Jako klíč se použije název parametru a hodnotou je kód chyby.

rules

Toto pole obsahuje „instrukce“, co se se vstupními parametry má provádět. Pole indexované klíči, které jsou shodné s názvy vstupních parametrů. Každý prvek pole obsahuje další pole s těmito indexy:

  • convert – určuje jak se má parametr zpracovat (na jaký typ se má převést)
    • int – hodnota bude převedena na celé číslo
    • float – hodnota bude převedena na desetinné číslo
    • trim – z řetězcové hodnoty budou oříznuty bílé znaky na začátku a konci řetězce
    • date_cz2iso – hodnota zapsaná jako datum v českém formátu (DD.MM.RRRR) bude převedena na datum ve formátu ISO (RRRR-MM-DD)
    • function – hodnota bude převedena pomocí vámi definované funkce, jejíž název je uložen v klíči check.function; funkce bude volána takto: nazev_funkce(string name, array data), řetězec name určuje název parametru pro převod, v poli data se předávají aktuální hodnoty parametrů
  • check – určuje, jak má parametr vypadat, aby mohl být považován za „bezchybný“
    • is_fill – zkontroluje, zda je hodnota vyplněna (není prázdný řetězec)
    • check_date – zkontroluje, zda je zadané datum ve formátu ISO platné (například 2003-02-31 není platné datum)
    • is_eq – zkontroluje, zda je hodnota shodná s hodnotou parametru, který je uložen v klíči check.is_iq (například kontrola hesla při registraci)
    • is_email – zkontroluje, zda má hodnota formát emailové adresy
    • ereg – zkontroluje, zda hodnota odpovídá regulárnímu výrazu (výraz je uložen v klíči check.ereg)
    • preg – zkontroluje, zda hodnota odpovídá perlovskému regulárnímu výrazu (výraz je uložen v klíči check.preg)
    • function – hodnota bude zkontrolována uživatelskou funkcí, jejíž název je uložen v klíči check.function)

A teď ukázka

Vstupní formulář bude mít prvky email (musí obsahovat emailovou adresu), datum (musí obsahovat platné datum), heslo (musí být vyplněno), heslo_kontrola (musí být shodné s polem heslo), telefon (telefonní číslo v mezinárodním formátu +xxxxxxxxxxxx) a poznamka (nepovinná). Kód pro kontrolu tohoto formuláře bude následující:

<?php include ‚user_data_checker.class.php‘; # vlozi soubor se tridou
$kontrola = new tUserDataChecker; // vytvori instanci tridy  
$kontrola->rules = array(      // nadefinuje pravidla
  ‚email‘ => array(            // pravidla pro pole email
    ‚convert‘ => ‚trim‘,       // odstran pripadne bile znaky
    ‚check‘ => ‚is_email‘      // zkontroluj emailovou adresu
  ),
  ‚datum‘ => array(            // pravidla pro pole datum
    ‚convert‘ => ‚date_cz2iso‘,// pro snazsi zpracovani preved na iso
    ‚check‘ => ‚check_date‘    // zkontoluj platnost datumu
  ),
  ‚heslo‘ => array(            // pravidla pro pole heslo
    ‚check‘ => ‚is_fill‘       // zkontoluj, zda je heslo vyplneno
  ),
  ‚heslo_kontrola‘ => array(   // pravidla pro pole heslo_kontrola
    ‚check‘ => ‚is_eq‘,        // zkontoluj, zda je pole shodne s …
    ‚check.is_eq‘ => ‚heslo‘   // … polem heslo
  ),
  ‚telefon‘ => array(          // pravidla pro pole telefon
    ‚check‘ => ‚ereg‘,         // zkontoluj, zda je pole odpovida …
    ‚check.ereg‘ => ‚^\+([0-9]{12})$‘  
  ),                           // … regularnimu vyrazu
  ‚poznamka‘ => array()        // poznámka se nijak nekontroluje ani neupravuje ale musi byt zadana aby se jeji hodnota prenesla
);
$kontrola->getUserData($_POST);// data se prevezmou s pole $_POST

Po provedení tohoto kódu budou v $kontrola->data upravená data a pokud budou některá pole chybně vyplněna, v $kontrola->errors budou chybové kódy. Jaké budou výsledky při zadání různých vstupních údajů si můžete vyzkoušet.

Kód třídy s vysvětlením funkce

Nejprve nadefinujeme hlavičku a pole rules, data a errors:

<?php
class tUserDataChecker {
  var $rules = array();
  var $data = array();
  var $errors = array();
  function getUserData($idata = NULL) {
    // pokud není určeno odkud se mají data „brát“ použije se pole $_REQUEST
    if ($idata == NULL) $idata = &$_REQUEST;
    foreach ($this->rules as $name => $rule) {
      $this->data[$name] = $idata[$name];
      $value = &$this->data[$name];
      // konverze

Tato část funkce převádí proměnné na požadovaný typ. Pro převod na číselný typ int nebo float používáme normální přetypování pomocí $novy = (typ)$puvodni, k oříznutí bílých znaků používáme funkci trim a pro převod data regulární výrazy.

Jistě jste si všimli konstrukce $value = $rule['convert.function']($name, $data);. Pokusím se vysvětlit její princip: $rule['convert.function'] obsahuje název spouštěné funkce, ($name, $data) jsou parametry volané funkce ($name je jméno parametru a $data jsou všechna vstupní data) a $value = je přiřazení výsledku funkce proměnné.

      switch($rule[‚convert‘]) {
        case ‚int‘:      // převod na celé číslo
          $value = (int)$value;
          break;
        case ‚float‘:    // převod na desetinné číslo
          $value = (float)$value;
          break;
        case ‚trim‘:     // odstranění bílých znaků na konci a začátku
          $value = trim($value);
          break;
        case ‚function‘: // převod definovanou funkcí
          $value = $rule[‚convert.function‘]($name, $data);
          break;
        case ‚date_cz2iso‘: // převod datumu
          if (ereg (‚([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{4})‘,
                    $value, $regs)) {
            $value = sprintf(‚%04d-%02d-%02d‘,
                             $regs[3],$regs[2],$regs[1]);
          };
          break;
      };
      // kontrola

Tato část kódu kontroluje vstupní data, zda odpovídají zadaným kritériím. Pokud je nalezen chybný údaj, uloží se tato informace do pole errors. Kontrola shodnosti a naplněnosti pole se provádí jednoduše pomocí porovnání řetězců. Kontrola data se provádí ve dvou krocích, nejprve se údaj rozloží pomocí regulárního výrazu a poté se platnost data zkontroluje pomocí funkce checkdate. Pro kontrolu pomocí regulárních výrazů se používají funkce ereg, případně preg_match. Kontrola pomocí funkce je stejná, s tím rozdílem, že funkce vrací případný chybový kód.

      switch($rule[‚check‘]) {
        case ‚is_fill‘: // kontrola, zda je pole vyplneno
          if ($value == “) $this->errors[$name] = ‚empty‘;
          break;
        case ‚is_email‘: // kontrola, zda je email v platnem formatu
          if (!ereg(‚.+@.+\..+‘, $value))
                  $this->errors[$name] = ‚no_email‘;
          break;
        case ‚is_eq‘: // kontrola, zda je shodny s jinym polem
          if ($value != $idata[$rule[‚check.is_eq‘]])
             $this->errors[$name] = ‚no_eq‘;
          break;
        case ‚check_date‘ : // kontrola platnosti datumu
          if (ereg („([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})“,
              $value, $regs)) {
            if (!checkdate ($regs[2], $regs[3], $regs[1])) {
              $this->errors[$name] = ‚invalid_date‘;
            };
          } else {
              $this->errors[$name] = ‚invalid_date_format‘;
          };
          break;
        case ‚ereg‘ :
          if (!ereg ($rule[‚check.ereg‘], $value))
            $this->errors[$name] = ‚no_ereg‘;
          break;
        case ‚preg‘ :
          if (!preg_match ($rule[‚check.preg‘], $value))
            $this->errors[$name] = ‚no_ereg‘;
          break;
        case ‚function‘ :
          $e = $rule[‚check.function‘]($name, $data);
          if ($e) $this->errors[$name] = $e;
          break;
      };
    };
  }
}
?>

Třídu i s ukázkou si můžete stáhnout.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Předchozí článek Typografie webových stránek
Další článek sknovesedlice
Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *