Javascript e PHP: inviare variabili POST tramite scrittura dinamica del codice

Siccome ho implementato il contatore PHP che (se avete letto) utilizza un variabile POST per decidere se aumentarsi o no, ho avuto anche la necessità di trovare un modo per poter inserire dei link interni che mi inviasse la variabile POST che mi serviva.

Siccome ciò non avviene in modo esplicito tramite una query string (sarebbero variabili GET), non posso inserire i valori nell’attributo href del link.
Dopo un po’ di ricerche ho trovato una buona idea: inviare i dati utilizzando una form (nascosta) contenente le variabili da inviare, generando il submit tramite Javascript inserendo il codice nell’evento OnClick del link.


<form method="post" name="data_form" action="index.php">
	<!-- variabile per il contatore -->
	<input type="hidden" name="increase_counter" value="no" />
	<!-- variabile per la pagina da caricare -->
	<input type="hidden" name="p" value="pagina3" />
</form>
<!-- al click sul link, invio i dati della form (che ha metodo POST) -->
<!-- 'return false;' serve per "fermare" il link, che altrimenti, dopo l'esecuzione del codice in OnClick -->
<!-- cercherebbe di andare al documento pagina3, generando ovviamente un errore 404 -->
<a href="pagina3" onclick="document.data_form.submit(); return false;">Vai a pagina 3</a>

Ora però, nonostante il tutto funzionasse, mi trovavo a dover scrivere tutto il codice di una form ogni volta che inserivo un link. Ho quindi scritto una funzione che, prima di inviare il form, impostasse il giusto valore alle variabili a seconda dell’attributo href del link. In questo modo, utilizzo una sola form per tutti i link, con un bel risparmio di codice!


<!-- Nell'head della pagina, inserisco questo tag script: -->
<script language="javascript" type="text/javascript">
//la funzione ha un unico parametro, link_object, che viene passato usando 'this'
//questa rappresenta il link che è stato cliccato
function go_link (link_object) {
	//siccome ai link relativi viene aggiunto automaticamente l'url completo, lo tolgo
	document.data_form.p.value = link_object.href.replace("http://www.example.net/", "");
	document.data_form.submit();
}
</script>
....
....
<!-- All'inizio del body -->
<form method="post" name="data_form" action="index.php">
	<input type="hidden" name="increase_counter" value="no" />
	<input type="hidden" name="p" value="" />
</form>
....
....
<!-- Un link diventa quindi: -->
<a href="pagina3" onclick="go_link(this); return false;">Vai a pagina 3</a>

Una volta completata anche questa operazione, e mentre mi stavo approcciando a farlo in tutte le altre pagine, mi son detto: perchè non implementarlo nel motore PHP?
Così ho aggiunto il codice Javascript una volta sola per tutte le pagine (lo inserisce infatti la pagina PHP) e ho aggiunto una ulteriore funzione che al caricarsi della pagina aggiunge ai link interni (escludendo ancore e link esterni) l’attributo onload che richiama la funzione go_link()
In questo modo ho semplificato enormemente la cosa: riesco a lavorare in background (usando le variabili POST), senza dover riscrivere lo stesso codice per ogni link, grazie a Javascript.


<head>
<script language="javascript" type="text/javascript">
function insert_links_attributes () {
	//grazie all'array links, ho tutti i link contenuti nella pagina
	for (n in document.links) {
		//modifico il link solo se è interno (contiene quindi l'url del mio sito nell'attributo href
		//oppure se è un ancora (link a un punto diverso della stessa pagina, contraddistinto dal carattere #
		if ((document.links[n].href.indexOf("http://www.example.net/") != -1) && (document.links[n].href.indexOf("#") == -1)) {
	 		document.links[n].setAttribute("onclick", "go_link\(this\)\; return false\;", 0);
	 	}
	}
}
</script>
</head>
<!-- Chiamo la funzione insert_links_attributes una volta completato il caricamento della pagina -->
<body onload="insert_links_attributes();">

Contatore visite in PHP

Per il sito della mia classe (che sto ora rinnovando aggiungendo un motore PHP) ho sviluppato un contatore utenti in PHP, che mi conti solamente le visite da link esterni.

