Autor Zpráva
Dan Charousek
Profil
Dobré odpoledne,
dovolte mi prosím, abych vám představil svůj nejnovější počin Vall-Iho.

Vall-I je PHP třída, která slouží k validaci všech druhů formulářů. Určený je především pro menší soukromé projekty, které nepoužívají framework a vlastní formulářové třídy. Jeho hlavním účelem je zpříjemnit svému programátorovi programování při práci na validaci formulářů. To zda se mu to daří posuďte prosím sami. Zdrojový kód naleznete na GIThubu, na mém blogu, na kterém krátce o Vall-Im hovořím a kde ukazuji základní použití, nebo na mém pískovišti, kde naleznete i testovací formulář, na kterém si výstup Vall-Iho můžete vyzkoušet.

Abych nezůstal jen u vypisování odkazů, uvedl bych opravdu stručně základní použití i zde.

1) 3 soubory: index.php, form.php, valli.class.php

valli.class.php
Zdrojový kód Vall-Iho (třeba z githubu)

form.php
<form method="POST" id="myForm">
    <!-- id formuláře odpovídá id předaného konsturktoru třídy, name a data-name odpovídají označení inputu při předávání pravidel
           pomocí addRule() metody;
           class="VallIElement" je nezbytná pro označení elementu, se kterými má VallI pracovat
    -->
    <input type="text" name="data[username]" class="VallIElement" data-name="username"><br>
    <input type="password" name="data[password]" class="VallIElement" data-name="password"><br>
    <input type="submit" value="Odeslat">
</form>

index.php
<?php
    // načteme Vall-Iho
    require_once 'valli.class.php';

    // vytvoříme si nový objekt
    /**
     * @param string $formHTML - zdrojový kód formuláře
     * @param string $formID - hodnota atributu id formuláře
     */
    $valli = new VallI(file_get_contents("formular.php"), "myForm");

    // po odeslání formuláře:
    if(isset($_POST['data'])){

        // přidáme pravidla pro inputy:
        /**
         * @param string $inputName - odpovídá atributu data-name a name
         * @param array $rules - pole pravidel
         * @param aray $errorMsgs - pole chybových hlášek (pořadí odpovídá pravidlům)
         */
        $valli->addRule("username", ["required" => true], ["Vyplňte prosím jméno"]);
        $valli->addRule("password", ["minlength" => 6], ["Heslo musí být min. 6 znaků dlouhé"]);

        // validujeme
        if($valli->validate($_POST['data'])) {
            $msg = "Vall-I je s daty spokojen :)";
            // pomocí $valli->getData() bychom si mohli vypsat validovaná data
        } else {
            $msg = "Vall-Imu se data nelíbí :(<br>";
            // připojíme chybové hlášky:
            /**
             * @return array $errorMsgs
             */
             $msg .= implode("<br>", $valli->getErrorMsgs());

             //obnovíme správně zadaná data:
             /**
              * @param array $classes - css třídy pro validní a invalidní inputy
              * @param array $notToRestore - jména inputů, které se neobnoví (hesla, atp.)
              */
              $valli->restoreData(array(
                  "valid" => "validInputClass",
                  "invalid" => "invalidInputClass",
              ), array("password"));
        }

    }
?>
<!DOCTYPE html>
<html>
    <head><meta charset="utf-8"></head>
    <body>
         Zobrazíme formulář:
        <?=$valli->printForm()?>

        Pokud existuje $msg, vypíšeme:
    <?=(!empty($msg)?$msg:'')?>
    </body>
</html>

Co na něj říkáte? Máte nějaké připomínky, dotazy? Využili byste jej na nějaký svůj projekt? Chybí vám něco?
Budu rád za každý komentář, který mne a Vall-Iho posune o kus dál.

Přeji hezký den,
Dan
Edit: ještě přidávám seznam podporovaných validačních pravidel:

$rules = [
  "required" => true, // vyžaduje, aby byla položka vyplněna,
  "is" => "pes", // kontroluje, zda se hodnota rovná řetězci "pes"
  "is" => "{hesloZnovu}", // kontroluje zda odpovídá hodnotě z inputu "hesloZnovu"
  "isnt" => "pes", // opak "is"
  "regxp" => "~(.*)~", // kontroluje shodu se zadaným regulárním výrazem
  "maxlength" => 6, // maximální délka řetězce,
  "minlength" => 2, // minimální délka řetězce,
  "isurl" => true, // alias pro filter_var($url, FILTER_VALIDATE_URL)
  "isemail" => true, // alias pro filter_var($email, FILTER_VALIDATE_EMAIL)
  "filter" => FILTER_VALIDATE_*, // obecná varianta pro filter_var
  "number" => true, // alias pro is_numeric
  "own" => function($data) {  // vlastní ověřovací funkce, vrací true nebo false, podle toho, zda je splněna podmínka
      // pokud je číslo sudé
      if($data%2 == 0) {
        return true;
      } else {
        return false;
      }
      // zkráceně by šlo i
      return ($data%2 == 0);
  }

];
Lamicz
Profil
Upřímně nevím, co to má společného s Wall-E, ale budiž. Základní nedostatek vidím v chybějící dynamické validaci přes JS na straně klienta (např. nějakého inputu oproti existujícím datům přes AJAX)
BTW kdyby jsi spojil validaci s vykreslením přes stejnou třídu, tak by to bylo IMHO jednodušší a pohodlnější.
Dan Charousek
Profil
Validátor --zdrobnělina--> Valli -> Vall-I
Čti spíš počeštěle [vali] než-li anglicky [vól í]

Vall-I je původně navržen jako serverový validátor, ale o přidání validace na straně klienta budu uvažovat.
Napsat vlastní vykreslovací třídu, která by pokryla kompletně všechny formulářové prvky, mi nepřijde zrovna „jednodušší a pohodlnější

Vall-I je určen pro menší projekty, které neběží na nějakém frameworku a nepoužívají komplexní formulářové třídy. Já osobně u těhle knihoven nemám rád tu svázanost při vykreslování formuláře. Vím, že (jako např. u nette) je možné přepnout do manuálního vykreslovacího režimu a nastylovat si formulář dle sebe, ale to už mi potom formulářová třída funguje spíše jako samotný validátor. Pro tyto formuláře je určen Vall-I kompletně odděluje závislost od vykreslovací třídy a nechává programátorovi nad formulářem volnou ruku.
ProbablyYes
Profil
Dan Charousek:
Co na něj říkáte? Máte nějaké připomínky, dotazy? Využili byste jej na nějaký svůj projekt? Chybí vám něco?
Aktuálně nevyužil. Většinu pravidel není problém po krátkém googlení spatlat i bez větších znalostí - aktuálně je složitější implementace tvého řešení než vytvoření vlastního. Chybí složitější validace - například pro email, telefonní číslo, webovou stránku atp.
Alphard
Profil
Dan Charousek:
Já bych to sice nepužil, protože používám komplexnější řešení, ale napadlo mě jedno vylepšení.
Když už jdete cestou, že formulář je definovaný v html, bylo by zajímavé umožnit zapsání validačních pravidel přímo do formuláře. V té vaší ukázce např.
<form method="POST" id="myForm">
    <input type="text" name="data[username]" class="VallIElement" data-name="username" rule="required"><br>
    <input type="text" name="data[mail]" class="VallIElement" data-name="mail" rule="required mail"><br>
    <input type="text" name="data[phone]" class="VallIElement" data-name="phone" rule="phone"><br>
    <input type="submit" value="Odeslat">
</form>
nebo
<form method="POST" id="myForm">
    <input type="text" name="data[username]" class="VallIElement" data-name="username">
      <rule type="required" message="Vyplnění jména je povinné." />
    </input><br>
    <input type="text" name="data[mail]" class="VallIElement" data-name="mail">
      <rule type="required" message="Vyplnění e-mailu je povinné." />
      <rule type="mail" message="Zadaný email není ve správném formátu" />
    </input><br>
    <input type="submit" value="Odeslat">
</form>

V PHP kódu by se z validace potom mohlo stát prakticky jednořádkové volání.
Dan Charousek
Profil
ProbablyYes:
Většinu pravidel není problém po krátkém googlení spatlat i bez větších znalostí
To lze samozřejmě u všech pravidel. Z vlástní zkušenosti vím, že splácat něco dohromady není problém:

        if (isset($_POST['jmeno']) && $_POST['jmeno'] &&
                isset($_POST['email']) && $_POST['email'] &&
                isset($_POST['zprava']) && $_POST['zprava'] &&
                isset($_POST['rok']) && $_POST['rok'] == date('Y'))
        {
                // Sem přijde odeslání emailu
        }
