jump to navigation

PHP – Passaggio di parametri organizzati gerarchicamente 9 Febbraio 2008

Posted by gianfrasoft in PHP.
Tags: , , , ,
trackback

Consideriamo un form che chiede all’utente di introdurre i propri dati anagrafici allo scopo di organizzarli in una struttura del tipo:

  • dati_personali
    • nominativo
    • età
    • indirizzo
      • via
      • civico
      • città

E’ facile individuare in questa struttura dati l’albero delle informazioni che pone le proprie radici nel nodo dati_personali e che realizza tre livelli di profondità. Questo albero contiene in totale 7 nodi organizzati in 3 livelli.

In questo articolo esamineremo come sia possibile costruire una pagina dinamica in PHP che sia in grado di raccogliere le informazioni introdotte dall’utente nell’ambito di un form, e di elaborarle nel pieno rispetto della loro struttura gerarchica, qualunque sia in form. Nella fattispecie, la pagina dinamica recupererà le informazioni introdotte dall’utente riorganizzandole nell’ambito una struttura ricorsiva composta da array associativi: ad ogni livello dell’albero verrà associato un array ottenendo, nel caso descritto sopra, tre array:

il primo array conterrà tre informazioni: nominativo di tipo stringa, età di tipo intero ed un array associativo relativo all’indirizzo; l’array dell’indirizzo conterrà a sua volta tre informazioni: via di tipo stringa, civico di tipo intero e città anch’esso di tipo stringa.

Per prima cosa va fissata una rappresentazione delle informazioni nell’ambito del form HTML che dia modi di stabilire il tipo e la gerarchia dei dati introdotti dall’utente, ciò perché possano essere correttamente processati dalla pagina PHP. Un modo per effettuare questa rappresentazione è quello di strutturare i nomi delle etichette di input in modo che contengano sia il nome del parametro di input che il tipo dello stesso separati da un carattere speciale, ad esempio:

string%nominativo

inoltre, per rendere possibile la gerarchia delle informazioni, verranno introdotti nei nomi delle etichette <input> una coppia di parentesi quadre per ogni livello di annidamento dell’informazione associando al livello il particolare tipo array. Nel caso delle informazioni anagrafiche descritte nella pagina precedente avremo infatti:

dati_personali[string%nominativo]
dati_personali[int%eta]
dati_personali[array%indirizzo][string%via]
dati_personali[array%indirizzo][int%civico]
dati_personali[array%indirizzo][string%citta]

Dalle informazioni riportate sopra possiamo dedurre che:

  • i tipi string, int ed array non devono necessariamente corrispondere ai tipi del PHP; essi rappresentano semplicemente un protocollo per la trasmissione di informazioni sul tipo dei dati e servono per un controllo dell’integrità da parte della pagina PHP;
  • ai dati che rappresentano dei “contenitori” di informazioni veine associato il tipo array;
  • le parentesi quadre aiutano a definire i differenti livelli di annidamento.

Ecco quindi come compare il testo della form HTML:

<form action="wsquery.php">
<p><font size="+2"><b>Lettura dei parametri:</b></font></p>
<table cellpadding="2" cellspacing="2"          border="1" width="100%">
<tr><td>Nominativo
<input type="text" name="dati_personali[string%nominativo]">
</td></tr>
<tr><td>Età
<input type="text" name="dati_personali[int%eta]">
</td></tr>
<tr><td>Indirizzo / via
<input type="text" name="dati_personali[array%indirizzo][string%via]">
</td></tr>
<tr><td>Indirizzo / civico
<input type="text" name="dati_personali[array%indirizzo][int%civico]">
</td></tr>
<tr><td>Indirizzo / città
<input type="text" name="dati_personali[array%indirizzo][string%citta]">
</td></tr>
<tr><td>
<input type="submit" name="button" value="Submit">
</td></tr>
</table>
</form> 

Nel form HTML appena descritto compare il nome della pagina dinamica “wsquery.php” che è proprio la pagina PHP che si occuperà del processamento dei dati.