Il suo funzionamento è molto semplice: si basa su un file counter.txt che contiene il numero di utenti che hanno visitato la pagina. Se la pagina viene aperta da un link esterno, aumenta il contatore di 1, altrimenti, se si è giunti lì da un link all’interno del sito, mostra solamente il valore attuale del contatore. I numeri sono scritti con immagini prese da un contatore di Altervista (quello che ho dovuto sostituire, almeno così non si nota u.u), che potete scaricare da qui in un pacchetto ZIP.

Ecco qua il codice:

<?php
//nome del file con il valore del contatore
$file_name = 'Pages/counter.txt';
//controllo se devo aumentare il contatore
//ossia se provengo da un link esterno e non interno
//per fare ciò controllo se mi è stata passata la variabile increase_counter
//che invio in POST dai form del menu
if (empty($_POST['increase_counter'])) {
        $can_access = false;
        //ciclo finchè non riesco ad avere accesso al file
        //ciò perchè successivamente lo elimino, e in caso di due interrogazioni simultanee della pagina
        //potrebbe darsi che non trovando il file, ne crei uno nuovo e faccia ripartire il contatore da 0
        while (!$can_access) {
                if (file_exists($file_name)) {
                        //una volta avuto accesso al file, ne metto il contenuto in $count e l'aumento di 1
                        $counter_file = fopen($file_name, r);
                        $count = fread($counter_file, filesize($file_name));
                        fclose($counter_file);
                        $can_access = true;
                }
        }
        //elimino il file
        unlink($counter_file);
        //lo ricreo e lo apro in scrittura
        $counter_file = fopen($file_name, w);
        //e lo ci scrivo il nuovo valore aumentato di 1
        fwrite($counter_file, $count);
        fclose($counter_file);
} else {
        $can_access = false;
        //altrimenti, se provengo da un link interno, visualizzo l'attuale valore
        //in counter.txt
        while (!$can_access) {
                if (file_exists($file_name)) {
                        //una volta avuto accesso al file, ne metto il contenuto in $count
                        $counter_file = fopen($file_name, r);
                        $count = fread($counter_file, filesize($file_name));
                        fclose($counter_file);
                        $can_access = true;
                }
        }
}
//ottengo l'array dei caratteri che formano il numero
$count_chars = str_split($count);
//aggiungo degli 0 davanti al numero per portarlo a 7 cifre
for ($n = count($count_chars); $n < 7; $n++) {
        array_unshift($count_chars, "0");
}
//inserisco le immagini corrispondenti per ogni cifra
foreach ($count_chars as $number) {
        echo "<img src=\"/Immagini/Counter/" . $number . ".gif\" />";
}
?>

La variabile increase_counter la passo tramite il menu del sito, composto da form. Il codice di un pulsante, ad esempio, è questo:

<!-- Il form ha come metodo POST: le informazioni dei campi contenuti in esso saranno passate alla pagina
nell'attributo action, ma a differenza di GET, che le passa esplicitamente nella query della pagina, POST le immette in un array nascosto all'utente ma accessibile dal codice PHP presente nella pagina -->
<form action="index.php" method="POST">
        <!-- Pulsante vero e proprio che l'utente vede -->
        <input type="submit" value="Home" />
        <!-- Campo nascosto  increase_counter a cui assegno un valore (qualunque, l'importante che l'abbia -->
        <input type="hidden" name="increase_counter" value="no" />
</form>

Basterà preoccuparsi di passare increase_counter nei link interni al sito.
Si potrebbe anche utilizzare GET e quindi renderne il passaggio esplicito, visto che non sono private e necessariamente da nascondere, e ciò renderebbe più facile inserire i link

PHP Hypertext Processor

Ieri ero in vena di imparare e mi sono messo a studiare la guida PHP di HTML.it
Davvero ben fatta devo dire, ho imparato tutte le basi in un paio d’ore, e scritto il mio primo (stupidissimo) script PHP

PHP è un linguaggio lato server (cioè eseguito dal server web, non dal computer dell’utente) che restituisce pagine HTML, e che è usato per poter fare pagine web che possano cambiare, pagine dinamiche. Questo stesso blog è scritto in PHP: struttura base sempre uguale, ma a seconda di ciò che richiede l’utente modifica la pagina HTML in output: la pagina per vedere un post ad esempio, è sempre la stessa, ma a seconda del parametro p passato nella query string visualizza un post piuttosto che un altro

Query string: la stringa nell’URL di una pagina dopo il carattere ? che contiene parametri che la pagina utilizzerà per il processamento del codice PHP piuttosto che ASP