andbin
07-09-2007, 12:52
Premessa
Devo gestire un form un pochino più complesso dei "soliti" form di contatto che ho già fatto diverse volte in passato.
Dal momento che la gestione e la validazione dei dati di un form è una cosa abbastanza noiosa che ho già fatto svariate volte e che in futuro farò certamente altre volte, stavo pensando di realizzare un piccolo framework di classi specifiche per PHP 5 (tanto PHP 4 se non è ancora morto, lo sarà a breve tempo...).
Pensavo di fare una classe base FormField e poi una serie di classi derivate, ognuna per gestire un tipo specifico di campo (di testo, di testo per una email, di <select>, di password, ecc....). Più eventualmente alcune classi di utility e per tenere dati "globali".
In genere la gestione/validazione la faccio con del codice PHP un pochino, per così dire, sparpagliato.
if (isset ($_POST['blabla']))
{
$blabla = $_POST['blabla'];
.....
}
e poi nel corpo del <form> faccio cose del tipo:
<input type="text" name="blabla" size="40" maxlength="40" value="<?php echo htmlspecialchars ($blabla, ENT_QUOTES); ?>">
Indubbiamente molto noioso. Ma ancora più noioso quando ci sono delle <select> con le sue <option>, in quanto per ognuna delle option devo stabilire se è quella a cui mettere l'attributo 'selected'.
Il framework
Al momento ho già scritto 2 classi, quella base e una sottoclasse. Sono solo un abbozzo per il momento, ma funzionano.
Ecco il codice:
abstract class FormField
{
private $name;
private $value;
private $submitted;
private $required;
private $attributes;
function __construct ($name, $required, $defvalue="")
{
$this->name = $name;
$this->required = $required ? TRUE : FALSE;
$this->attributes = array ();
if (isset ($_POST[$this->name]))
{
$this->submitted = TRUE;
if (get_magic_quotes_gpc ())
$this->value = stripslashes ($_POST[$this->name]);
else
$this->value = $_POST[$this->name];
}
else
{
$this->submitted = FALSE;
$this->value = $defvalue;
}
}
function getName () { return $this->name; }
function getValue () { return $this->value; }
function isSubmitted () { return $this->submitted; }
function isRequired () { return $this->required; }
function isValid ()
{
if (!$this->isSubmitted ())
return !$this->isRequired ();
else
return $this->validate ();
}
function validate () { return TRUE; }
function addAttribute ($name, $value)
{
$this->attributes[(string) $name] = (string) $value;
}
function outputHTML () { }
protected function outputAttributes ()
{
$a = "";
foreach ($this->attributes as $k => $v)
{
if ($a != "")
$a .= " ";
$a .= $k . "=\"" . htmlspecialchars ($v, ENT_QUOTES) . "\"";
}
return $a;
}
}
class EmailFormField extends FormField
{
function __construct ($name, $required, $size, $maxlength, $defvalue="")
{
parent::__construct ($name, $required, $defvalue);
$this->addAttribute ("size", (int) $size);
$this->addAttribute ("maxlength", (int) $maxlength);
}
function validate ()
{
if (eregi ("^[a-z0-9\._-]+@[a-z0-9\._-]+(\.[a-z]{2,3}){1,2}$", $this->getValue ()))
return TRUE;
else
return FALSE;
}
function outputHTML ()
{
echo "<input type=\"text\" name=\"" .
htmlspecialchars ($this->getName (), ENT_QUOTES) .
"\" " . $this->outputAttributes () . " value=\"" .
htmlspecialchars ($this->getValue (), ENT_QUOTES) .
"\">\r\n";
}
}
A quel punto in una pagina php mi basterebbe scrivere:
$fld_email = new EmailFormField ("email", TRUE, 30, 60);
....uso isValid().....
<form .....>
<?php $fld_email->outputHTML (); ?>
E mi sembra che sia già molto più semplice e pulito. Che ne pensate?
Ci sarebbero poi delle informazioni, da memorizzare in qualche modo, che riguardano la pagina nella sua globalità, cioè ad esempio: il charset utilizzato o se la pagina è HTML o XHTML o ancora la sequenza di newline da mandare in output. Potrei fare una classe con campi statici accessibili tramite getter/setter.
Ma ci sarebbero anche informazioni relative al form: potrei volerlo inviare come GET piuttosto che come POST. In tal caso stavo pensando di creare una classe che contiene le informazioni su un form. Visto che in uno script gestisco solo un form per request, pensavo di usare anche qui dei campi static con getter/setter.
In definitiva: avete idee, suggerimenti? Cosa ne pensate delle mie scelte? Mi interessa più che altro capire se il "design" è quello giusto oppure se è una delle classiche scemenze che scrivo.
Se poi avete esperienze specifiche riguardo la validazione di form in PHP, magari se avete usato dei framework già pronti per queste cose, fatemi sapere.
Naturalmente, ringrazio fin da ora per qualunque risposta.
Devo gestire un form un pochino più complesso dei "soliti" form di contatto che ho già fatto diverse volte in passato.
Dal momento che la gestione e la validazione dei dati di un form è una cosa abbastanza noiosa che ho già fatto svariate volte e che in futuro farò certamente altre volte, stavo pensando di realizzare un piccolo framework di classi specifiche per PHP 5 (tanto PHP 4 se non è ancora morto, lo sarà a breve tempo...).
Pensavo di fare una classe base FormField e poi una serie di classi derivate, ognuna per gestire un tipo specifico di campo (di testo, di testo per una email, di <select>, di password, ecc....). Più eventualmente alcune classi di utility e per tenere dati "globali".
In genere la gestione/validazione la faccio con del codice PHP un pochino, per così dire, sparpagliato.
if (isset ($_POST['blabla']))
{
$blabla = $_POST['blabla'];
.....
}
e poi nel corpo del <form> faccio cose del tipo:
<input type="text" name="blabla" size="40" maxlength="40" value="<?php echo htmlspecialchars ($blabla, ENT_QUOTES); ?>">
Indubbiamente molto noioso. Ma ancora più noioso quando ci sono delle <select> con le sue <option>, in quanto per ognuna delle option devo stabilire se è quella a cui mettere l'attributo 'selected'.
Il framework
Al momento ho già scritto 2 classi, quella base e una sottoclasse. Sono solo un abbozzo per il momento, ma funzionano.
Ecco il codice:
abstract class FormField
{
private $name;
private $value;
private $submitted;
private $required;
private $attributes;
function __construct ($name, $required, $defvalue="")
{
$this->name = $name;
$this->required = $required ? TRUE : FALSE;
$this->attributes = array ();
if (isset ($_POST[$this->name]))
{
$this->submitted = TRUE;
if (get_magic_quotes_gpc ())
$this->value = stripslashes ($_POST[$this->name]);
else
$this->value = $_POST[$this->name];
}
else
{
$this->submitted = FALSE;
$this->value = $defvalue;
}
}
function getName () { return $this->name; }
function getValue () { return $this->value; }
function isSubmitted () { return $this->submitted; }
function isRequired () { return $this->required; }
function isValid ()
{
if (!$this->isSubmitted ())
return !$this->isRequired ();
else
return $this->validate ();
}
function validate () { return TRUE; }
function addAttribute ($name, $value)
{
$this->attributes[(string) $name] = (string) $value;
}
function outputHTML () { }
protected function outputAttributes ()
{
$a = "";
foreach ($this->attributes as $k => $v)
{
if ($a != "")
$a .= " ";
$a .= $k . "=\"" . htmlspecialchars ($v, ENT_QUOTES) . "\"";
}
return $a;
}
}
class EmailFormField extends FormField
{
function __construct ($name, $required, $size, $maxlength, $defvalue="")
{
parent::__construct ($name, $required, $defvalue);
$this->addAttribute ("size", (int) $size);
$this->addAttribute ("maxlength", (int) $maxlength);
}
function validate ()
{
if (eregi ("^[a-z0-9\._-]+@[a-z0-9\._-]+(\.[a-z]{2,3}){1,2}$", $this->getValue ()))
return TRUE;
else
return FALSE;
}
function outputHTML ()
{
echo "<input type=\"text\" name=\"" .
htmlspecialchars ($this->getName (), ENT_QUOTES) .
"\" " . $this->outputAttributes () . " value=\"" .
htmlspecialchars ($this->getValue (), ENT_QUOTES) .
"\">\r\n";
}
}
A quel punto in una pagina php mi basterebbe scrivere:
$fld_email = new EmailFormField ("email", TRUE, 30, 60);
....uso isValid().....
<form .....>
<?php $fld_email->outputHTML (); ?>
E mi sembra che sia già molto più semplice e pulito. Che ne pensate?
Ci sarebbero poi delle informazioni, da memorizzare in qualche modo, che riguardano la pagina nella sua globalità, cioè ad esempio: il charset utilizzato o se la pagina è HTML o XHTML o ancora la sequenza di newline da mandare in output. Potrei fare una classe con campi statici accessibili tramite getter/setter.
Ma ci sarebbero anche informazioni relative al form: potrei volerlo inviare come GET piuttosto che come POST. In tal caso stavo pensando di creare una classe che contiene le informazioni su un form. Visto che in uno script gestisco solo un form per request, pensavo di usare anche qui dei campi static con getter/setter.
In definitiva: avete idee, suggerimenti? Cosa ne pensate delle mie scelte? Mi interessa più che altro capire se il "design" è quello giusto oppure se è una delle classiche scemenze che scrivo.
Se poi avete esperienze specifiche riguardo la validazione di form in PHP, magari se avete usato dei framework già pronti per queste cose, fatemi sapere.
Naturalmente, ringrazio fin da ora per qualunque risposta.