Zdroj: www.itnetwork.cz/php/zaklady/zaklady-php-kontaktni-emailovy-formular/

Problém většinou nastává, když chceš pro každou validační podmínku vypsat vlastní chybovou hlášku. I zde na diskusi je občas k vidění směs podmínek, která se větví do všech stran a i autor sám se v ní sotva orientuje.To je hlavní účel Vall-Iho.

aktuálně je složitější implementace tvého řešení
Můžeš to nějak konkretizovat prosím?

Chybí složitější validace - například pro email, telefonní číslo, webovou stránku atp.
viz. seznam validačních pravidel - isemail, isurl
Na ověření telefonního čísla si můžeš napsat vlastní regxp pravidlo a v případě opravdu náročné validace můžeš využít own

Alphard:
Děkuji za tip, zní to jako dobrý nápad, zkusím na tom zapracovat a pak dám vědět, jak to dopadlo :)
Dan Charousek
Profil
Alphard:
Implementoval jsou tvou myšlenku. Nejjednodušší použití Vall-Iho vypadá nyní takto:

vali.class.php
// valli

formular.php
<form method="POST" id="myForm">

    <input type="text" name="data[username]" class="VallIElement" data-name="username"><br>
        <!-- name uvádí jakému inputu jsou pravidla určena -->
        <rules name="username">
            <rule name="required" content="true" message="Vyplňte prosím jméno">
        </rules>
        
    <input type="password" name="data[password]" class="VallIElement" data-name="password"><br>
        <rules name="password">
            <rule name="minlength" content="6" message="Heslo musí být minimálně 6 znaků dlouhé">
        </rules>
        
    <input type="submit" value="Odeslat">
    
</form>

index.php
<?php

    require_once 'valli.class.php';
    $valli = new VallI(file_get_contents("formular.php"), "myForm");

    if(isset($_POST['data'])){
 
         // alternativní forma přidávání
        /* $valli->addRule("username", ["required" => true], ["Vyplňte prosím jméno"]);
        $valli->addRule("password", ["minlength" => 6], ["Heslo musí být min. 6 znaků dlouhé"]); */
 
        // validujeme
        if($valli->validate($_POST['data'])) {
            // ok
        } else {
            // not ok
        }
 
    }
?>
<!DOCTYPE html>
<html>
    <head><meta charset="utf-8"></head>
    <body>
         Zobrazíme formulář:
        <?=$valli->printForm()?>
    </body>
</html>
Alphard
Profil
[#7] Dan Charousek
To je pořád moc složité. Proč v konstruktoru zadávat id, když si ho můžete vyparsovat?
A ten file_get_contents také není hezký, ten by se mohl volat interně.
A isset($_POST['data']) nahradit nějakým $valli->isSend(), které ale nebude povinné.
Předávat kopii superglobálního pole také není nutné (vím, že tohle jde proti principu DI, ale v tomto případě je to snad tolerovatelné; jestli formulář používá metodu get, ať knihovna zcela automaticky pracuje s $_GET).

Mělo by stačit
require_once 'valli.class.php';
$valli = new VallI('formular.html'); // změnil jsem formát na .html, php stejně nenaparsujete

if($valli->isValid()) {
    // ok
} else {
    // not ok
}

Vývojáře většinou nezajímá, jestli formulář nebyl odeslaný, nebo byl odeslaný chybně. Vypsání chybových hlášek a předvyplnění dříve zadaných hodnot by knihovna měla dělat zcela automaticky.

Do šablony formuláře by se ještě mohl předpřipravit nějaký seznam, kam se vypíší chybové hlášky.
Kubo2
Profil
Dan Charousek:
Tvoj projekt ma zaujal, a chcel by som ho pomôcť vyvíjať a využiť ho pri ďaľšom vývoji jedného môjho dlhodobejšieho projektu, no odkaz na GitHub končí 404 a nikde na blogu nepíšeš, či ten kód je možné voľne použiť. Rád by som sa ťa teda na to spýtal.
Dan Charousek
Profil
Kubo2:
Projekt jsem s GIThubu smazal, protože jsem lenivý a v současné době jsem nechtěl vývoj udržovat veřejně. VallI je samozřejmě volně k dispozici avšak na blogu se nenachází nejaktuálnější verze. Pokud by ses chtěl dozvědět víc, tak mě kontaktuj na email uvedený v mém profilu.

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: