Přidat článek mezi oblíbenéZasílat nové komentáře e-mailemZamknuto Ajax - Validácia formulárov: serverová časť

Doteraz sme sa zaoberali všeobecnými vlastnosťami Ajax aplikácií a podrobnejšie sme sa pozreli na prenos údajov prostredníctvom objektu XMLHttpRequest alebo skrytého elementu iframe. Dnes si od programovania v JavaScripte oddýchneme a vytvoríme jednoduché stránky v PHP, na ktorých si ukážeme validáciu údajov na strane servera. A keďže tomu venujeme jeden celý diel, tak to aspoň spravíme poriadne a podrobne.

V prvom rade si musíme povedať, čo vlastne chceme spraviť. Naším cieľom bude vytvoriť formulár pre vkladanie komentárov do diskusie, ktorý musí používateľ vyplniť. Ak nevyplní niektoré polia formuláru správne, bude na to upozornený. Ak prebehne všetko v poriadku, bude presmerovaný na inú (alebo tú istú) stránku. Príklad bude samozrejme spĺňať to, čo by mala spĺňať každá webová stránka - bude použiteľný aj bez JavaScriptu. Netrpezliví si môžu stiahnuť zdrojové kódy dnešného snaženia už teraz. My ostatní si aspoň môžeme pozrieť výsledok.

Ako vidíme, ide o klasické použitie formulára. Prečo v ňom chceme použiť Ajax? Napríklad preto, že okrem tohto formulára môže byť na stránke veľa iných údajov, ktoré sa pri nesprávnom vyplnení formulára musia zo servera prenášať znova. Môže ísť napríklad o formulár pre vloženie príspevku, ktorý sa nachádza na konci dlhého zoznamu komentárov.

Keď implementujeme tento formulár tak, aby fungoval bez JavaScriptu, budeme chcieť doplniť validáciu formulára použitím Ajaxu. Preto je dobré si dopredu premyslieť, ako to vlastne bude fungovať.

Pri odosielaní formulára sa zavolá obslužná funkcia napísaná v JavaScripte, ktorá odošle požiadavku na server a zabráni odoslaniu formulára bežným spôsobom. Odoslaná požiadavka bude v sebe obsahovať všetky údaje, ktoré boli vyplnené vo formulári a bude zakódovaná rovnako, akoby ju poslal prehliadač. Skript na strane servera odlíši túto požiadavku pomocou parametra, ktorý nastavíme v URL adrese.

Odpoveď bude obsahovať informáciu o tom, ktoré polia sú nesprávne vyplnené a krátku správu, ktorá sa zobrazí pri nesprávne vyplnenom poli. Otázkou je, v akom formáte táto odpoveď bude zakódovaná. Možností je veľa a formát odpovede záleží len na nás. Mal by byť taký, aby sme ho vedeli v JavaScripte jednoducho spracovať. V tomto príklade bude formát odpovede rovnaký, aký používa pri odoslaní požiadavky prehliadač - páry meno=hodnota budú zakódované ako v URL. Meno bude obsahovať meno poľa formulára, ktoré obsahuje nejakú chybu a hodnota bude obsahovať textový opis chyby. V prípade, že budú všetky polia vyplnené správne, budeme chcieť používateľa presmerovať na ďalšiu stránku. Pre takúto situáciu potrebujeme ďalší typ správy, ktorý odlíšime tým, že na jej začiatku bude dvojbodka.

Vkladanie komentárov

Spôsobov, ako napísať skript pre vkladanie komentárov do diskusie, je veľa. V našom príklade použijeme návrhový vzor Model-View-Controller (MVC), ktorý sa vo webových aplikáciách často používa. Znamená to, že budeme mať tri oddelené vrstvy: Kontroler (angl. controller) na základe požiadavok od používateľa zmení model (angl. model) a vyberie pohľad (angl. view).

PHP skripty v tomto príklade používajú skrátené tagy pre označenie časti s kódom PHP (namiesto

<?php

je len

<?

). Zvolil som tento spôsob, pretože najmä pri definovaní pohľadu zvyšuje čitateľnosť kódu. Musím preto zdôrazniť, že ak je server nastavený tak, aby skrátené tagy nepodporoval, bude potrebné tieto tagy prepísať na ich dlhší ekvivalent alebo upraviť nastavenie pomocou súboru

.htaccess

(ak je to možné). Rovnako predpokladám, že je vypnuté otravné vkladanie spätných lomítok do informácií prijatých od používateľa (

magic_quotes_gpc off

).

Model

Najprv si pripravíme triedu pre objekty, ktoré budú predstavovať komentáre. Objekty tejto triedy budú obsahovať metódu na skontrolovanie, či sú všetky vlastnosti správne nastavené. V skutočnej aplikácii by tu mohli byť ešte metódy na načítanie vlastností z databázy a tiež aj ich vloženie do databázy. Kód triedy umiestnime do samostatného súboru

comment.php

:

<?

class Comment
{
	var $nick;
	var $mail;
	var $text;

	function Comment ()
	{
	}
	
	function validate ()
	{
		$errors = array ();

		$nick_length = strlen (trim ($this->nick));

		if (!$nick_length)
			$errors ["nick"] = "je povinná";
		elseif ($nick_length < 3)
			$errors ["nick"] = "musí mať aspoň 3 znaky";

		if (strlen (trim ($this->text)) == 0)
			$errors ["text"] = "je povinný";
		
		return $errors;
	}
}

?>

S týmto objektom budeme ďalej pracovať. Pri odoslaní formulára ho potrebujeme jednoducho naplniť podľa vyplnených údajov. Vytvoríme si na to pomocnú funkciu

set_object_vars

, ktorá nastaví vlastnosti objektu podľa asociatívneho poľa. Jej použitie bude vyzerať nasledovne:

$comment = new Comment ();
set_object_vars ($comment, array ("nick" => "NN", "text" => "Nejaky text"));

Tento kód vytvorí objekt pre nový komentár a nastaví jeho vlastnosti

nick

a

text

podľa zadaných hodnôt. Pri vhodnom pomenovaní prvkov formulára budeme môcť do tejto funkcie posielať priamo asociatívne pole z premennej

$_POST

. Nasleduje implementácia samotnej pomocnej funkcie:

function set_object_vars (&$object, $parameters, $allowed = false)
{
	$class		= get_class ($object);
	$class_vars	= get_class_vars ($class);
	
	if ($class_vars):
		if (!$allowed)
			$allowed = array_keys ($class_vars);

		if ($parameters)
			foreach ($parameters as $var => $value)
				if (array_key_exists ($var, $class_vars) and in_array ($var, $allowed))
					$object->$var = $value;
	endif;
}

Táto funkcia naplní vlastnosti objektu podľa hodnôt v asociatívnom poli. Posledným nepovinným argumentom tejto funkcie je pole, pomocou ktorého môžeme obmedziť nastavovanie vlastností. Hoci v našom príklade toto obmedzovanie nevyužijeme, vo svojej aplikácii zrejme nebudete chcieť povoliť nastavovanie úplne všetkých vlastností objektu podľa vstupu používateľa.

Všetky pomocné funkcie, ktoré sa využívajú viackrát, budeme písať do súboru

helper.php

. Zatiaľ do tohto súboru teda umiestníme funkciu

set_object_vars

.

Pohľad

Dohromady vytvoríme dva pohľady. Prvý bude formulár, ktorý sa zobrazí v prehliadači. Druhým pohľadom bude odpoveď servera na požiadavku klienta vytvorenú JavaScriptom.

Každý pohľad môže dostať od kontrolera nejaké parametre. Napríklad pohľad pre zobrazenie komentára potrebuje vedieť, ktorý komentár má vlastne zobraziť. Kontroler zobrazí pohľad volaním funkcie

render_page

, ktorej prvým argumentom bude súbor s pohľadom a druhý argument bude obsahovať parametre pohľadu. Vybraný pohľad sa k parametrom dostane volaním funkcie

get_params

. Obe funkcie umiestnime do súboru s pomocnými funkciami:

function render_page ($page, $params = false, $exit = false)
{
	$GLOBALS ["params"] = $params;

	include $page;
	
	if ($exit)
		exit ();
}

function get_params ()
{
	return $GLOBALS ["params"];
}

Formulár

Nasledujúci pohľad definuje to, čo uvidí používateľ. Zobrazí formulár, do ktorého treba zadať prezývku, e-mail a text príspevku. V parametroch dostane komentár, ktorý má zobraziť a pole chybových správ. Tento pohľad uložíme do súboru

add-html.php

:

<?
	$params = get_params ();
	$comment = $params ["comment"];
	$errors = $params ["errors"];
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
	<head>
		<meta http-equiv="content-type" content="text/html;charset=utf-8" />
		<title>Formulár</title>
		<link href="master.css" type="text/css" rel="stylesheet" />
	</head>
	<body>
		<h1>Formulár</h1>
		<form action="" method="post" class="ajax">
			<dl>
				<dt>
					<label for="nick">Prezývka <?=html_error ($errors, "nick", "je povinná")?></label>
				</dt>
				<dd>
					<input type="text" id="nick" name="comment[nick]" value="<?=htmlspecialchars ($comment->nick)?>" />
				</dd>
				<dt>
					<label for="mail">E-mail</label>
				</dt>
				<dd>
					<input type="text" id="mail" name="comment[mail]" value="<?=htmlspecialchars ($comment->mail)?>" />
				</dd>
				<dt>
					<label for="text">Text <?=html_error ($errors, "text", "je povinný")?></label>
				</dt>
				<dd>
					<textarea id="text" name="comment[text]" rows="12" cols="40"><?=htmlspecialchars ($comment->text)?></textarea>
				</dd>
			</dl>
			<p>
				<input type="submit" />
			</p>
		</form>
	</body>