La pagina “wsquery.php” sarà infatti caratterizzata dalla funzione principale array_map_deep riportata di seguito:

function array_map_deep($in_array)
{
  $out_array = array();
  if ($in_array != array())
  {
    foreach ($in_array as $key => $value)
    {
      // se il valore dell'array e' a sua volta un array attua la ricorsione
      if (is_array($value))
      {
        // elabora l'array contenuto "ricorsivamente"
        $temp = array_map_deep($value);
        // carica l'elaborazione nell'array di uscita
        $out_array[get_name($key)] = $temp;
      }
      else
      {
        // ricava il tipo dell'elemento nell'array in ingresso, fa il
        // cast del valore in esso contenuto e lo carica nell'array di uscita
        $out_array[get_name($key)] = set_the_type($value, get_schema_type($key));
      }
    }
  }
  return $out_array;
}

La funzione appena descritta è una funzione ricorsiva che, a partire da una array associativo contenente una lista di valori caratterizzati da nomi definiti come descritto sopra, restituisce un secondo array caratterizzato da una struttura ricorsiva dove ad ogni livello di profondità corrisponde un nuovo array associativo. Nel caso in esempio si avrà un array denominato dati_personali contenente una stringa (nominativo), un intero (eta) ed un array (indirizzo); quest’ultimo array conterrà due stinghe (via e citta) ed un intero (civico).

E’ facile immaginare che l’array in input a questa funzione sarà proprio

$_REQUEST["dati_personali"]

In questo modo la funzione array_map_deep si occuperà di esaminare tutti i parametri provenienti dall’interfaccia utente riferiti alla struttura dati_personali, esplorando ricorsivamente il contenuto dei parametri con struttura complessa (che nel linguaggio PHP sono univocamente rappresentati mediante array associativi).

Quando la funzione array_map_deep individua un tipo semplice, essa ne ricava il tipo mediante la funzione get_schema_type, e il nome mediante la funzione get_name semplicemente scomponendo la stringa contenuta nel nome del componente HTML <input> nella sottostringa che precede e che segue il carattere “%”:

function get_name($str)
{
  $i = strpos ($str, "%");
  return substr (substr ($str, $i ++), 1);
}
function get_schema_type($str)
{
  $i = strpos ($str, "%");
  return substr ($str, 0, $i);
}

Successivamente effettua la sua conversione nel tipo PHP corrispondente attraverso la funzione set_the_type. La funzione set_the_type individua una corrispondenza tra i tipi definiti come array, string,int e boolean e i tipi PHP veri e propri ed effettua la conversione del valore contenuto nel parametro.

function set_the_type($var, $schema_type)
{
  switch ($schema_type)
  {
    case "int":
    return (integer)$var;
    break;
    case "boolean":
    return (boolean)$var;
    break;
    case "string":
    return (string)$var;
    break;
    default:
    return (string)$var;
    break;
  }
}

Infine, per testare l’accesso alla struttura gerarchizzata possiamo usare il seguente codice che incolonna, nell’ambito di un file di testo, le informazioni trasferite dal form HTML alla pagina PHP:

$dati_personali = array_map_deep($_REQUEST["dati_personali"]);
echo $dati_personali['nominativo']." ";
echo $dati_personali['eta']." ";
echo $dati_personali['indirizzo']['via']." ";
echo $dati_personali['indirizzo']['civico']." ";
echo $dati_personali['indirizzo']['citta']." ";

L’array $dati_personali mantiene la gerarchia delle informazioni così come l’avevamo definita nel form chiamante. Notiamo infine che qualsiasi modifica alla gerarchia dei dati viene automaticamente assimilata dalla pagina dinamica PHP.

Infine, il codice PHP contenuto in questo articolo può essere combinato con il codice dell’articolo “PHP – Ispezione delle strutture complesse (array e oggetti)” in modo da automatizzare l’accesso ai dati provenienti dal form HTML senza conoscerne la struttura.

Commenti»

No comments yet — be the first.