</html>

Pri vytváraní pohľadu sme použili funkciu

html_error

. Jej úlohou je vypísať chybové hlásenie. V prípade, že nenastala žiadna chyba, vypíše informáciu, ktorú jej pošleme v poslednom nepovinnom argumente.

function html_error ($errors, $name, $info = false)
{
	if (isset ($errors [$name]))
		return '<em class="error">' . htmlspecialchars ($errors [$name]) . '</em>';
	elseif ($info)
		return '<em class="info">' . htmlspecialchars ($info) . '</em>';

	return "";
}

Odpoveď servera

Keď pošle požiadavku na server JavaScript, kontroler vyberie druhý pohľad, ktorý bude obsahovať informáciu zakódovanú tak, ako sme špecifikovali na začiatku článku. Tento pohľad bude v súbore

add-ajax.php

:

<?
	$params = get_params ();
	$errors = $params ["errors"];

	$response = array ();

	foreach ($errors as $name => $value)
		$response [] = url_pair ("comment[$name]", "$value (ajax)"); 

	if (!empty ($response))
		echo implode ("&", $response);
	else
		echo ":add.php";
?>

Pri definovaní tohto pohľadu sme použili funkciu

url_pair

, ktorá vytvorí z mena a hodnoty URL-zakódovaný reťazec. Táto pomocná funkcia bude rovnako ako všetky ostatné zapísaná v súbore

helper.php

:

function url_pair ($name, $value)
{
	return str_replace ("+", "%20", urlencode ($name)) . "=" . str_replace ("+", "%20", urlencode ($value));
}

Kontroler

Poslednou časťou tohto príkladu je samotná logika vkladania komentára, ktorú definujeme v kontroleri:

<?
	require_once "helper.php";
	require_once "comment.php";

	$comment = new Comment ();
	$errors = array ();
	
	if (isset ($_POST ["comment"]) and is_array ($_POST ["comment"])):
		set_object_vars ($comment, $_POST ["comment"]);
		$errors = $comment->validate ();

		if (isset ($_GET ["ajax"]))
			render_page ("add-ajax.php", array ("comment" => $comment, "errors" => $errors), true);
		elseif (empty ($errors))
			redirect_to ("add.php");
	endif;
	
	render_page ("add-html.php", array ("comment" => $comment, "errors" => $errors));
?>

Logika kontrolera je celkom jasná. Najprv sa vytvorí objekt pre komentár a pole pre chybové hlásenia. V prípade, že používateľ formulár vyplnil, skontrolujeme, či bol komentár vyplnený správne. Ak je požadovaná odpoveď pomocou Ajaxu (požiadavka má nastavený parameter

ajax

), kontroler vyberie na to určený pohľad. Ak nenastali žiadne chyby, presmerujeme klienta na inú adresu. Pokiaľ sa ešte nevybral pohľad alebo nenastalo presmerovanie, zobrazíme pohľad s formulárom.

V kontroleri sme použili pomocnú funkciu

redirect_to

. Táto funkcia presmeruje klienta na inú stránku. Jednoduchá verzia tejto funkcie by mohla vyzerať takto:

function redirect_to ($url)
{
	header ("Location: $url");
	
	exit ();
}

V skutočnej aplikácii by sme posielali v hlavičke

Location

absolútnu cestu tak, ako to vyžaduje špecifikácia.

Takto by mohla vyzerať časť pre vkladanie komentárov na strane servera. Môžete si stiahnuť celú serverovú časť dnešného príkladu a vyskúšať u seba, že robí to, čo má. Vyplnený komentár sa síce nezapisuje do databázy alebo do súboru, ale ukazuje validáciu komentára a pri nesprávne vyplnených poliach vypisuje správy pre používateľa.

Záver

V tejto časti seriálu o Ajaxe sme síce o Ajaxe veľa nehovorili, ale pripravili sme si serverovú časť aplikácie pre pridávanie komentárov. Validáciu zadaných údajov zabezpečuje jediná funkcia. V ďalšej časti seriálu rozšírime tento príklad o JavaScript tak, aby prebehla validácia a spracovanie hodnôt po odoslaní formulára technikou Ajax, pričom sa na validáciu použije tá istá funkcia, takže nebude potrebné písať validačnú funkciu viackrát.

Předmět Autor Datum
docela koukam ze no comments .. no ja tomu nerozumim :) ale i tak ocenuju tuto pracicku :beer:
MKc 20.12.2006 12:29
MKc
Já zase oceňuju ty jednotlivé moduly a pohledy jako bonus. Pro začátečníka to ovšem není .... :-| poslední
Flash_Gordon 29.12.2006 17:47
Flash_Gordon

Zpět na články Nahoru