<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Il blog di webEngine &#187; Sviluppo Web</title>
	<atom:link href="http://blog.webeng.it/category/sviluppo/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.webeng.it</link>
	<description>Blog dedicato alle tecnologie Web e alle notizie dal mondo della rete...</description>
	<lastBuildDate>Thu, 17 Dec 2009 13:07:15 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Configurare Apache e Php per l&#8217;invio di email</title>
		<link>http://blog.webeng.it/2009/12/17/configurare-apache-e-php-per-invio-di-email/</link>
		<comments>http://blog.webeng.it/2009/12/17/configurare-apache-e-php-per-invio-di-email/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 12:59:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Sviluppo Web]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[estensioni]]></category>
		<category><![CDATA[Link utili]]></category>

		<guid isPermaLink="false">http://blog.webeng.it/?p=1112</guid>
		<description><![CDATA[Dunque, se siete arrivati su questa pagina, state sicuramente progettando o comunque vi sarà già capitato, di imbattervi nella creazione di uno script di invio email in automatico&#8230; Inviare automaticamente email con php è possibile grazie alla funzione nativa mail descritta abbondantemente nella guida ufficiale del php e utilizzata da tutti gli script di più [...]]]></description>
			<content:encoded><![CDATA[<p>Dunque, se siete arrivati su questa pagina, state sicuramente progettando o comunque vi sarà già capitato, di imbattervi nella creazione di uno script di invio email in automatico&#8230; Inviare automaticamente email con php è possibile grazie alla funzione nativa <a href="http://php.net/manual/en/function.mail.php">mail</a> descritta abbondantemente nella guida ufficiale del php e utilizzata da tutti gli script di più alto livello presenti in rete.</p>
<p><span id="more-1112"></span>Potrebbe capitarvi che PHP non sia correttamente configurato per l&#8217;invio delle email e che quindi tutti i tentativi di eseguire il vostro script correttamente, falliscano miseramente e senza darvi troppe spiegazioni. Questo perchè PHP di default ,non effettua la configurazione del &#8220;modulo&#8221; sendmail, necessario per l&#8217;invio dell&#8217;email da PHP.</p>
<p>Eccovi una breve descrizione di come configurare il server web Apache per l&#8217;invio di email dagli script php sviluppati localmente, l&#8217;approccio di risoluzione è il medesimo sia che ci si trovi in ambienti Windows che Linux/Unix.</p>
<p>Per tutti gli utenti linux/unix effettuare una ricerca del comando sendmail:</p>
<p><span style="color: #339966;">luca@lincelnx:~$ locate /sendmail<br />
/home/luca/.ies4linux/ie6/drive_c/windows/system32/sendmail.dll<br />
/usr/lib/sendmail<br />
/usr/sbin/sendmail<br />
/usr/share/gnome-pilot/conduits/sendmail.conduit<br />
/usr/share/man/man8/sendmail.8.gz<br />
/usr/share/perl5/Mail/Mailer/sendmail.pm</span></p>
<p>Prendiamo come buoni tutti i risultati contenuti nelle cartelle dove risiedono i binari</p>
<p>/usr/sbin o usr/bin (varia da sistema a sistema)</p>
<p>Gli utenti di Microsoft Windows non devono effettuare questo passaggio in quanto l&#8217;invio di email avviene grazie alla configurazione integrata di So/Outlook e account utente.</p>
<p>Individuare il file php.ini e aprirlo per modificarne la configurazione.</p>
<p>Per gli utenti Linux/Unix individuare con una ricerca testuale il sendmail_path e settarlo correttamente e in modo esteso es:</p>
<p><span style="color: #339966;">; For Unix only.  You may supply arguments as well (default: &#8220;sendmail -t -i&#8221;).<br />
sendmail_path =</span> <span style="color: #800000;">/usr/sbin/sendmail</span></p>
<p>Per gli utenti Windows settare il proprio account locale di posta elettronica in modo che php riesca a utilizzarlo per l&#8217;invio delle email.</p>
<p><span style="color: #666699;">[mail function]<br />
; For Win32 only.<br />
SMTP = localhost<br />
smtp_port = 25</span></p>
<p><span style="color: #666699;">; For Win32 only.<br />
sendmail_from =</span><span style="color: #800000;"> luca@webeng.it</span></p>
<p>Salvare il file, riavviare Apache ed effettuare un test del vostro script di invio.</p>
<p>Spero vi sia stato utile.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webeng.it/2009/12/17/configurare-apache-e-php-per-invio-di-email/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Box Fluido con Ombra</title>
		<link>http://blog.webeng.it/2009/11/10/box-fluido-con-ombra/</link>
		<comments>http://blog.webeng.it/2009/11/10/box-fluido-con-ombra/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 16:19:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Articoli Generici]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Script]]></category>
		<category><![CDATA[box fluido]]></category>
		<category><![CDATA[html]]></category>

		<guid isPermaLink="false">http://blog.webeng.it/?p=1101</guid>
		<description><![CDATA[Ecco un breve esempio di una funzione PHP che ci permette di generare un box fluido in HTML con l&#8217;effetto ombreggiatura. La funzione è scritta in PHP ma il codice HTML generato è valido per qualsiasi tipo di linguaggio di programmazione. L&#8217;effetto ombra è ottenuto tramite un immagine creata con GIMP.
Le immagini che fanno da [...]]]></description>
			<content:encoded><![CDATA[<p>Ecco un breve esempio di una funzione PHP che ci permette di generare un box fluido in HTML con l&#8217;effetto ombreggiatura. La funzione è scritta in PHP ma il codice HTML generato è valido per qualsiasi tipo di linguaggio di programmazione. L&#8217;effetto ombra è ottenuto tramite un immagine creata con GIMP.</p>
<p><span id="more-1101"></span>Le immagini che fanno da angolo sinistro (superiore e inferiore) devono essere opportunamente dimensionate in modo da poter coprire una qualsiasi lunghezza (nel nostro caso fino a un massimo di 2000px) .</p>
<pre class="brush: php">

&lt;html&gt;
&lt;head&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/style.css&quot;&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;?php
function get_box($header, $content){
$box = &quot;&lt;div class=\&quot;box\&quot;&gt;&lt;div class=\&quot;hd\&quot;&gt;&lt;div class=\&quot;c\&quot;&gt;&lt;/div&gt;&lt;/div&gt;&quot;;
$box .= &quot;&lt;div class=\&quot;bd\&quot;&gt;&lt;div class=\&quot;c\&quot;&gt;&lt;div class=&#039;s&#039;&gt;&quot;;
$box .= &quot;&lt;!-- content area --&gt;&quot;;
$box .= &quot;&lt;h1&gt;&quot;.$header.&quot;&lt;/h1&gt;&quot;;
$box .=    &quot;&lt;hr/&gt;&quot;;
$box .= $content;
$box .= &quot;&lt;!-- content area --&gt;&quot;;
$box .= &quot;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&quot;;
$box .= &quot;&lt;div class=\&quot;ft\&quot;&gt;&lt;div class=\&quot;c\&quot;&gt;&lt;/div&gt;&lt;/div&gt;&quot;;
$box .= &quot;&lt;/div&gt;&quot;;
return $box;
}
?&gt;

&lt;?php
echo get_box(&quot;Questo &amp;amp;amp;amp;amp;egrave; un box fluido&quot;, &quot;Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old.&quot;);
?&gt;
&lt;/body&gt;
</pre>
<p>Ora veniamo al css.</p>
<pre class="brush: css">

/* stili per le box */
.box {
width:100%;
margin:1em 0 0em 0;
min-width:5em;
color:#fff;
}

.box .hd .c,
.box .ft .c {
font-size:1px; /* ensure minimum height */
height:13px;
}

.box .ft .c {
height:14px;
}

.box .hd {
background:transparent url(../images/box_top_left.png) no-repeat 0px 0px;
}

.box .hd .c {
background:transparent url(../images/box_top_right.png) no-repeat right 0px;
}

.box .bd {
background:transparent url(../images/box_left.png) repeat-y 0px 0px;
}

.box .bd .c {
background:transparent url(../images/box_right.png) repeat-y right 0px;
}

.box .bd .c .s {
margin:0px 8px 0px 4px;
background:#8193a7 repeat-x 0px 0px;
padding:1em;
}

.box .ft {
background:transparent url(../images/box_bottom_left.png) no-repeat 0px 0px;
}

.box .ft .c {
background:transparent url(../images/box_bottom_right.png) no-repeat right 0px;
}

/* content-specific */
.box h1 {
/* header */
font-size:1em;
margin:0px;
padding:0px;
margin-top:-1.0em;
}

.box p {
margin:0.5em 0px 0px 0px;
padding:0px;
font-size: 0.9em;
line-height: 1;
}

.box hr {
color: white;
}
</pre>
<p><a href="http://blog.webeng.it/wp-content/uploads/2009/11/box.rar">L&#8217;intero esempio è scaricabile da qui</a>.</p>
<p>Un grazie a Daniele.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webeng.it/2009/11/10/box-fluido-con-ombra/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installare Apache, Php, Mysql, PhpMyAdmin per Ubuntu</title>
		<link>http://blog.webeng.it/2009/04/21/installare-apache-php-mysql-phpmyadmin-per-ubuntu/</link>
		<comments>http://blog.webeng.it/2009/04/21/installare-apache-php-mysql-phpmyadmin-per-ubuntu/#comments</comments>
		<pubDate>Tue, 21 Apr 2009 21:55:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Articoli Generici]]></category>
		<category><![CDATA[MySql]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.webeng.it/?p=1064</guid>
		<description><![CDATA[Eccovi riassunti in questa piccola guida i pochi e semplici passi da effettuare per configurare un ambiente di sviluppo web sulla propria postazione o su un server basato su ubuntu linux. Come potete notare l&#8217;installazione risulta molto più immediata che su windows con l&#8217;unica differenza che i nostri file di configurazione saranno posizionati diversamente sul [...]]]></description>
			<content:encoded><![CDATA[<p>Eccovi riassunti in questa piccola guida i pochi e semplici passi da effettuare per configurare un ambiente di sviluppo web sulla propria postazione o su un server basato su ubuntu linux. Come potete notare l&#8217;installazione risulta molto più immediata che su windows con l&#8217;unica differenza che i nostri file di configurazione saranno posizionati diversamente sul filesystem.<br />
<span id="more-1064"></span><br />
<strong><span style="text-decoration: underline;">Installare Apache2</span></strong></p>
<p>Aprire una shell bash e digitare il comando:</p>
<p><code>sudo apt-get install apache2</code></p>
<p>A questo punto abbiamo installato il server web, per verificare che tutto funzioni correttamente apriamo Firefox e mandiamolo su http://localhost , il risultato visualizzato nel caso l&#8217;installazione sia andata a buon fine sarà questo.</p>
<p><img class="alignnone size-full wp-image-1065" title="apache-1" src="http://blog.webeng.it/wp-content/uploads/2009/04/apache-1.jpg" alt="apache-1" width="580" height="210" /></p>
<p>Per effettuare personalizzazioni varie alla nostra configurazione di Apache possiamo editare con un semplice blocco note il file apache2.conf contenuto nella directory /ect/apache2 . Le nostre applicazioni web saranno posizionate invece nella directory di default /var/www .</p>
<p>Per controllare il servizio possiamo utilizzare i comandi</p>
<ol>
<li><code>sudo /etc/init.d/apache2 restart</code> (per restartare apache ad esempio dopo il caricamento di moduli o cambiamento di file di configurazione)</li>
<li><code>sudo /etc/init.d/apache2 start</code> (per startare il servizio in caso di avvio manuale)</li>
<li><code>sudo /etc/init.d/apache2 stop</code> (per stoppare il servizio in caso di necessità)</li>
</ol>
<p><strong><span style="text-decoration: underline;">Installare PHP</span></strong></p>
<p>Aprire una shell bash e digitare il comando:</p>
<p><code>sudo apt-get install php5</code></p>
<p>A questo punto testiamo la capacità di apache di comprendere il php creando una pagina d&#8217;esempio, avendo cura prima di restartare apache in modo da poter caricare php con il comando:</p>
<p>sudo /etc/init.d/apache2 restart</p>
<ol>
<li>Creare una directory con il comando <code>sudo mkdir /var/www/phpinfo</code></li>
<li>Creare una nuova pagina con il comando <code>sudo gedit /var/www/phpinfo/phpinfo.php</code></li>
<li>Incollare il testo &lt;?php phpinfo(); ?&gt; e salvare</li>
<li>Recarsi su http://localhost/phpinfo/phpinfo.php e verificare la stampa a video dei paramentri di php.</li>
</ol>
<p><span style="text-decoration: underline;"><strong>Installare MySql Server</strong></span></p>
<p>Aprire una shell bash e digitare il comando:</p>
<p><code>sudo apt-get install mysql-server-5.0</code></p>
<p>Per controllare il servizio possiamo utilizzare i comandi</p>
<ol>
<li><code>sudo /etc/init.d/mysql restart</code> (per restartare apache ad esempio dopo il caricamento di moduli o cambiamento di file di configurazione)</li>
<li><code>sudo /etc/init.d/mysql start</code> (per startare il servizio in caso di avvio manuale)</li>
<li><code>sudo /etc/init.d/mysql stop</code> (per stoppare il servizio in caso di necessità)</li>
</ol>
<p><strong><span style="text-decoration: underline;">Installare PhpMyAdmin, MySql Query Browser, MySql Administrator</span></strong></p>
<p><code>sudo apt-get install phpmyadmin</code></p>
<p>Al termine dell&#8217;installazione dovreste avere a disposizione la vostra maschera di login su http://localhost/phpmyadmin , nel caso non fosse così aprite una shell e digitate il comando:</p>
<p><code>sudo ln -s /usr/share/phpmyadmin /var/www/phpmyadmin</code></p>
<p>questo comando crerà un link simbolico nella cartella di apache che punterà al percorso reale dell&#8217;applicazione, infatti può succedere che lo script di installazione non riesca ad effettuare automaticamente questa operazione.</p>
<p>Opzionalmente possiamo installare questi pacchetti molto noti per lo sviluppo di applicazioni lato DB con i seguenti comandi:</p>
<p><code>sudo apt-get install mysql-query-browser</code><br />
<code>sudo apt-get install mysql-admin</code><br />
<code>sudo apt-get install mysql-navigator</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webeng.it/2009/04/21/installare-apache-php-mysql-phpmyadmin-per-ubuntu/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Guida ad Ajax : Spaghetti Ajax</title>
		<link>http://blog.webeng.it/2009/02/07/guida-ad-ajax-spaghetti-ajax/</link>
		<comments>http://blog.webeng.it/2009/02/07/guida-ad-ajax-spaghetti-ajax/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 22:51:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Sviluppo Web]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[sviluppo web]]></category>

		<guid isPermaLink="false">http://blog.webeng.it/?p=981</guid>
		<description><![CDATA[AJAX, acronimo di Asynchronous JavaScript and XML, è uno strumento di sviluppo per la realizzazione di applicazioni web interattive (Rich Internet Application).
Questa breve guida ad ad AJAX renderà più facile lo sviluppo di piccole funzionalità che arricchiranno le vostre applicazioni e/o i vostri siti web. La guida è stata rilasciata dall&#8217;autore con la licenza creative [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.webeng.it/wp-content/uploads/2009/02/ajax.jpg"><img class="alignnone size-full wp-image-973" style="float: left; margin-right: 5px;" title="ajax" src="http://blog.webeng.it/wp-content/uploads/2009/02/ajax.jpg" alt="" width="120" /></a>AJAX, acronimo di Asynchronous JavaScript and XML, è uno strumento di sviluppo per la realizzazione di applicazioni web interattive (Rich Internet Application).</p>
<p>Questa breve guida ad ad AJAX renderà più facile lo sviluppo di piccole funzionalità che arricchiranno le vostre applicazioni e/o i vostri siti web. La guida è stata rilasciata dall&#8217;autore con la licenza creative commons.<br />
<span id="more-981"></span><br />
<script src="/scripts/spaghetti_ajax/script.js" type="text/javascript"></script></p>
<h2>Prologo</h2>
<p>Quando ho pensato a questo articolo la mia idea fondamentale era quella di mostrare come passare dall&#8217;utilizzo di Ajax nudo e crudo, ad una forma più astratta e potente. Mi sono accorto velocemente che un lettore ha bisogno di conoscere alcuni concetti di programmazione funzionale che i designer di Javascript hanno ben pensato di aggiungere al linguaggio per capire appieno come funzionano alcuni pezzi del codice che mostrerò. Come conseguenza l&#8217;articolo ha assunto una nuova forma, quella di una guida veloce ma completa ad Ajax, dalle basi alle astrazioni che erano all&#8217;origine lo scopo dell&#8217;articolo.</p>
<p>Molto del codice esposto viene utilizzato in un servizio di social bookmarking che sto sviluppando in questi mesi (<a href="http://segnalo.com/">segnalo.com</a>), dunque le tecniche di programmazione mostrate sono <em>reali</em>, nel senso che sono applicabili a progetti in produzione.</p>
<h2>Cos&#8217;è Ajax</h2>
<p>Se leggete in giro su internet forse vi farete l&#8217;idea che Ajax è una cosa complicatissima che solo i programmatori più bravi usano. In realtà Ajax è una stupidagine dal punto di vista tecnico, fondamentalmente l&#8217;unione di due cose.</p>
<ul>
<li>La capacità di Javascript di aggiornare parte di una pagina HTML senza che questa venga caricata nuovamente.</li>
<li>La capacità di Javascript di fare richieste tramite il protocollo HTTP.</li>
</ul>
<p>Molto spesso si parla di Ajax anche quando soltanto una di queste due caratteristiche viene utilizzata, in ogni caso per capirci qualcosa iniziamo esplorando la prima capacità listata sopra: aggiornare le pagine in temo reale tramite Javascript.</p>
<h2>Giocare con gli elementi di una pagina</h2>
<pre class="brush: javascript">

&lt;script&gt;
function script1() {
var e = document.getElementById(&quot;pluto&quot;);
e.innerHTML = &quot;Benone!&quot;;
}
&lt;/script&gt;
&lt;div id=&quot;pluto&quot;&gt;
Ciao come stai?
&lt;/div&gt;
&lt;input type=&quot;button&quot; value=&quot;Esegui esempio&quot; onClick=&quot;script1()&quot; /&gt;
</pre>
<p><!-- esempio --></p>
<div class="example">
<h3>Esempio 1</h3>
<div id="pluto">Ciao come stai?</div>
<input onclick="script1()" type="button" value="Esegui esempio" /></div>
<p><!-- fine esempio --></p>
<p>Provate a guardare il codice dell&#8217;esempio 1 e ad utilizzarlo (basta premere il bottone <strong>Esegui esempio</strong>). Alla pressione del bottone il contenuto dell&#8217;elemento <strong>DIV</strong> che ha come <strong>id</strong> <em>pluto</em> viene modificato da &#8220;Come stai&#8221; a &#8220;Benone!&#8221;. Guardando il codice si capisce subito che farlo è molto semplice, questa è la funzione <em>script1</em> che viene richiamata alla pressione del pulsante:</p>
<pre class="brush: javascript">

function script1() {
var e = document.getElementById(&quot;pluto&quot;);
e.innerHTML = &quot;Benone!&quot;;
}
</pre>
<p>La funzione <em>script1</em> chiama la funzione <em>document.getElementById</em> passando come argomento l&#8217;identificativo del <strong>DIV</strong>, e quello che viene ritornato è un riferimento all&#8217;oggetto che rappresenta il nostro <strong>DIV</strong> nella pagina HTML. L&#8217;oggetto in questione ha una proprietà chiamata <strong>innerHTML</strong> che può essere letta/scritta. Se viene letta restituisce il codice HTML presente dentro il <strong>DIV</strong>, se viene scrittta settandola a qualcosa di diverso come abbiamo fatto noi nell&#8217;ultima riga della funzione <em>script1</em> il contenuto del <strong>DIV</strong> cambia e gli effetti si vedono immediatamente nella pagina. Facile no?</p>
<h2>Javascript illusionista</h2>
<p>Altra cosa molto utilizzata in applicazioni Ajax è la possibilità di poter settare due proprietà dello stile CSS di un oggetto chiamate <em>visibility</em> e <em>display</em> in modo da fare scomparire e apparire l&#8217;oggetto a piacimento. Bisogna far pratica anche con questo aspetto (altrettanto semplice) prima di scrivere applicazioni Ajax serie. Ecco il secondo esempio che illustra come fare a diventare prestigiatori in Javascript.</p>
<pre class="brush: javascript">

&lt;script&gt;
function script2() {
var e = document.getElementById(&quot;pippo&quot;);
if (e.style.visibility == &#039;hidden&#039;) {
e.style.visibility = &#039;visible&#039;;
e.style.display = &#039;block&#039;;
} else {
e.style.visibility = &#039;hidden&#039;;
e.style.display = &#039;none&#039;;
}
}
&lt;/script&gt;
&lt;div id=&quot;pippo&quot;&gt;
Io scompaio e appaio!
&lt;/div&gt;
&lt;input type=&quot;button&quot; value=&quot;Clicca per far sparire/ricomparire&quot; onClick=&quot;script2()&quot; /&gt;
</pre>
<p><!-- esempio --></p>
<div class="example">
<h3>Esempio 2</h3>
<div id="pippo">Io scompaio e appaio!</div>
<input onclick="script2()" type="button" value="Clicca per far sparire/ricomparire" /></div>
<p><!-- fine esempio --></p>
<p>Anche in questo caso l&#8217;idea di base non è difficile da capire. Prendiamo il riferimento dell&#8217;oggetto con <em>document.getElementById</em> come al solito e modifichiamo lo stile dell&#8217;oggetto a nostro piacimento tamite <em>oggetto.style.nomeProprietà</em> per fare quello che vogliamo. Qualcuno di voi che non conosce molto bene i CSS si chiederà come mai modifichiamo sia la proprietà <em>visibility</em> che <em>display</em>. La prima viene settata a <strong>visible</strong> se si vuole che l&#8217;oggetto sia visibile, mentre il valore di <strong>hidden</strong> la fa scomparire. La seconda invece viene settata a <strong>none</strong> quando si vuole che l&#8217;oggetto non prenda più spazio nella pagina, altrimenti anche se invisibile occuperebbe lo spazio ugualmente. A volte ciò  è desiderabile, altre volte non lo è. Si noti come la proprietà <em>dispaly</em> venga settata a <strong>block</strong> quando si vuole far ricomparire l&#8217;oggetto: questo valore è infatti il default per un <strong>DIV</strong> ma varia al variare dei diversi elementi HTML, ad esempio per altri elementi il valore di default è <strong>inline</strong>. Se volete saperne di più cercate un buon tutorial sui CSS in giro. Congratulazioni! Sapete la metè delle cose che bisogna sapere per utilizzare Ajax in maniera rudimentale. Dunque andiamo a scoprire l&#8217;altra metè della storia.</p>
<h2>Richieste HTTP da Javascript</h2>
<p>Qual&#8217;è la caratteristica principale di una applicazione in Ajax? Il fatto che la pagina si aggiorna senza la necessità di essere ricaricata, o al contrario che un evento generato dall&#8217;utente (come ad esempio la pressione di un tasto) causi una operazione sul server, senza la necessita di postare alcun FORM. Abbiamo visto come tramite Javascript sia possibile modificare il contenuto di una porzione della pagina, e di come gli elementi possano scomparire e ricomparire. Questo è sufficiente per creare pagine i cui contenuti si aggiornano in maniera dinamica in linea teorica. In pratica per il sistema avere una utilità reale serve che ad una azione dell&#8217;utente vengano visualizzati dati che noi non potevamo avere già in memoria. Immaginate un programma di gestione del magazzino scritto in Ajax. Quando l&#8217;utente digita il codice di una particolare merce immediatamente appare nella pagina la quantità ancora disponibile in magazzino. Ovviamente non è pensabile che tutti i dati del magazino siano nella memoria di Javascript, dunque è necessario eseguire una richiesta al server &#8220;di nascosto&#8221;, e appena si ottiene la risposta necessaria aggiornare la pagina.</p>
<p>Altro esempio, una web mail scritta in Ajax (chi non conosce Gmail?). Alla pressione del tasto <strong>Delete</strong> l&#8217;email viene cancellata. Eliminare la riga di quella email dalla lista delle email è semplice, abbiamo già visto come fare. Ma chi dice al server di cancellare l&#8217;email dal database se non è possibile spedire un FORM?</p>
<p>Quello che ci vuole per risolvere questi problemi è la capacità di fare richieste al server in maniera <em>asincrona</em>, ovvero in <em>background</em>, senza che l&#8217;utente si accorga di niente. In questo modo Javascript può contattare il server spedendo e ricevendo informazioni senza che la pagina venga ricaricata. Ma come si fa nella pratica?</p>
<h2>L&#8217;oggetto XMLHttpRequest</h2>
<p>Javascript è capace di fare richieste HTTP in background sia utilizzando il metodo GET che il POST. Noi ci occuperemo solo del primo perchè nella pratica è quello che si utilizza di più e una volta che conoscete questo, se vi fosse necessario, utilizzare l&#8217;altro non sarà una cosa complicata. Per poter fare tale richiesta è necessario utilizzare un oggetto che si chiama <strong>XMLHttpRequest</strong> in tutti i browser moderni escluso Internet Explorer che necessita di un diverso oggetto. Prima facciamo finta che Internet Explorer non esista (ho quasi l&#8217;impressione che il mondo riesca ad andare avanti lo stesso). Ciò che serve per fare una richiesta HTTP in Ajax è ovviamente un pò di Javascript, e dall&#8217;altra parte (nel server) qualcuno che risponda alla richiesta, ovvero un piccolo script in <strong>PHP</strong>. Ovviamente l&#8217;applicazione server-side può essere scritta in qualunque linguaggio, tutti gli esempi di questo articolo sono scritti in PHP perchè lo conosce anche mia zia Caterina, esperta di programmazione web e di uncinetto, a cui dedico questo articolo.</p>
<p>La prima cosa che vi mostro è la funzione che crea un oggetto XMLHttpRequest.</p>
<pre class="brush: javascript">

function CreateXmlHttpReq(handler) {
var xmlhttp = null;
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = handler;
return xmlhttp;
}
</pre>
<p>Bisogna spiegare cosa fa questo codice. La funzione <em>CreateXmlHttpReq</em> prende in ingresso un solo argomento, una funzione, che verrà chiamata quando la richiesta è stata eseguita. Infatti Javascript è un linguaggio che per l&#8217;input/output utilizza un modello basato sugli eventi, ricordate onClick, onChange, eccetera? L&#8217;idea è che lui quando non sta fecendo niente per l&#8217;utente aspetta che si verifichi un evento associato ad una qualche funzione. Appena l&#8217;evento si verifica Javscript entra in azione chiamando l&#8217;handler (ovvero una funzione che gestisce l&#8217;evento) apposito. Bene, le richieste HTTP necessitano del tempo per essere eseguite, cosa dovrebbe fare Javascript nel mentre, aspettare? Non può perchè deve gestire il resto dell&#8217;applicazione. Dunque la richiesta viene lanciata in background. Appena ci sono novità di rilievo l&#8217;handler che noi passiamo come argomento a <em>CreateXmlHttpReq</em> viene chiamato per servire la nostra richiesta.</p>
<p>Ora che sappiamo come creare l&#8217;oggetto necessario per fare una richiesta HTTP in background, e come associarvi un handler, ci serve sapere come utilizzarlo per richiamare una data pagina e qualche altro dettaglio.</p>
<pre class="brush: javascript">

var myRequest = CreateXmlHttpReq(myHandler);
myRequest.open(&quot;GET&quot;,&quot;primo.php&quot;);
myRequest.send(null);
</pre>
<p>Come potete immaginare il codice sopra setta l&#8217;oggetto XMLHttpRequest in maniera da fargli eseguire una query tramite il metodo <strong>GET</strong> al file primo.php, e nella riga immediatamente successiva spedisce la richiesta. A questo punto la richiesta parte&#8230; ma non abbiamo ancora scritto la funzione <em>myHandler</em> che deve occuparsi di gestirla quando ci sono novità in vista.</p>
<pre class="brush: javascript">

function myHandler() {
if (myRequest.readyState == 4 &amp;&amp; myRequest.status == 200) {
alert(myRequest.responseText);
}
}
</pre>
<p>Si noti come myRequest sia una variabile globale, infatti l&#8217;handler viene chiamato senza arogmenti, non c&#8217;è nessuno che gli comunica a quale oggetto si riferisce la richiesta per cui è stato invocato, dunque bisogna avere un riferimento globale all&#8217;oggetto XMLHttpRequest. Nel codice finale che viene presentato in questo articolo l&#8217;oggetto viene invece registrato nella <em>chiusura</em> (se leggete di piu&#8217; capirete cos&#8217;e'), cio&#8217; permette di gestire in maniera affidabile piu&#8217; richieste concorrenti. Ma per ora non ci pensate, facciamo finta che il modo migliore sia avere una variabile globale per l&#8217;oggetto XMLHttpRequest.</p>
<p>Il nostro handler viene invocato più volte durante una richiesta HTTP. La proprietà <em>readyState</em> ci dice per quale motivo l&#8217;handler è stato chiamato in base al valore che assume.</p>
<ul>
<li>0: uninitialized</li>
<li>1: loading</li>
<li>2: loaded</li>
<li>3: interactive</li>
<li>4: complete</li>
</ul>
<p>Ciò che a noi interessa è fare qualcosa quando la richiesta viene completata, per questo testiamo che <em>readyState</em> abbia il valore <strong>4</strong>. A quel punto sarà settata anche la proprietà <em>status</em> che contiene il valore dello stato della risposta HTTP, che è 200 per richieste avvenute con successo, il famoso 401 per pagine non trovate, e così via.</p>
<p>Come averete visto il nostro handler è una funzione che si milita a visualizzare un alert. Ora mettiamo le parti assieme e proviamo questo esempio, manca però solo una parte: il file PHP. Ecco dunque il sorgente di <strong>primo.php</strong>:</p>
<pre class="brush: php">

&lt;?
echo(&quot;Questi dati vengono dal PHP&quot;);
?&gt;
</pre>
<p>Ecco l&#8217;esempio con il codice completo e la possibilità di vederne gli effetti dal vivo.</p>
<pre class="brush: javascript">

var myRequest = null;

function CreateXmlHttpReq(handler) {
var xmlhttp = null;
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = handler;
return xmlhttp;
}

function myHandler() {
if (myRequest.readyState == 4 &amp;&amp; myRequest.status == 200) {
alert(myRequest.responseText);
}
}

function esempio3() {
myRequest = CreateXmlHttpReq(myHandler);
myRequest.open(&quot;GET&quot;,&quot;primo.php&quot;);
myRequest.send(null);
}
&amp;lt;/script&amp;gt;
&amp;lt;input type=&quot;button&quot; value=&quot;Clicca per lanciare la richiesta&quot; onClick=&quot;esempio3()&quot; /&amp;gt;
</pre>
<p><!-- esempio --></p>
<div class="example"><strong>Nota: questo script non funziona con Internet Explorer!</strong></p>
<input onclick="script3()" type="button" value="Clicca per lanciare la richiesta" /></div>
<p><!-- fine esempio --></p>
<p>Ogni volta che cliccate sul bottone <strong>Clicca per lanciare la richiesta</strong>, tale richiesta parte, quando la risposta del server è disponibile l&#8217;handler viene richiamato con la giusta combinazione di <em>readyState</em> e <em>status</em> e l&#8217;alert col contenuto della risposta viene visualizzato. Se avessimo voluto avremmo potuto mettere un <strong>DIV</strong> nella pagina e tramite la proprietà innerHTML sarebbe stato possibile mostrare il risultato della richiesta aggiornando il <strong>DIV</strong> direttamente, invece che utilizzare un alert. Questo è un buon esercizio che vi consiglio di fare subito prima di continuare a leggere l&#8217;articolo. Tra poco affronteremo argomenti un tantino più complicati dunque è consigliabile giocare un pò con i concetti esposti fino a questo punto per acquisire dimetichezza.</p>
<h2>Internet Explorer comunque esiste</h2>
<p>E non lo possiamo ignorare poichè più o meno l&#8217;ottanta percento delle persone lo utilizza. Per fortuna non serve modificare che una singola funzione per rendere il nostro codice compatibile con IE, la <em>CreateXmlHttpReq2</em>. Ecco la versione compatibile:</p>
<pre class="brush: javascript">

// Create the XML HTTP request object. We try to be
// more cross-browser as possible.
function CreateXmlHttpReq2(handler) {
var xmlhttp = null;
try {
xmlhttp = new XMLHttpRequest();
} catch(e) {
try {
xmlhttp = new ActiveXObject(&quot;Msxml2.XMLHTTP&quot;);
} catch(e) {
xmlhttp = new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;);
}
}
xmlhttp.onreadystatechange = handler;
return xmlhttp;
}
</pre>
<p>Questa funzione tenta di risolvere un certo numero di problemi con diverse versioni di Internet Explorer, e un problema con una vecchia versione del browser Mozilla. Come potete vedere il modo in cui viene creato l&#8217;oggetto per la richiesta HTTP e il modo in cui viene settato l&#8217;handler variano nei diversi browser, ma gli oggetti sono molto simili e l&#8217;handler non deve essere modificato per gestire l&#8217;uno o l&#8217;altro. Ciò è importantissimo: abbiamo isolato il codice non compatibile tra i diversi browser in un&#8217;unica funzione!</p>
<p>C&#8217;è un secondo problema con IE in realtà, fa il caching delle richieste HTTP fatte in questo modo, dunque se sono effettuate utilizzando la stessa URL più volte, anche se lo script PHP richiamato produce diversi risultati, il risultato ottenuto sarà sempre lo stesso. Per evitare questo problema invece di richiedere qualcosa come <strong>script.php</strong> basta richiedere <strong>script.php?rand=</strong><em>numeroCasualie</em>. In questo modo inganniamo IE facendogli credere che ogni volta si tratta di una richiesta diversa ed evitiamo il problema della cache. Per generare un numero casuale in Javascript si utilizza la funzione <em>Math.random</em>, dunque per evitare il problema della cache di IE tutto quello che dovremmo modificare nello script di sopra è la riga in cui la richiesta viene settata utilizzando il metodo <em>open</em>. Nello script originale usavamo:</p>
<pre class="brush: javascript">

myRequest.open(&quot;GET&quot;,&quot;primo.php&quot;);
</pre>
<p>Mentre sarebbe opportuno utilizzare:</p>
<pre class="brush: javascript">

myRequest.open(&quot;GET&quot;,&quot;primo.php&amp;rand=&quot;+escape(Math.random()));
</pre>
<h2>Un esempio completo che funziona su tutti i browser</h2>
<p>A questo punto siamo pronti per riscrivere l&#8217;esempio di sopra con alcune modifiche. Per prima cosa utilizzeremo la funzione CreateXmlHttpReq2 compatibile con IE, secondo utilizzeremo il parametro casuale nella richiesta per evitare la cache e terzo modificheremo lo script PHP in modo da ritornare il tempo in secondi, così possiamo vedere che i dati cambiano ad ogni invio. Infine questa volta useremo un <strong>DIV</strong> per visualizzare il risultato dinamicamente utilizzando innerHTML.</p>
<p>Il codice integrale è il seguente.</p>
<pre class="brush: javascript">

var myRequest = null;

function CreateXmlHttpReq2(handler) {
var xmlhttp = null;
try {
xmlhttp = new XMLHttpRequest();
} catch(e) {
try {
xmlhttp = new ActiveXObject(&quot;Msxml2.XMLHTTP&quot;);
} catch(e) {
xmlhttp = new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;);
}
}
xmlhttp.onreadystatechange = handler;
return xmlhttp;
}

function myHandler2() {
if (myRequest.readyState == 4 &amp;&amp; myRequest.status == 200) {
e = document.getElementById(&quot;ex4result&quot;);
e.innerHTML = myRequest.responseText;
}
}

function esempio4() {
var nome = document.f1.nome.value;
var r = Math.random();
myRequest = CreateXmlHttpReq(myHandler2);
myRequest.open(&quot;GET&quot;,&quot;secondo.php?nome=&quot;+escape(nome)+&quot;&amp;rand=&quot;+escape(r));
myRequest.send(null);
}
</pre>
<p>Il PHP del file secondo.php è il seguente semplice script:</p>
<pre class="brush: php">

&lt;?
if (isset($_GET[&#039;nome&#039;])) {
$n = strtolower($_GET[&#039;nome&#039;]);
$name[&#039;giorgio&#039;] = &quot;Bianchi&quot;;
$name[&#039;vittorio&#039;] = &quot;Rossi&quot;;
$name[&#039;augusto&#039;] = &quot;Verdi&quot;;
if (isset($name[$n])) {
echo(&quot;Il cognome di $n è $name[$n]&quot;);
} else {
echo(&quot;Non conosco il cognome di $n&quot;);
}
echo(&quot;
tempo corrente in secondi: &quot;.time().&quot;&quot;);
}
?&gt;
</pre>
<div class="example">
<form name="f1"> Nome:<br />
<input name="nome" type="input" />
<input onclick="script4()" type="button" value="Visualizza cognome" />
Risultato:
<div id="ex4result"></div>
</form>
</div>
<p>Per testare l&#8217;esempio sopra provate a immettere i nomi Giorgio, Vittorio, Augusto e premere <strong>Visualizza congome</strong>, poi provate a mettere un altro nome che non è contenuto nell&#8217;array del programma <strong>secondo.php</strong>, ad esempio Alessio. Avete capito bene come funziona il codice? Complimenti, ora potete dire di sapere come funziona Ajax, e anche spargere la voce sul fatto che le basi sono molto semplici. Ma non illudetevi, Ajax è facile, chiunque può imparare ad usarlo. Quasi tutta la programmazione è così, alla portata di tutti. La differenza che potete fare voi è che se avete talento e voglia potete diventare dei grandi programmatori, capaci di utilizzare astrazioni più potenti che vi rendono il lavoro più facile e veloce. La seconda parte di questo articolo, che è la motivazione per cui la prima parte è stata scritta, si sofferma proprio su questo: l&#8217;astrazione, ma prima permettetemi una breve digressione su XML.</p>
<h2>XML? no, grazie</h2>
<p>Il termine Ajax è un acronimo, e significa:</p>
<ul>
<li><strong style="color: red;">A</strong>synchronous</li>
<li><strong style="color: red;">Ja</strong>vascript</li>
<li>and <strong style="color: red;">X</strong>ML</li>
</ul>
<p>XML è una delle tre parti, eppure noi abbiamo utilizzato Ajax fino ad ora senza neppure toccare XML. Come mai? semplicemente chi ha coniato il termine pensava che il modo migliore per comunicare tra il programma che risiede sul server, e il client che fa la richiesta in Ajax, era quello di utilizzare XML. Lo pensano in molti, ma in realtà Ajax non ha niente a che fare con XML. PHP (o chi per lui) e Javascript possono spedirsi i dati in qualunque formato desiderabile. Si noti come di solito la grande quantità dei dati passi dal server al client. Ad esempio in Gmail il server spedisce al client informazioni sui messaggi, e il client si occupa tramite Javascript di visualizzare tali messaggi nella pagina dell&#8217;utente. Di solito il passaggio di parametri dal client al server avviene semplicemente passando dei parametri tramite una richeista GET, come abbiamo fatto noi poco fa nel caso del nome.</p>
<p>Per questa ragione uno dei miei metodi preferiti per passare dati dal server all&#8217;interprete Javascript del client è utilizzare un formato di semplice testo nel caso di operazioni molto semplici. Ad esempio se devo controllare se uno username in fase di registrazione in un servizio web è già occupato prima di ricaricare la pagina, faccio ritornare dal server un semplice OK o ERR, e controllo dal Javascript se la stringa ritornata è l&#8217;una o l&#8217;altra.</p>
<p>Se invece è necessario passare molti dati, utilizzo una tecnica diversa. Creo nello script che gira sul server un array Javascript e lo spedisco. Dal lato Javascript uso la funzione <em>eval</em> per valutare l&#8217;Array, è già pronta, non mi serve scrivere un parser. Ecco un esempio in PHP.</p>
<pre class="brush: php">

&lt;?
echo(&#039;var data = Array(&quot;&#039;);
echo($a);
echo(&#039;&quot;,&quot;&#039;);
echo($b);
echo(&quot;)&quot;);
?&gt;
</pre>
<p>Semplice no? ma cosa succede se <strong>$a</strong> o <strong>$b</strong> contengono caratteri (in questo contesto) speciali come le virgolette? Per evitare qualunque problema basta utilizzare la seguente funzione.</p>
<pre class="brush: php">

&lt;?
function safejsstring($s) {
$a = unpack(&quot;C*&quot;,$s);
$res = &quot;&quot;;
foreach($a as $byte) {
$res .= sprintf(&quot;\\x%02x&quot;, $byte);
}
return $res;
}
?&gt;
</pre>
<p>Tale funzione prende una stringa PHP e la converte interamente in sequenze di escape nella forma <strong>\xHH</strong> dove HH è sono due cifre esadecimali. In questo modo Javascript riuscirà sempre ad interpretare la stringa in maniera corretta anche se fosse costituita da dati binari. Dal PHP potete generare semplicemente anche Array annidati, in breve strutture dati complicate quanto lo desiderate. Se volete usare XML&#8230; non vi tiene nessuno <img src='http://blog.webeng.it/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ma volevo soltanto che fosse chiaro che non è necessario e il termine è finito dentro questa tecnica di programmazione solo perchè l&#8217;autore dell&#8217;acronimo ha deciso così.</p>
<h2>Parte seconda: facciamo di meglio</h2>
<p>Carino Ajax vero? Ma se pensate a quanto codice abbiamo scritto per fare una mezza richiesta HTTP in Javascript, che abbiamo utilizzato in maniera esplicita una variabile globale, e quanto poco <em>astratto</em> dal reale problema che risolve risulta il nostro codice, non c&#8217;è mica da essere orgogliosi&#8230; dobbiamo proprio correre ai ripari.</p>
<p>Benvenuti nella seconda parte di questo articolo, dove (se non lo sapete già), imparerete come innalzare il livello del vostro Javascript utilizzando i concetti della <em>Programmazione Funzionale</em>. Se non sapete di cosa si tratta vi consiglio di leggere questa parte anche se non siete interessati a sapere di più su Ajax. In ogni caso i concetti che seguono sono assolutamente necessari per seguire la parte più avanzata dell&#8217;articolo, in cui saranno usati per creare una piccola libreria Ajax che ci libera dal tedio di fare tutto a mano, e che sembra <em>integrata</em> nel linguaggio.</p>
<h2>Funzioni anonime</h2>
<p>Utilizzando linguaggi che sono fondamentalmente imperativi, come il C, Java, PHP, Javascript (anche se l&#8217;ultimo come vedremo ha un buon supporto per la programmazione funzionale), una delle cose che capita spesso di fare è quella di scorrere un array indice dopo indice tramite un ciclo <em>for</em>.</p>
<p>Partiamo da un esempio reale&#8230; una operazione spesso necessaria è, dato un array, prendere l&#8217;elemento col valore massimo. Serve per un sacco di cose, una tra tutte: avete presente la nuova moda <em>web 2.0</em>, di visualizzare dei <em>tag</em> con un font o con un colore proporzionale alla sua popolarità? (più spesso proporzionalmente al logaritmo della popolarità). Bene, la prima cosa che serve per fare la proporzione è ovviamente sapere qual&#8217;è il valore del massimo elemento.</p>
<p>In javascript scrivereste abbastanza ovviamente:</p>
<pre class="brush: javascript">

var a = Array(10,5,7,81,28);
var max = a[0];
for (i = 1; i &lt; a.length; i++) {
if (a[i] &gt; max) {
max = a[i];
}
}
</pre>
<h2>La fuzione reduce</h2>
<p>E se vi serve sapere qual&#8217;è la stringa più lunga di un array? Vi serve un altro ciclo for. Una volta un programmatore ha detto <em>Se per ogni ciclo for che ho scritto nella mia vita potessi ricevere un centesimo sarei ricco</em>. Come possiamo liberarci da questa schiavitù del ciclo for? La soluzione è data dal fatto che in Javascript le funzioni sono <strong>oggetti di prima classe</strong>, che in breve significa che le funzioni così come un oggetto stringa o un numero possono essere passate come argometi ad altre funzioni e ritornate come valore di ritorno da funzioni. In pratica non c&#8217;è differenza sostanziale tra quello che si può fare con un numero, con una stringa e con una funzione. Ora abbiamo la soluzione al nostro primo problema, possiamo scrivere una potente funzione che si chiama <em>reduce</em>.</p>
<pre class="brush: javascript">

function reduce(a,f) {
if (a.length == 0) {
throw emptyArrayError;
}
var res = a[0];
for (var j = 1; j &lt; a.length; j++) {
res = f(res,a[j]);
}
return res;
}
</pre>
<p>Questa piccola funzione prende in ingresso due oggetti: il primo è un array, il secondo è una funzione <strong>f</strong>. Applica <strong>f</strong> ai primi due elementi dell&#8217;array, e prende il risultato. Poi applica <strong>f</strong> al risultato e al terzo elemento dell&#8217;array, e così via. in pratica se L&#8217;array contiene i valori 1,2,3,4 il risultato di <em>reduce</em> è <em>f(f(f(1,2),3),4)</em>.</p>
<p>Come vedete la funzione <strong>f</strong> che viene passata a <em>reduce</em> prende in input due argomenti, li compara, e ritorna uno dei due. Se <strong>f</strong> fosse una funzione che dati due argomenti ritorna il più grande dei due, il risultato di <em>reduce(a,f)</em> sarebbe il massimo elemento dell&#8217;array! Bene, ora siamo in grado di scrivere del codice che prende l&#8217;elemento più grande di un array senza ricorrere ad un clico <em>for</em> usando <em>reduce</em>. Ecco come.</p>
<pre class="brush: javascript">

function max(a,b) {
if (a &gt; b)
return a;
else
return b;
}

var a = Array(10,5,7,81,28);
var max = reduce(a,max);
</pre>
<p>In pratica abbiamo estrapolato quello che c&#8217;è di uguale in molti cicli for e lo abbiamo separato dal resto del codice, incarnandolo nella funzione <em>reduce</em>. Rimane un problema, abbiamo dovuto scrivere la funzione <em>max</em>, e ciò può essere noioso. Ora che abbiamo <em>reduce</em> vorremmo utilizzarla in tanti piccoli contesti quotidiani, e scrivere continuamente funzioni <em>aiutanti</em> è una noia. Ma Javascript non è un linguaggio smidollato! Infatti ha un concetto molto utile, le <strong>funzioni anonime</strong>. Se in Javascript le funzioni sono oggetti come tutti gli altri, perchè devono avere per forza un nome? Una stringa non ha un nome, neppure un numero. Anche le funzioni possono non averlo, possono essere scritte in maniera &#8220;letterale&#8221;, o messe dentro una variabile, come tutti gli altri tipi di dato. Basta usare la seguente notazione.</p>
<pre class="brush: javascript">

var a = Array(10,5,7,81,28);
var maxfunction = function(a,b) { return (a&gt;b) ? a : b };
var max = reduce(a,maxfunction);
</pre>
<p>Così come <strong>Array(1,2,3)</strong> ritorna un array, <strong>function(<em>parametri</em>) {<em>codice</em>}</strong> ritorna una funzione. Dunque nell&#8217;esempio sopra abbiamo creato una funzione e abbiamo messo il suo riferimento in una variabile, e poi l&#8217;abbiamo usata come argomento di <em>reduce</em>. Ma perchè usare una variabile intermedia? Ecco dunque la versione finale, in tutto il suo splendore <img src='http://blog.webeng.it/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<pre class="brush: javascript">

var a = Array(10,5,7,81,28);
var max = reduce(a,function(a,b){return (a&gt;b)?a:b;});
</pre>
<p>Confrontate questo codice per trovare il massimo elemento di un array con quello che avevamo scritto utilizzando il ciclo <em>for</em> all&#8217;inizio. Non solo questo, reduce fa tutto quello che volete&#8230; avete voglia di sommare l&#8217;array? Bene:</p>
<pre class="brush: javascript">

var a = Array(10,5,7,81,28);
var sum = reduce(a,function(a,b){return a+b;});
</pre>
<p>Il limite è la vostra fantasia.</p>
<h2>Le amiche di reduce: map e filter</h2>
<p>Anche se per i nostri scopi la cosa importante è la comprensione delle funzioni anonime (che permetteranno di capire cosa sono le <strong>chiusure</strong> nel prossimo paragrafo), la programmazione funzionale è uno strumento potentissimo, dunque illustro brevemente altre due classiche primitive della programmazione funzionale, <em>map</em> e <em>filter</em>.</p>
<p>Come <em>reduce</em> anche map prende come input un array e una funzione <strong>f</strong>, ma invece che ridurre l&#8217;array ad un solo elemento applicando una funzione come fa <em>reduce</em>, <em>map</em> ritorna un nuovo array in cui ogni elemento è stato ottenuto trasformando il vecchio elemento nel nuovo tramite una funzione <strong>f</strong>.</p>
<p>In termini pratici, dato l&#8217;array 1,2,4,7 ciò che ritorna map(a,f) è f(1),f(2),f(4),f(7). Ecco la funzione <em>map</em>.</p>
<pre class="brush: javascript">

function map(a,f) {
var res = Array();
for (var j = 0; j &lt; a.length; j++) {
res[j] = f(a[j]);
}
return res;
}
</pre>
<p>Questa volta la funzione <strong>f</strong> che passiamo come argomento a <em>map</em> è una funzione che prende un solo argomento (una funzione <em>unaria</em>), e ritorna un valore. Ecco un esempio di applicazione di <em>map</em>, che non fa altro che trasformare un array di numeri in un array dei quadrati di tali numeri.</p>
<pre class="brush: javascript">

var a = Array(1,5,4,3);
var b = map(a,function(x){return x*x});
</pre>
<p>Alla fine del programma l&#8217;array <strong>b</strong> conterrà gli elementi 1,25,16,9. Come potete immaginare è possibile sommare gli effetti di <em>map</em> e <em>reduce</em>, ad esempio provate a scrivere il codice che utilizzando queste due primitive sommi i quadrati degli elementi di un array. Si noti come anche se teoricamente siamo interessati soltanto al valore di ritorno della funzione <strong>f</strong>, sia possible forzare <em>map</em> a lavorare come una sorta di <em>foreach</em>.</p>
<pre class="brush: javascript">

var a = Array(1,5,4,3);
map(a,alert);
</pre>
<p>Queste due righe di codice avranno l&#8217;effetto di fare l&#8217;alert di tutti gli elementi dell&#8217;array. Il risultato della funzione map non viene utilizzato in nessun modo perch&amp;egrabe; non è nostro scopo, in questo caso siamo solo interessati nell&#8217;<em>effetto collaterale</em> (o side effect) che ha la chiamata della funzione <strong>f</strong> (ovvero <em>alert</em>), che è quello di visualizzare i numeri.</p>
<p>L&#8217;ultima delle funzioni che giocano un ruolo importante tra le primitive della programmazione funzionale su cui ci soffermeremo è <em>filter</em>. Questa funzione sarà solo descritta in quanto concettualmente molto simile alle altre due. L&#8217;implementazione di filter è lasciata come esercizio al lettore. Ma cosa fa <em>filter</em>? Dato un Array e una funzione unaria <strong>f</strong> in ingresso, ritorna un Array composto solo dagli elementi per cui la chiamata alla funzione <strong>f</strong> restituisce <em>true</em>. In pratica <em>filter</em> filtra l&#8217;array e ne crea uno che ha come elementi solo quelli che piacciono alla funzione passata come argomento, che utilizza il valore di ritorno <em>true</em> o <em>false</em> per indicare se tenere o scartare ogni dato elemento</p>
<p>Utilizzando assieme map, filter e reduce è per esempio possibile in una singola linea di codice processare un array per tenere solo gli elementi che sono maggiori di 10, elevarli al quadrato e ottenerne la somma. Ma ora è tempo di chiudere questa (spero interessante) parentesi e continuare il nostro breve incontro delle caratteristiche evolute di Javascript.</p>
<h2>Le chiusure</h2>
<p>La più semplice definizione di chiusura, e anche una delle meno immediatamente comprensibili per chi non le conosce, è la seguente: <em>una chiusura è una funzione con uno stato ad essa associato</em>. Cosa significa di preciso? Per spiegarlo bisogna fare un passo indietro, e ritornare alle <em>funzioni anonime</em> di cui abbiamo parlato prima (se non ricordate bene cosa sono, tornate indietro a fare un ripasso e poi ritornate qui!). Abbiamo detto che in Javascript le funzioni sono un oggetto di prima classe, e abbiamo infatti visto come sia possibile passare una funzione come argomento ad un&#8217;altra funzione. Abbiamo anche affermato che è possibile scrivere funzioni che ritornano funzioni come argomento. Ad esempio il codice</p>
<pre class="brush: javascript">

function creaFunzione() {
var f = function() {return 1};
return f;
}
var b = creaFunzione();
alert(b());
</pre>
<p>quando viene eseguito mostra un alert in cui c&#8217;è scritto <strong>1</strong>. La funzione <em>creaFunzione</em> ritorna una funzione che non fa altro che ritornare <strong>1</strong> (scusate il gioco di parole, ma è proprio cosi, creaFunzione ritorna una funzione che quando viene chiamata ha come valore di ritorno l&#8217;intero 1). Tale funzione ritornata da <em>creaFunzione</em> viene salvata dentro la variabile <em>b</em>. Da questo momento in poi <strong>b</strong> può essere usata come una funzione, infatti la chiamiamo nell&#8217;ultima riga del programma di esempio, per ottenere l&#8217;argomento di <em>alert</em>.</p>
<p>Fin qui nulla di nuovo. Esistono le funzioni anonime, e come tutte le altre funzioni sono oggetti di prima classe: possono essere utilizzato come argomento, ritornate da altre funzioni, tenute dentro le variabili, e qualunque altra cosa fareste con un numero, una stringa o un array (anch&#8217;essi tutti oggetti di prima classe). Ma cosa accade se nel corpo di una funzione anonima c&#8217;è un riferimento ad una variabile che è definita al momento della sua creazione nello <em>scopo</em> esterno ad essa? Un esempio chiarirà cosa voglio dire.</p>
<pre class="brush: javascript">

function creaFunzione(valore) {
var f = function() {return valore};
return f;
}
</pre>
<p>La variabile <em>valore</em> esiste mentre la funzione <em>creaFunzione</em> viene eseguita, e come potete vedere compare nel corpo della funzione anonima che alla fine restituiamo come valore di ritorno. Ma quando utilizzeremo la funzione anonima creata, creaFunzione non sarà più attiva, dunque cosa contiene la variabile <em>valore</em> quando la funzione anonima viene invocata?. Concentratevi che questo è un passaggio delicato. Ciò che accade è che la funzione anomina create <strong>ricorderà</strong> il riferimento all&#8217;oggetto che aveva la variabile <em>valore</em> al momento in cui la funzione anonima è stata creata. Dunque se scrivo</p>
<pre class="brush: javascript">

a = creaFunzione(10);
b = creaFunzione(20);
a(); // ritorna 10
b(); // ritorna 20
</pre>
<p>Le funzioni <em>a</em> e <em>b</em> ritorneranno ad ogni chiamata rispettivamente 10 e 20! Ecco cosa significa che una chiusura è una funzione con uno stato ad essa associato. La chiusura ricorda tutti i riferimenti a variabili esterne al momento della sua creazione. La cosa interessante è che questo <em>stato</em> che la chiusura si porta appresso può anche essere modificato.</p>
<p>Per esempio è possibile scrivere una funzione che ritorna delle funzioni che contano.</p>
<pre class="brush: javascript">

function creaContatore() {
var c=0;
return function() {
return c++;
}
}

var a = creaContatore();
var b = creaContatore();
a(); /* ritorna 0 */
a(); /* ritorna 1 */
a(); /* ritorna 2 */
b(); /* ritorna 0 */
b(); /* ritorna 1 */
a(); /* ritorna 3 */
</pre>
<p>Ad ogni chiamata a() e b() ritornano l&#8217;intero successivo (partendo da zero), e <strong>ricordano</strong> dove erano arrivate. Siccome questo non è un corso completo di programmazione funzionale non mi posso spingere oltre, ma provate a immaginare le possibilità&#8230; (argh, sembra lo spot della Apple).</p>
<h2>Chiusure e handler?</h2>
<p>C&#8217;è un campo in cui è necessario soffermarsi sull&#8217;applicazione delle chiusure: le funzioni che gestiscono eventi in Javascript, ovvero i così detti <em>handler</em>. Partiamo da un problema reale, e vediamo come viene affrontato tramite le chiusure. In una pagina HTML ci sono due elementi: uno spazio in cui l&#8217;utente può scrivere qualcosa (un banale elemento <strong>INPUT</strong> di tipo <em>text</em>) e un bottone. Alla pressione del bottone Javascript fa partire un timer, che dopo dieci secondi mostrerà un alert che visualizza cosa c&#8217;era scritto nell&#8217;<strong>INPUT</strong> al momento in cui l&#8217;utente aveva premuto il tasto. Eccovi l&#8217;esempio funzionante.</p>
<div class="example">
<input id="inputobj" type="text" />
<input onclick="whenButtonIsPressed()" type="button" value="Premi qui" /></div>
<p>L&#8217;utente potrebbe ad esempio scrivere <em>hello</em> e premere il tasto, poi scrivere <em>world</em> e premere il tasto. Dopo alcuni secondi vedrebbe in successione due alert, uno in cui è scritto <em>hello</em> e l&#8217;altro in cui è scritto <em>world</em>. Per implementare un tale programma qualcuno potrebbe essere tentato di scrivere qualcosa come:</p>
<pre class="brush: javascript">

function whenButtonIsPressed() {
setTimeout(showAlert, 10000);
}
function showAlert() {
var e = object.getElementById(&quot;inputobj&quot;);
alert(e.value);
}
</pre>
<p>Nell&#8217;esempio immaginiamo che il bottone abbia un evento onClick che richiama la funzione <em>whenButtonIsPressed</em> e che il testo digitato dall&#8217;utente sia contenuto in un elemento <strong>INPUT</strong> con ID <em>inputobj</em>.</p>
<p>Ovviamente il codice mostrato sopra non funziona, perchè l&#8217;handler del timer, ovvero la funzione <em>showAlert</em>, va a leggere il contenuto dell&#8217;<strong>INPUT</strong> solo quando deve visualizzare l&#8217;alert. Se nel mentre il contenuto è cambiato perchè l&#8217;utente nel corso dei 10 secondi ha scritto qualcosa di nuovo il nostro gioco non funziona. Noi vogliamo che alla pressione del tasto, l&#8217;alert risultante 10 secondi dopo visualizzi <strong>quello che c&#8217;era scritto quando il tasto era stato premuto</strong>. Ci servirebbe un handler che ha memoria del passato&#8230; ovvero, una chiusura! Ecco il codice corretto:</p>
<pre class="brush: javascript">

function whenButtonIsPressed() {
var string = document.getElementById(&quot;inputobj&quot;).value;
var myHandler = function() {
alert(string);
};
setTimeout(myHandler, 10000);
}
</pre>
<p>Abbiamo risolto il problema con un&#8217;unica funzione. La chiusura  che usiamo come handler ha un riferimento a <em>string</em>, dunque si crea un collegamento tra l&#8217;oggetto che conteneva tale variabile al momento della creazione della funzione e la funzione stessa.</p>
<p><em>Nota: questo particolare problema potrebbe essere risolto anche tramite eval(), ma ci sono molti casi in cui le chiusure risolvono problemi non risolvibili con eval() e tantissimi altri casi in cui risolvono i problemi in maniera molto più elegante.</em></p>
<h2>Ajax comodo</h2>
<p>Siamo prossimi alla conclusione. Con le conoscenze acquisite ci proponiamo di scrivere delle funzioni che rendono Ajax così semplice che per fare una query in Ajax e mostrare la risposta in un alert basterà scrivere:</p>
<pre class="brush: javascript">

ajaxGet(&quot;primo.php&quot;,myHanlder);
function myHandler(content) {
alert(content);
}
</pre>
<p>In pratica la funzione <em>ajaxGet</em> dovrà predisporre la query, e poi chiamare l&#8217;handler passando come primo argomento il risultato della richiesta HTTP <strong>solo</strong> se la richiesta è andata a buon fine. Non c&#8217;è nessuna variabile globale, nessun controllo dello stato, tanto meno la ripetizione del codice necessario per creare l&#8217;oggetto necessario alla richiesta e alla sua inizializzazione. Ma non ci accontentiamo di questo, l&#8217;altra importantissima caratteristica che deve avere la nostra nuova interfaccia verso Ajax è la seguente: qualunque argomento addizionale passato alla funzione <em>ajaxGet</em> dovrà essere passato all&#8217;handler quando la richiesta viene completata, dunque il codice:</p>
<pre class="brush: javascript">

ajaxGet(&quot;primo.php&quot;,myHandler,&quot;a&quot;,10);
function myHandler(content,first,second) {
alert(content);
alert(first);
alert(second);
}
</pre>
<p>Avrà l&#8217;effetto di eseguire la richiesta e chiamare l&#8217;Handler con la risposta ottenuta dal server come primo argomento, la stringa &#8220;a&#8221; come secondo argomento e l&#8217;intero 10 come terzo. Riflettete un pò su questa caratteristica e vi accorgerete come ora la richiesta sia in grado di portarsi appresso lo stato, e permetta dunque di usare lo stesso handler per gestire diverse situazioni. Infatti dietro l&#8217;implementazione di <em>ajaxGet</em> ci sono proprio le chiusure, abbiamo preso i vantaggi della closure e li abbiamo trasportati nella nostra API, anche se nella pratica per usare tale API non serve conoscere le chiusure.</p>
<p>E&#8217; importante notare come la possibilità di passare argomenti addizionali all&#8217;handler aumenti la potenza della nostra interfaccia. Immaginate di avere due divesi elementi <strong>DIV</strong> nella pagina. Volete fare delle richieste a diversi file PHP e visualizzare il contenuto in un <strong>DIV</strong> o nell&#8217;altro tramite <em>innerHTML</em>. Potete semplicemente scrivere:</p>
<pre class="brush: javascript">

ajaxGet(&quot;primo.php&quot;,myHandler,&quot;primodiv&quot;);
function myHandler(content,elementid) {
var e = document.getElementById(elementid);
e.innerHTML = content;
}
</pre>
<p>Se più tardi volete fare una nuova richiesta ma visualizzare il risultato in un <strong>DIV</strong> diverso, potrete riutilizzare il vecchio handler e scrivere semplicemente:</p>
<pre class="brush: javascript">

ajaxGet(&quot;primo.php&quot;,myHandler,&quot;secondodiv&quot;);
</pre>
<p>Vedrete come nella vita reale qualunque applicazione Ajax non banale presenta questo tipo di necessità. Ora che abbiamo visto come vorremmo che fosse la nostra interfaccia verso Ajax, andiamo ad implementarla utilizzando le tecniche di programmazione imparate fino ad ora e qualcuna nuova che sarà esposta quando occorre.</p>
<h2>Implementazione</h2>
<p>Iniziamo dalla fine, mostrando il codice completo della funzione <em>ajaxGet</em> e della sua funzione aiutante <em>ajaxOk</em>.</p>
<pre class="brush: javascript">

var ajax_req = null;

function ajaxOk() {
if (ajax_req.readyState == 4 &amp;&amp; ajax_req.status == 200) {
return ajax_req.responseText;
} else {
return false;
}
}

function ajaxGet(url,handler) {
var a = new Array(&quot;placeholder&quot;);
for (var j=2; j&lt;arguments.length; j++) {
a[a.length] = arguments[j];
}
var myhandler = function() {
var content = ajaxOk();
if (content != false) {
a[0] = content;
return handler.apply(this, a);
}
}
ajax_req = CreateXmlHttpReq(myhandler);
ajax_req.open(&quot;GET&quot;,url);
ajax_req.send(null);
}
</pre>
<p>La funzione <em>ajaxOk</em> svolge un compito banale, se avete ancora fresca nella memoria la prima parte dell&#8217;articolo ricorderete che le proprietà <em>readyState</em> e <em>status</em> dell&#8217;oggetto xmlHttpReq vengono utilizzate per controllare lo stato della richiesta, ovvero se è andata a buon fine. In caso positivo, tramite la proprietà <em>responseText</em> si può ottenere il contenuto della riposta HTTP. Alla luce di questi fatti si vede subito che <em>ajaxOk</em> non fa altro che controllare se la richiesta registrata nella variabile globale <em>ajax_req</em> sia terminata con esito positivo, e in tal caso ritornare la risposta ottenuta. In caso contrario invece viene ritornato <em>false</em>.</p>
<p>Analizziamo ora il pezzo forte, ovvero <em>ajaxGet</em>. Questa è una funzione che utilizza un numero variabile di argomenti. In Javascript ogni funzione ha accesso esplicito alla lista di argomenti con cui è stata chiamata tramite l&#8217;array <em>arguments</em>. Quello che fanno le prime righe di codice di ajaxGet è predisporre un array con il primo elemento settato a una stringa arbitraria (che sarà poi rimpiazzata dal testo della riposta HTTP), e tutti gli altri argomenti settati al valore passato dall&#8217;utente ad <em>ajaxGet</em> come argomenti addizionali. In pratica questo array sarà utilizzato per chiamare l&#8217;handler quando la richiesta Ajax è completa. Infatti sotto si procede alla creazione dell&#8217;handler <strong>vero</strong> della richiesta, quello che poi chiamerà l&#8217;handler più astratto, in pratica il vero handler fa da <em>wrapper</em> o da interfaccia per usare un termine italiano a quello di più alto livello. Utilizzando la funzione <em>ajaxOk</em> il vero handler controlla che la richiesta abbia avuto buon fine (altrimenti non fa nulla), in caso positivo setta il primo elemento dell&#8217;array <strong>a</strong> alla risposta ottenuta. Ora l&#8217;array <strong>a</strong> contiene una la lista degli argomenti con cui richiamare l&#8217;handler di <em>alto livello</em>, e il gioco è fatto. Si noti come sia l&#8217;array <strong>a</strong> che l&#8217;argomento <strong>handler</strong> della funzione ajaxGet siano memorizzati nella chiusura assegnata alla variabile <strong>myHandler</strong>. Ecco dunque a cosa servivano le chiusure in questa nostra libreria.</p>
<h2>La funzione apply</h2>
<p>Siamo all&#8217;ultima riga di codice che rimane oscura:</p>
<pre class="brush: javascript">

return handler.apply(this, a);
</pre>
<p>Cosa fa <em>apply</em>?. Il problema è il seguente: l&#8217;handler reale deve chiamare il nostro handler di alto livello con la lista di argomenti settati nell&#8217;array <strong>a</strong>. Come si richiama una funzione utilizzando come argomenti gli elementi di un array? In breve se ho un array che contiene gli elementi &#8220;a&#8221;, &#8220;b&#8221; e &#8220;c&#8221;, e una funzione <em>f()</em>, vorrei avere qualcosa che produca l&#8217;effetto di una chiamta a <em>f(&#8220;a&#8221;,&#8221;b&#8221;,&#8221;c&#8221;)</em>. Il metodo <em>apply</em> di ogni oggetto funzione Javascript fa proprio questo. A questo punto dovrebbe essere tutto chiaro, le seguenti righe di codice non fanno altro che creare la richiesta e assegnarla alla variabile globale <em>ajax_req</em>, e finalmente spedire la richiesta.</p>
<h2>La variabile globale</h2>
<p>Come avete visto anche se nell&#8217;utlizzo della nuova interfaccia non c&#8217;è traccia di variabili globali, nella implementazione l&#8217;abbiamo utilizzata. Ciò era in questo caso desiderabile perchè la funzione <em>CreateXmlHttpReq</em> si occupa sia di creare l&#8217;oggetto necessario alla richiesta XmlHttpReq che di settare l&#8217;handler. Separando tale funzione in due parti, una che crea la richiesta ed una che setta l&#8217;handler, la necessità di una variabile globale non sussiste più, ma poichè viene fatta al massimo una richiesta Ajax per volta e non volevo rimettere le mani nel codice esposto nella prima parte per non creare confusione ho preferito questa soluzione. In realtà non c&#8217;è alcun motivo per non registare anche l&#8217;oggetto della richiesta nella chiusura, dunque una buona esercitazione è quella di riscrivere il codice in modo da evitare le variabili globali (anche se nella vita reale l&#8217;implementazione esposta potrebbe essere più conveniente perchè la parte incompatibile tra i diversi browser viene isolata in una sola funzione).</p>
<h2>Internet Explorer 5</h2>
<p>Purtroppo il codice sopra esposto non funzionerà con Internet Explorer 5, perchè tale browser non implementa <em>apply</em>. Siccome ancora c&#8217;è circa l&#8217;un percento della popolazione di internet che utilizza tale browser è bene sopportarlo in qualche modo. A tal fine ho scritto una implementazione di <em>apply</em> utilizzando la funzione eval:</p>
<pre class="brush: javascript">

function myDummyApply(funcname,args) {
var e = &quot;funcname(&quot;;
for (var i = 0; i &lt; args.length; i++) {
e += &quot;args[&quot;+i+&quot;]&quot;;
if (i+1 != args.length) {
e += &quot;,&quot;;
}
}
e += &quot;);&quot;
return eval(e);
}
</pre>
<p>Anche <em>ajaxGet</em> va modificata per utilizzare tale funzione se la <em>apply</em> reale fallisse. Ecco dunque il codice integrale completo di ogni pezzo che implementa l&#8217;interfaccia Ajax comoda da usare.</p>
<p><strong>(30 Maggio 2007) Nota: la funzione e&#8217; stata aggiornata per memorizzare l&#8217;oggetto della richiesta Ajax nella chiusura</strong>, questo significa che la nuova funzione ora gestisce richieste simultanee senza problemi. Questa modifica e&#8217; stata fatta nel codice che uso in produzione da un anno ma ho sempre dimenticato di metterla online, scusate per l&#8217;inconveniente. Consiglio a tutti di utilizzare questa nuova versione.</p>
<pre class="brush: javascript">

/* Copyright(C) 2005,2006,2007 Salvatore Sanfilippo &lt;antirez@gmail.com&gt;
* All Rights Reserved. */

// Create the XML HTTP request object. We try to be
// more cross-browser as possible.
function CreateXmlHttpReq(handler) {
var xmlhttp = null;
try {
xmlhttp = new XMLHttpRequest();
} catch(e) {
try {
xmlhttp = new ActiveXObject(&quot;Msxml2.XMLHTTP&quot;);
} catch(e) {
xmlhttp = new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;);
}
}
xmlhttp.onreadystatechange = handler;
return xmlhttp;
}

// An handler that does nothing, used for AJAX requests that
// don&#039;t require a reply and are non-critical about error conditions.
function DummyHandler() {
return true;
}

// Shortcut for creating a GET request and get the reply
// This few lines of code can make Ajax stuff much more trivial
// to write, and... to avoid patterns in programs is sane!
function ajaxGet(url,handler) {
var a = new Array(&quot;placeholder&quot;);
for (var j=2; j&lt;arguments.length; j++) {
a[a.length] = arguments[j];
}
var ajax_req = CreateXmlHttpReq(DummyHandler);
var myhandler = function() {
var content = ajaxOk(ajax_req);
if (content !== false) {
a[0] = content;
try {
return handler.apply(this, a);
} catch(e) {
return myDummyApply(handler, a);
}
}
}
ajax_req.onreadystatechange = myhandler;
ajax_req.open(&quot;GET&quot;,url);
ajax_req.send(null);
}

// IE 5.0 does not support the apply() method of the function object,
// we resort to this eval-based solution that sucks because it is not
// capable of preserving &#039;this&#039; and is ugly as hell, but it works for us.
function myDummyApply(funcname,args) {
var e = &quot;funcname(&quot;;
for (var i = 0; i &lt; args.length; i++) {
e += &quot;args[&quot;+i+&quot;]&quot;;
if (i+1 != args.length) {
e += &quot;,&quot;;
}
}
e += &quot;);&quot;
return eval(e);
}

// Add a random parameter to the get request to avoid
// IE caching madness.
function ajaxGetRand(url,handler) {
url += (url.indexOf(&quot;?&quot;) == -1) ? &quot;?&quot; : &quot;&amp;&quot;;
url += &quot;rand=&quot;+escape(Math.random());
arguments[0] = url;
try {
return ajaxGet.apply(this,arguments);
} catch(e) {
return myDummyApply(ajaxGet,arguments);
}
}

function ajaxOk(req) {
if (req.readyState == 4 &amp;&amp; req.status == 200) {
return req.responseText;
} else {
return false;
}
}

function $(id) {
return document.getElementById(id);
}

function $html(id) {
return document.getElementById(id).innerHTML;
}

function $sethtml(id,html) {
document.getElementById(id).innerHTML += html;
}

function $apphtml(id,html) {
document.getElementById(id).innerHTML += html;
}
</pre>
<p>Nel codice finale ci sono due aggiunte. La prima è una funzione <em>DummyHandler</em> che non fa proprio niente. Si usa come handler Ajax quando si vuole semplicemente fare una richiesta al server senza avere alcuna risposta. Si potrebbe modificare la <em>ajaxGet</em> in modo da accettare <em>false</em> come handler e capire da sola che non deve chiamarlo in tal caso.</p>
<p>La seconda aggiunta è una versione potenziata di <em>ajaxGet</em> che si chiama <em>ajaxGetRand</em> che aggiunge automaticamente alla richiesta un parametro casuale per evitare i problemi di cache di Internet Explorer esposti nella prima parte dell&#8217;articolo.</p>
<h2>Gestione degli errori</h2>
<p>Per completezza ci sarebbe ancora una cosa da fare per migliorare questo codice: si dovrebbe gestire la condizione di errore delle richieste e visualizzare un alert, qualcosa come <em>Problemi di comunicazione col server</em> se la richiesta fallisce. Poichè questo articolo ormai sfiora le 60000 battute, non mi resta che lasciare anche questo come esercizio al lettore volenteroso, e passare alle conclusioni.</p>
<h2>Escape degli argomenti della richiesta</h2>
<p>Quando si fa una qualunque richiesta HTTP utilizzando il metodo GET, è necessario fare l&#8217;<em>escape</em> degli argomenti nella richiesta in modo da essere certi che non contengano caratteri che in una query sono considerati speciali come ad esempio <strong>?</strong>, <strong>+</strong>, <strong>&amp;</strong> ed altri ancora. A questo scopo bisogna utilizzare la funzione Javascript <em>encodeURIComponent</em> che è più o meno l&#8217;equivalente della funzione PHP <em>urlencode</em>. Dunque se devo passare un parametro tramite ajaxGet ad uno script PHP scriverò qualcosa come:</p>
<pre class="brush: javascript">

ajaxGet(&quot;/script.php?parametro=&quot;+encodeURIComponent(parametro),myHandler);
</pre>
<p>I browser più vecchi quali il solito IE 5 non possiedono tale funzione, ma una meno sicura che non fa l&#8217;escape in maniera corretta di alcuni caratteri (come il <strong>+</strong>), chiamata <em>escape</em> (la funzione inversa è <em>unescape</em>). Se dovete passare parametri che sicuramente non contengono uno spazio potete accontentarvi di <em>escape</em>, altrimenti è necessario usare la giusta funzione. Se proprio volete il massimo della compatibilità vi consiglio di scrivere una funzione per conto vostro che faccia l&#8217;escape di tutti i caratteri tranne alcuni contenuti in una lista (i caratteri alfanumerici nell&#8217;intervallo A-z e 0-9 non hanno bisogno di alcun escape).</p>
<h2>Conclusioni</h2>
<p>Forse avrei potuto fare un articolo lungo un decimo, mostrando direttamente il poco codice che serve a rendere Ajax più comodo ed astratto da utilizzare, e rimandando ogni parte meno ovvia del codice a riferimenti esterni, avrei anche evitato di spendere le quasi 8 ore che ci sono volute per scrivere questo articolo, ma non credo sarebbe stato lo stesso. Le risorse in inglese su Ajax abbondano mentre in italiano c&#8217;è ben poco, dunque pensavo che sarebbe stato utile avere in un unico articolo una introduzione ad Ajax e un approfondimento sulle tecniche evolute di programmazione con Javascript. Spero vivamente che questo articolo serva ad almeno un programmatore di lingua italiana a scoprire qualcosa di nuovo. Ringrazio tutti i lettori che sono arrivati a leggere fino a questo punto, non erano argomenti semplicissimi. Alla prossima. <!-- Fine articolo --></p>
<h2>Javascript playground</h2>
<p>La Javascript console di Firefox (IE manco la possiede) non è esattamente il massimo per sperimentare con Javascript, problema che ho avvertito più volte in passato e che sto constatando ancora una volta mentre scrivo questo articolo, per questo motivo propongo la <em>Javascript playground</em>, una area di testo e relativa finestra dove va a finire l&#8217;output, e che serve ovviamente per giocare con Javascript.</p>
<p>L&#8217;utilizzo è semplice: scrivete uno script nell&#8217;area di testo arancione, premete &#8220;esegui&#8221;, e vedete l&#8217;output nella parte grigio chiara. Per emettere l&#8217;output dovete usare due funzioni normalmente non disponibili in Javascript ma implementate qui di proposito: <em>echo</em>, e <em>clearscreen</em>. La prima prende un argomento e lo stampa nella finestra di output, la seconda cancella tutto il contenuto dell&#8217;area di output. E&#8217; più facile guardare l&#8217;esempio che spiegare come funziona mi sa <img src='http://blog.webeng.it/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<div class="example"><textarea id="playgroundinput">clearscreen();for (var i=0;i<10;i++){echo(i+"\n");}</textarea><br />
<textarea id="playgroundoutput"></textarea></p>
<input onclick="playgroundrun()" type="button" value="Esegui" />
<input onclick="clearscreen()" type="button" value="Cancella" /></div>
<p>Articolo tratto da : <a href="http://antirez.com/articoli/spaghettiajax.html" target="_blank">http://antirez.com/articoli/spaghettiajax.html</a><br />
Autore : Salvatore Sanfilippo</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webeng.it/2009/02/07/guida-ad-ajax-spaghetti-ajax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Estensioni Firefox: la Top 10 per il Web Design</title>
		<link>http://blog.webeng.it/2009/01/29/estensioni-firefox-la-top-10-per-il-web-design/</link>
		<comments>http://blog.webeng.it/2009/01/29/estensioni-firefox-la-top-10-per-il-web-design/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 00:55:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Articoli Generici]]></category>
		<category><![CDATA[Link utili]]></category>
		<category><![CDATA[Sviluppo Web]]></category>
		<category><![CDATA[estensioni]]></category>
		<category><![CDATA[firebug]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[html validator]]></category>
		<category><![CDATA[seo for firefox]]></category>
		<category><![CDATA[web developer]]></category>

		<guid isPermaLink="false">http://blog.webeng.it/?p=807</guid>
		<description><![CDATA[Firefox si è rivelato uno dei migliori browser per lo sviluppo sul web, uno strumento indispensabile per ogni Web Designer al di là della sua diffusione presso i non professionisti.
In questo articolo voglio elencare le 10 estensioni di Firefox a cui non potrei mai rinunciare, che mi aiutano nel lavoro di tutti i giorni e [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.webeng.it/wp-content/uploads/2009/01/estensioni-firefox.jpg"><img class="alignnone size-full wp-image-808" style="float: left; margin-right: 5px;" title="estensioni-firefox" src="http://blog.webeng.it/wp-content/uploads/2009/01/estensioni-firefox.jpg" alt="" width="126" height="126" /></a>Firefox si è rivelato uno dei migliori browser per lo sviluppo sul web, uno strumento indispensabile per ogni Web Designer al di là della sua diffusione presso i non professionisti.</p>
<p>In questo articolo voglio elencare le <strong>10 estensioni di Firefox</strong> a cui non potrei mai rinunciare, che mi aiutano nel lavoro di tutti i giorni e che spero possano risultare utili a chi ancora non le conosce.</p>
<p><span id="more-807"></span>1. <a href="https://addons.mozilla.org/it/firefox/addon/60">Web Developer</a></p>
<p>Aggiunge una toolbar con numerosi strumenti e funzionalità, dalla possibilità di disabilitare i <acronym title="Cascading Style Sheet">CSS</acronym> alla validazione della pagina corrente.</p>
<p>2. <a href="https://addons.mozilla.org/it/firefox/addon/1843">Firebug</a></p>
<p>Permette di fare il debug e modificare il contenuto di una pagina con pochi clic, monitorando CSS, HTML e Javascript in tempo reale. La considero un’estensione complementare a Web Developer, piuttosto che sostitutiva.</p>
<p>3. <a href="https://addons.mozilla.org/it/firefox/addon/4187">CSS Mate</a></p>
<p>Estensione fondamentale per fare test al volo sui CSS di una pagina, avendo un feedback immediato.</p>
<p>4. <a href="https://addons.mozilla.org/it/firefox/addon/1419">IE Tab</a></p>
<p>Per testare un sito è comodo avere degli strumenti che facilitino lo switch tra i vari browser. Questa estensione permette di visualizzare una pagina con il rendering engine di Internet Explorer dentro una tab di Firefox.</p>
<p>5. <a href="https://addons.mozilla.org/it/firefox/addon/1429">IE View Lite</a></p>
<p>Variante di IE Tab (vedi sopra), consente di aprire la pagina corrente in una finestra di Explorer tramite una voce nel menu contestuale.</p>
<p>6. <a href="https://addons.mozilla.org/it/firefox/addon/1190">OperaView</a></p>
<p>Estensione dal funzionamento analogo ad IE View, utile per aprire una pagina sul browser Opera.</p>
<p>7. <a href="https://addons.mozilla.org/it/firefox/addon/249">HTML Validator</a></p>
<p>Aggiunge all’interno della finestra per la visualizzazione del codice alcune indicazioni utili sulla validazione della pagina. Segnala errori e warnings, con utili suggerimenti per correggerli.</p>
<p>8. <a href="https://addons.mozilla.org/it/firefox/addon/539">MeasureIt</a></p>
<p>Semplice ma utilissimo tool che crea un righello con il quale misurare gli elementi di una pagina.</p>
<p>9. <a href="https://addons.mozilla.org/it/firefox/addon/1146">Screengrab!</a></p>
<p>Per catturare screenshot di una pagina salvando solo la porzione visibile o tutto il contenuto. Questa estensione è stata migliorata ed il salvataggio dei file immagine ora è molto più veloce.</p>
<p>10. <a href="http://tools.seobook.com/firefox/seo-for-firefox.html">SEO for Firefox</a></p>
<p>Aggiunge informazioni utili ai risultati della ricerca di Google: PageRank, età del dominio, numero di links, rank su Technorati ed Alexa e molto altro.</p>
<p>Trovate queste estensioni di Firefox anche nella <a href="http://www.tomstardust.com/utility">pagina utility</a> di TomStardust.com, insieme ad altre risorse. Se avete consigli sull’argomento o se pensate che nell’elenco manchi qualcosa di importante non esitate a dirlo nei commenti!</p>
<p>Articolo tratto da: <a href="http://www.tomstardust.com/archives/estensioni-firefox-la-top-10-per-il-web-design/" target="_blank">http://www.tomstardust.com/archives/estensioni-firefox-la-top-10-per-il-web-design/</a></p>
<p>Autore: <strong>Tommaso Baldovino</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webeng.it/2009/01/29/estensioni-firefox-la-top-10-per-il-web-design/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Guida Introduttiva a PHP 5</title>
		<link>http://blog.webeng.it/2008/12/09/guida-introduttiva-a-php-5/</link>
		<comments>http://blog.webeng.it/2008/12/09/guida-introduttiva-a-php-5/#comments</comments>
		<pubDate>Tue, 09 Dec 2008 11:00:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Articoli Generici]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Sviluppo Web]]></category>
		<category><![CDATA[sviluppo web]]></category>

		<guid isPermaLink="false">http://blog.webeng.it/?p=115</guid>
		<description><![CDATA[Lo scopo di questa guida è quello di portare le conoscenze di un neofita del PHP, a livello professionale.
Anche chi non ha mai programmato in PHP puo&#8217; tranquillamente avvicinarsi a questo fantastico linguaggio, per la prima volta, con questa guida che illustrerà passo passo e in modo dettagliato tutte le caratteristiche di PHP 5.
Dalla struttura [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.webeng.it/wp-content/uploads/2008/12/php.jpg"><img class="alignnone size-full wp-image-350" style="float: left; margin-right: 5px;" title="php" src="http://blog.webeng.it/wp-content/uploads/2008/12/php.jpg" alt="" width="140" /></a>Lo scopo di questa guida è quello di portare le conoscenze di un neofita del PHP, a livello professionale.</p>
<p>Anche chi non ha mai programmato in PHP puo&#8217; tranquillamente avvicinarsi a questo fantastico linguaggio, per la prima volta, con questa guida che illustrerà passo passo e in modo dettagliato tutte le caratteristiche di PHP 5.</p>
<p><span id="more-115"></span>Dalla struttura del linguaggio, alle nozioni necessarie per creare delle vere e proprie applicazioni web.</p>
<p>PHP è un linguaggio Server-Side che vi permetterà di creare delle pagine dinamiche, scrivendo il vostro codice anche in mezzo alla stessa pagina HTML.</p>
<p>Server-Side significa che il vostro codice risiederà solo sul server, e che non sarà pertanto possibile accedere ai sorgenti dal lato client, come invece accade con linguaggi Client-Side come JavaScript.</p>
<p>In pratica, quando un utente apre una vostra pagina PHP, il Web Server viene interrogato e restituisce al client niente altro che una semplice pagina HTML o XHTML ecc&#8230;</p>
<p>La pagina HTML che il client visualizzerà, sarà prodotta da PHP grazie alle vostre direttive.</p>
<p>Prima di iniziare a programmare, è necessario che vi procuriate il software necessario.</p>
<p>Per testare le vostre applicazioni, AppServ andrà più che bene.<br />
E&#8217; un pacchetto autoinstallante per piattaforma Windows, che installerà e configurerò automaticamente tutti i pacchetti di cui avrete bisogno, nel vostro PC.</p>
<p>Al momento in cui scrivo è disponibile la versione <strong>AppServ 2.5.10</strong> :</p>
<ul>
<li>Apache 2.2.8</li>
<li>PHP 5.2.6</li>
<li>MySQL 5.0.51b</li>
<li>phpMyAdmin-2.10.3</li>
<li>MySQL Root Password Reset</li>
</ul>
<p>Una volta installato AppServ, aprite il vostro browser e digitate questo indirizzo per vedere se l&#8217;installazione ha avuto successo :</p>
<div class="codebox">
<pre>http://localhost/</pre>
</div>
<p>Se vi appare una pagina rosa con la scritta <strong>&#8220;The AppServ Open Project&#8221;</strong> allora è tutto ok.</p>
<p>Ora vi serve solo un editor con cui scrivere e modificare il vostro codice, e al riguardo vi segnalo l&#8217;ottimo e gratuito PSPad con cui ho realizzato questo sito, in concomitanza con Aptana.</p>
<p>Nella prossima pagina vedremo come configurare in modo ottimale PSPad, per programmare in PHP.</p>
<ul>
<li class="leaf first"><a href="http://blog.webeng.it/guida-php-configurare-pspad/">1. Guida Php &#8211; Configurare PSPad</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-applicazione-hello-world/">2. Guida Php &#8211; Hello World!</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-lessico/">3. Guida Php &#8211; Lessico</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-spazi-e-commenti/">4. Guida Php &#8211; Spazi e commenti</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-variabili/">5. Guida Php &#8211; Variabili</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-tipi-di-dato/">6. Guida Php &#8211; Tipi di dato</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-costanti/">7. Guida Php &#8211; Costanti</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-array/">8. Guida Php &#8211; Array</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-array-multidimensionali/">9. Guida Php &#8211; Array multidimensionali</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-stringhe/">10. Guida Php &#8211; Stringhe</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-operatori/">11. Guida Php &#8211; Operatori</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-strutture-di-controllo/">12. Guida Php &#8211; Strutture di controllo</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-funzioni/">13. Guida Php &#8211; Funzioni</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-librerie-e-file-esterni/">14. Guida Php &#8211; Librerie e file esterni</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-oggetti/">15. Guida Php &#8211; Oggetti</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-gli-oggetti-e-i-membri-statici/">16. Guida Php &#8211; Gli Oggetti e i Membri Statici</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-oggetti-e-costanti/">17. Guida Php &#8211; Oggetti e Costanti</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-gli-oggetti-e-lereditarieta/">18. Guida Php &#8211; Gli oggetti e l&#8217;Ereditarietà</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-gli-oggetti-e-il-polimorfismo/">19. Guida Php &#8211; Gli oggetti e il Polimorfismo</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-clonare-gli-oggetti/">20. Guida Php &#8211; Clonare gli Oggetti</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-classi-astratte/">21. Guida Php &#8211; Classi Astratte</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-interfacce/">22. Guida Php &#8211; Interfacce</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-esempio-pratico-per-luso-di-interfacce/">23. Guida Php &#8211; Esempio pratico per l&#8217;utilizzo di interfacce</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-classi-e-metodi-final/">24. Guida Php &#8211; Classi e metodi Final</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-gestione-degli-errori/">25. Guida Php &#8211; Gestione degli Errori</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-la-classe-exception/">26. Guida Php &#8211; La Classe Exception</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-gestione-avanzata-delle-eccezioni/">27. Guida Php &#8211; Gestione avanzata delle eccezioni</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-serializzare-gli-oggetti/">28. Guida Php &#8211; Serializzare gli oggetti</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-metodi-magici/">29. Guida Php &#8211; Metodi Magici</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-il-metodo-magico-__set/">30. Guida Php &#8211; Il metodo magico __set()</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-il-metodo-magico-__get/">31. Guida Php &#8211; Il metodo magico __get()</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-overload-di-__isset-e-__unset/">32. Guida Php &#8211; Overload di __isset() e __unset()</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-il-metodo-magico-__call/">33. Guida Php &#8211; Il metodo magico __call()</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-la-funzione-magica-__autoload/">34. Guida Php &#8211; La funzione magica __autoload()</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-i-metodi-magici-__sleep-__wakeup-e-__set_state/">35. Guida Php &#8211; I metodi magici __sleep() __wakeup e __set_state()</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-overload-delloperatore-di-accesso-degli-array/">36. Guida Php &#8211; Overload dell&#8217;operatore di accesso degli array</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-overload-dellinterfaccia-di-iterazione/">37. Guida Php &#8211; Overload dell&#8217;interfaccia di operazione</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-osservazioni-finali-sugli-oggetti/">38. Guida Php &#8211; Osservazioni finali sugli oggetti</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-codice-php-nelle-pagine-html/">39. Guida Php &#8211; Codice PHP nelle pagine HTML</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-inviare-dati-coi-metodi-get-e-post/">40. Guida Php &#8211; Inviare dati coi metodi GET e POST</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-i-cookie/">41. Guida Php &#8211; I Cookie</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-i-cookie/">42. Guida Php &#8211; Una classe per i cookie</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-le-sessioni/">43. Guida Php &#8211; Le Sessioni</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-gestione-avanzata-delle-sessioni/">44. Guida Php &#8211; Gestione avanzata delle sessioni</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-upload-di-file/">45. Guida Php &#8211; Upload di file</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-classi-per-lupload-di-file/">46. Guida Php &#8211; Classi per l&#8217;upload di file</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-inviare-email/">47. Guida Php &#8211; Inviare email</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-inviare-email-con-allegati/">48. Guida Php &#8211; Inviare email con allegati</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-classi-per-inviare-email/">49. Guida Php &#8211; Classi per inviare email</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-i-database/">50. Guida Php &#8211; I Database</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-sicurezza/">51. Guida Php &#8211; Sicurezza</a></li>
<li class="leaf"><a href="http://blog.webeng.it/guida-php-conclusioni/">52. Guida Php &#8211; Conclusioni</a></li>
</ul>
<p class="leaf">Articolo e intera guida tratta da : <a href="http://www.realizzazione-sito.info/guide/php_5">http://www.realizzazione-sito.info/guide/php_5</a></p>
<p class="leaf">Ringraziamo l&#8217;autore della guida (Francesco Casula) ricordando che la stessa è stata rilasciata sotto licenza <span><a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/2.5/it/">Creative Commons Attribuzione-Non commerciale-Non opere derivate 2.5 Italia License</a>.</span></p>
<p class="leaf">Alla prossima.</p>
<p class="leaf">
]]></content:encoded>
			<wfw:commentRss>http://blog.webeng.it/2008/12/09/guida-introduttiva-a-php-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stabilire la durata delle sessioni cookie in PHP</title>
		<link>http://blog.webeng.it/2008/11/28/stabilire-la-durata-delle-sessioni-cookie-in-php-session-gc_maxlifetime-e-lifetime/</link>
		<comments>http://blog.webeng.it/2008/11/28/stabilire-la-durata-delle-sessioni-cookie-in-php-session-gc_maxlifetime-e-lifetime/#comments</comments>
		<pubDate>Fri, 28 Nov 2008 14:35:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Articoli Generici]]></category>
		<category><![CDATA[Sviluppo Web]]></category>
		<category><![CDATA[cookie]]></category>
		<category><![CDATA[durata sessioni]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.webeng.it/?p=109</guid>
		<description><![CDATA[Quando stiamo creando un sito in PHP,  che richiede autenticazione o in ogni caso una gestione delle sessioni, è sempre importante stabilire la durata di una sessione, perché la cosa più fastidiosa è trovarsi buttati fuori da un sistema, solo perché ci si è allontatati dalla postazione oppure si è ricevuta una telefontata.


Dannazione!
In questo articolo spiegherò come [...]]]></description>
			<content:encoded><![CDATA[<p>Quando stiamo creando un sito in PHP,  che richiede autenticazione o in ogni caso una gestione delle sessioni, è sempre importante stabilire la durata di una sessione, perché la cosa più fastidiosa è trovarsi buttati fuori da un sistema, solo perché ci si è allontatati dalla postazione oppure si è ricevuta una telefontata.</p>
<p><span id="more-109"></span></p>
<div class="wp-caption aligncenter" style="width: 383px;"><img title="Sessione scaduta" src="http://i237.photobucket.com/albums/ff314/timendum/sessione-scaduta.png" alt="Sessione scaduta... dannazione!" width="373" height="125" /></div>
<p class="wp-caption-text">Dannazione!</p>
<p>In questo articolo spiegherò come impostare i giusti settaggi di PHP, preferibilmente nel file <em>/etc/php5/cgi/php.ini</em> oppure tramite il comando <a title="Guida ufficiale" href="http://it.php.net/ini_set"><span style="color: #a00000;">ini_set</span></a>.</p>
<p>Il primo settaggio da impostare è <strong><span class="norm"><span class="norm">session.cookie_lifetime</span></span></strong>, che specifica QUANTO un cookie deve durare sulla macchina del visitatore, misurato in secondi; di default è impostato a 0, che non significa per sempre, ma piuttosto fino a quando il browser non viene chiuso. Dei valori di riferimento sono: 3600 = 1 ora; 28800 = 8 ore; 86400 = un giorno.</p>
<p>Per impostare questo parametro, o si edita il file <em>etc/php5/cgi/php.ini</em> oppure si utilizza la funzione, se abilitata, <em>ini_set(’session.cookie_lifetime’, 3600)</em>.</p>
<p>Fatto questo, passiamo a <strong>session.gc_maxlifetime</strong>, che stabilisce quanto una sessione dura sul server, cioè dopo quanti secondi il nostro fido PHP butta via una sessione che non ha aggiornato dati. Il paramentro è più subdolo di quanto possa sembrare, perché una sessione creata alle 8:00, viene considerata vecchia di 10 minuti già alle 8:10 anche se l’utente continua a visitare il sito, se nessun dato dell’array <em>$SESSION</em> viene aggiornato, quindi sta a te stabilire da quanto considerare una sessione scaduta, se dalla sua creazione/ultimo aggiornamento <span style="text-decoration: underline;">reale</span>, oppure se dall’ultima visita, in questo caso, ad esempio incremetare una variabile dummy ad ogni pagina, con il comando <em>$SESSION['keepailve']++</em> dopo esserti ricordato di inizializzare <em>keepalive</em> alla creazione della sessione.</p>
<p>In ogni caso, questo parametro non andrà MAI oltre quello precedente, quindi se alzi <em>maxlifetime</em>, devi ricordarti di fare altrettanto con <em>cookie_lifetime</em>.</p>
<p>Ora veniamo al bello, da solo il parametro <em>maxlifetime</em> non basta, perché PHP non passa ogni istante, per fortuna del tuo server, a controllare quali sessioni buttare, altrimenti il carico diventa eccessivo, piuttosto ha una data probabilità di farlo ad ogni pagina generata. I parametri sono <strong>session.gc_probability</strong> e <strong>session.gc_divisor</strong>. Immaginiamo di averli impostati a:</p>
<p>session.gc_probability = 7 session.gc_divisor = 80</p>
<p>Bene, allora per ogni pagina visitata, PHP controllerà (o meglio lo farà il Garbage Collector, ma questo è un dettaglio) tutte le sessioni valide, con una probabilità di 7 su 80 = 7/80 = 0.0875</p>
<p>Io ti consiglio di lasciare le impostazioni di base, cioè rispettivamente 1 e 100, ma dipende solamente dal server e dalle pageviews del tuo sito.</p>
<p>L&#8217;articolo è tratto da: <a href="http://www.timendum.net/blog/201/prolungare-o-accorciare-le-durate-delle-sessioni-cookie-con-php-session-gc_maxlifetime-e-lifetime/">http://www.timendum.net/blog/201/prolungare-o-accorciare-le-durate-delle-sessioni-cookie-con-php-session-gc_maxlifetime-e-lifetime/</a></p>
<p>Articolo tratto da : <a href="http://www.timendum.net/blog/201/prolungare-o-accorciare-le-durate-delle-sessioni-cookie-con-php-session-gc_maxlifetime-e-lifetime/" target="_blank">http://www.timendum.net/blog/201/prolungare-o-accorciare-le-durate-delle-sessioni-cookie-con-php-session-gc_maxlifetime-e-lifetime/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webeng.it/2008/11/28/stabilire-la-durata-delle-sessioni-cookie-in-php-session-gc_maxlifetime-e-lifetime/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Microsoft annuncia Internet Explorer 8</title>
		<link>http://blog.webeng.it/2008/03/10/microsoft-annuncia-internet-explorer-8/</link>
		<comments>http://blog.webeng.it/2008/03/10/microsoft-annuncia-internet-explorer-8/#comments</comments>
		<pubDate>Mon, 10 Mar 2008 15:42:36 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Articoli Generici]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Sviluppo Web]]></category>
		<category><![CDATA[internet explorer]]></category>
		<category><![CDATA[microsoft]]></category>

		<guid isPermaLink="false">http://blog.webeng.it/2008/03/10/microsoft-annuncia-internet-explorer-8/</guid>
		<description><![CDATA[Microsoft annuncia in questo articolo l&#8217;intenzione di avviare con la nuova versione del suo popolare browser Internet Explorer, un processo di adeguamento agli standard più significativi del world wide web. Nella nuova release di Explorer, la 8, sarà l&#8217;utente a scegliere il grado di flessibilità del proprio browser scegliendo tramite un apposità opzione i tre diversi livelli di compatibilità.
La [...]]]></description>
			<content:encoded><![CDATA[<p>Microsoft annuncia in questo <a title="Microsoft rispetta gli standard" href="http://www.microsoft.com/presspass/press/2008/mar08/03-03WebStandards.mspx" target="_blank">articolo</a> l&#8217;intenzione di avviare con la nuova versione del suo popolare browser Internet Explorer, un processo di adeguamento agli standard più significativi del world wide web. Nella nuova release di Explorer, la 8, sarà l&#8217;utente a scegliere il grado di flessibilità del proprio browser scegliendo tramite un apposità opzione i tre diversi livelli di compatibilità.</p>
<p><span id="more-32"></span><span class="articoli_corpo"><span id="intelliTXT">La notizia più che positiva è che MICROSOFT abbia finalmente deciso di visualizzare le pagine web secondo gli standard previsti dal <em>World Wide Web Consortium</em> (W3C), agevolando cosi il compito degli sviluppatori di applicazioni e siti web e consentendo agli utenti di avere una visualizzazione corretta delle pagine.</span></span></p>
<p><span class="articoli_corpo"><span id="intelliTXT">Il cambiamento di rotta, richiesto a gran voce da web designer e utenti, rappresenta un notevole passo in avanti rispetto alle versioni precedenti di explorer specialmente per quanto riguarda la versione 6 giudicata da molti come il peggior browser mai visto in circolazione. </span></span></p>
<p><span class="articoli_corpo"><span id="intelliTXT">IE 8 avrà tre modalità, dalla più restrittiva che interpreterà le pagine secondo i dettami del W3C a una seconda modalità meno rigida e che mostrerà le pagine esattamente come fa attualmente IE 7 terminando con l&#8217;ultima che permetterà di gestire correttamente anche le pagine ottimizzate per le versioni precedenti di IE.</span></span></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webeng.it/2008/03/10/microsoft-annuncia-internet-explorer-8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Configurare PHP, Apache, MySql, PhpMyAdmin su Windows</title>
		<link>http://blog.webeng.it/2007/10/30/configurare-php-apache-mysql-phpmyadmin-su-windows/</link>
		<comments>http://blog.webeng.it/2007/10/30/configurare-php-apache-mysql-phpmyadmin-su-windows/#comments</comments>
		<pubDate>Tue, 30 Oct 2007 16:06:58 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySql]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[apache]]></category>

		<guid isPermaLink="false">http://blog.webeng.it/2007/10/30/configurare-php-apache-mysql-phpmyadmin-in-ambiente-windows/</guid>
		<description><![CDATA[Ecco una breve guida per la configurazione di un server web basato su Apache PHP e Mysql in ambiente Windows; al termine del tutorial sarete in grado di montare un sito web in locale dove potrete sviluppare e testare il codice PHP delle vostre applicazioni web.
Per prima cosa dotiamoci del software di cui abbiamo bisogno&#8230;

Per installare l&#8217;Apache HTTP Server andare su http://httpd.apache.org/download.cgi, [...]]]></description>
			<content:encoded><![CDATA[<p>Ecco una breve guida per la configurazione di un server web basato su Apache PHP e Mysql in ambiente Windows; al termine del tutorial sarete in grado di montare un sito web in locale dove potrete sviluppare e testare il codice PHP delle vostre applicazioni web.</p>
<p><span id="more-24"></span>Per prima cosa dotiamoci del software di cui abbiamo bisogno&#8230;</p>
<ol>
<li>Per installare l&#8217;Apache HTTP Server andare su <a href="http://httpd.apache.org/download.cgi">http://httpd.apache.org/download.cgi</a>, una volta entrati clicchiamo su &#8220;other files&#8221; ed entriamo nella directory binaries/win32, scarichiamo quindi l&#8217;installer (msi) dell&#8217;ultima versione disponibile (2.2.6) .</li>
<li>Possiamo ora scaricare l&#8217;interprete del PHP dal sito <a href="http://www.php.net/downloads.php">http://www.php.net/downloads.php</a> , avendo cura di scaricare il pacchetto zip dei binari per windows.</li>
<li> Scaricare il database mysql per windows all&#8217;indirizzo <a href="http://dev.mysql.com/downloads/">http://dev.mysql.com/downloads/</a> .</li>
<li> Scaricare il software phpMyAdmin dal sito <a href="http://www.phpmyadmin.net/">http://www.phpmyadmin.net/</a> .</li>
</ol>
<p>Per prima cosa avviare l&#8217;installer di apache, durante l&#8217;esecuzione dell&#8217;installer dopo avervi sottoposto la licenza, il programma vi chiederà se volete configurare il servizio sulla porta 80 (default) in modalità di avvio automatico oppure sulla porta 8080 in modalità di avvio manuale.</p>
<p><img src="http://blog.webeng.it/wp-content/uploads/2007/10/apache_2055-win32-x86-no_ssl-install.jpg" alt="apache install" /></p>
<p>Se sceglierete la prima opzione assicuratevi di avere la porta 80 a disposizione o a meno di modifiche nella configurazione dell httpd.conf, il vostro server web non salirà (idem per la 8080). Nel caso invece si seguisse la strada di installarlo settando la seconda opzione bisognerà aver cura di avviare il servizio manualmente.</p>
<p>Effettuare la scelta e proseguire con l&#8217;installazione, dopotutto sarete comunque in grado di configurare la porta di ascolto successivamente editando il file di configurazione httpd.conf disponibile nella directory conf di Apache.</p>
<p>A questo punto estrarre il contenuto dei binari PHP e rinominare la cartella in php. Metterla per comodità sulla root di del disco rigido, in C:\php .</p>
<p>Passiamo ora ad installare il server di database MySql, estrarre l&#8217;archivio scaricato e avviare l&#8217;installer. Al termine della procedura di installazione eseguire la configurazione immediata, proseguire scegliendo una configurazione standard e selezionando le opzioni <strong>Install As Windows Service</strong> e <strong>Include Bin Directory in Windows Path</strong>.</p>
<p><img src="http://blog.webeng.it/wp-content/uploads/2007/10/mysql-configuration-wizard.png" alt="mysql configuration" /></p>
<p>A questo punto prima di concludere l&#8217;installazione scegliere la password di root (amministratore) e terminare effettuando la scrittura del file di configurazione mysql.ini .</p>
<p>Occupiamoci ora di configurare il php, a tal fine andare nella cartella C:\PHP e creare il file di configurazione php rinominando il file php.ini-recommended (effettuare prima una copia di backup) in php.ini, possiamo ora gestire la configurazione del php editando il file php.ini .</p>
<p>Per installare PHP come modulo su Apache, e consentire al server di interpretare il codice php, aprire il file httpd.conf presente nel path di installazione di Apache sotto la directory conf e scorrere il file con un editor fino alle direttive LoadModule&#8230; Aggiungere in coda le seguenti direttive&#8230;</p>
<p>LoadModule php5_module &#8220;c:/php/php5apache2_2.dll&#8221;<br />
AddType application/x-httpd-php .php</p>
<p># configure the path to php.ini<br />
PHPIniDir &#8220;C:/php&#8221;</p>
<p>Per chiarezza nella prima direttiva si aggiunge ad apache il modulo di php, nella seconda si aggiunge il tipo di applicazione e nella terza si comunica ad apache dove trovare il file di configurazione di php.</p>
<p>Apache e PHP ora dovrebbero funzionare insieme, per effettuare una prova :</p>
<ol>
<li>creare un file chiamato phpinfo.php contenente il codice sottostante e spostarlo nella directory htdocs (document root) sotto apache
<pre class="brush: php">
&lt;?php
phpinfo();
?&gt;
</pre>
</li>
<li>avviare/riavviare apache, aprire un browser e digitare <a href="http://localhost/phpinfo.php">http://localhost/phpinfo.php</a> (nel caso avessimo configurato apache su un altra porta/ip usare <a href="http://host:porta/phpinfo.php">http://host:porta/phpinfo.php</a>)</li>
</ol>
<p>Se tutto è andato bene dovremmo visualizzare un risultato simile.</p>
<p><img src="http://blog.webeng.it/wp-content/uploads/2007/10/phpinfo.jpg" alt="phpinfo" /></p>
<p>Provvediamo ora alla configurazione delle estensioni di mysql per php; apriamo il php.ini e occupiamoci di togliere i puntievirgola iniziali dalle seguenti estensioni:</p>
<p>extension=php_mysql.dll<br />
extension=php_mysqli.dll</p>
<p>Troviamo all&#8217;interno del file la direttiva che configura il path dove php cercherà le estensioni&#8230;</p>
<p>extension_dir = &#8220;./&#8221;</p>
<p>Questo parametro indica il percorso relativo o assoluto a partire dal quale php cercherà le estensioni. Nel caso si avessero delle esigenze specifiche modificarlo opportunamente tenendo conto che se si specifica un percorso relativo php cercherà le estensioni a partire dalla stessa directory del php.ini .</p>
<p>Copiamo il file C:\php\libmysql.dll in C:\php\ext e modifichiamo l&#8217;extension_dir in questo modo:</p>
<p>extension_dir = &#8220;C:\php\ext&#8221;</p>
<p>Infine copiare il file C:\php\libmysql.dll dentro C:\windows\system32 , salviamo il php.ini e riavviamo il server.</p>
<p>A questo punto possiamo testare la connessione con il seguente script:</p>
<pre class="brush: php">&lt;?php
&lt;span style=&quot;color: #008080;&quot;&gt;// Connessione a MySQL
&lt;/span&gt;$link = mysql_connect(&#039;localhost&#039;, &#039;root&#039;, &#039;password_root_mysql&#039;) or die(&#039;Connessione fallita: &#039; . mysql_error());
echo &#039;Connesso.&#039;;
mysql_close($link);
?&gt;</pre>
<p>Salviamo il codice precedente in un file chiamato test.php e mettiamolo nella directory htdocs.</p>
<p>Aprire un browser e digitare <a href="http://localhost/phpinfo.php">http://localhost/test.php</a> (nel caso avessimo configurato apache su un altra porta/ip usare <a href="http://host:porta/phpinfo.php">http://host:porta/test.php</a>) e verificare che la connessione sia riuscita.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webeng.it/2007/10/30/configurare-php-apache-mysql-phpmyadmin-su-windows/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Come proteggere un form html dall&#8217;invio di SPAM</title>
		<link>http://blog.webeng.it/2007/10/13/impedire-linvio-di-spam-da-un-form-html/</link>
		<comments>http://blog.webeng.it/2007/10/13/impedire-linvio-di-spam-da-un-form-html/#comments</comments>
		<pubDate>Sat, 13 Oct 2007 13:29:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Script]]></category>
		<category><![CDATA[Sicurezza]]></category>
		<category><![CDATA[Sviluppo Web]]></category>

		<guid isPermaLink="false">http://blog.webeng.it/2007/10/13/impedire-linvio-di-spam-da-un-form-html/</guid>
		<description><![CDATA[In questo articolo proveremo ad illustrarvi come proteggere un form HTML dall&#8217;invio di SPAM mediante la tecnica del CAPTCHA. I form html non gestiti in modo ottimale possono essere causa di problemi sia nel caso in cui il modulo invii delle informazioni tramite email che nel caso inserisca le informazioni in un database.
Il rischio principale [...]]]></description>
			<content:encoded><![CDATA[<p>In questo articolo proveremo ad illustrarvi come proteggere un form HTML dall&#8217;invio di SPAM mediante la tecnica del CAPTCHA. I form html non gestiti in modo ottimale possono essere causa di problemi sia nel caso in cui il modulo invii delle informazioni tramite email che nel caso inserisca le informazioni in un database.</p>
<p><span id="more-5"></span>Il rischio principale è costituito dagli SPAMBOT ovvero dei software in grado di effettuare richieste http allo scopo di bucare i form non protetti. Le conseguenze di un attacco di questo tipo possono essere il sovraccarico del server web, malfunzionamenti del server di posta nonchè il rapido accumularsi di informazioni inutili sul Database.Il potenziale pericolo è rappresentato dal fatto che analizzando i tag di una pagina html, si possono analizzare facilmente le variabili usate per il passaggio delle informazioni, il metodo utilizzato (POST/GET) e la pagina che elabora la richiesta di invio email.</p>
<p>Quindi un qualsiasi individuo che vuole crearvi una grana, può, mediante un banale programmino che invia richieste HTTP effettuare la medesima richiesta infinite volte e intasarvi la posta o riempirvi il database. Per questo problema nasce l&#8217;esigenza di validare lato server le richieste effettuate tramite la pagina che si occupa nello specifico di elaborare la richiesta.</p>
<p>La tecnica del Captcha Code &#8220;completely automated public Turing test to tell computers and humans apart&#8221; è uno dei metodi più utilizzati per verificare se chi effettua la richiesta è un umano oppure un BOT.</p>
<p>A questo punto mostriamo un esempio di come implementare tale tecnica all&#8217;interno del proprio sito web:</p>
<p>Iniziamo con la creazione di una tabella sul nostro DB MySql che contenga le informazioni necessarie per implementare la tecnica del Captcha. Connettiamoci al nostro DB tramite PhpMyAdmin o tramite linea di comando e creiamo la tabella captcha con il seguente script:</p>
<pre class="sql">CREATE TABLE `captcha` (
`captcha_id` varchar(255) character set latin1 collate latin1_general_ci NOT NULL,
`code` varchar(255) character set latin1 collate latin1_general_ci NOT NULL,
`timestamp` varchar(255) character set latin1 collate latin1_general_ci NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1;</pre>
<p>Occupiamoci ora della pagina dove verrà visualizzato il FORM, preleviamo il codice e salviamolo in un file di testo index.php (per comodità si consiglia di posizionare tutti i file creati all&#8217;interno della stessa directory nella root del web server) :</p>
<pre class="php">&lt;?php
echo "&lt;html&gt;";
echo "&lt;head&gt;";

// genero un identificativo criptato md5 da associare al codice di sicurezza
$captcha_id = md5(microtime().mt_rand().'super1segreto2segretissimo3');

// creo un codice di controllo per la verifica dell'identificativo
$sale = "frase super segreta da cambiare a discrezione.";

// cripto in md5 i due codici generati
$chk = md5($sale.$captcha_id);

echo "&lt;/head&gt;";
echo "&lt;body&gt;";

//Creo il form

echo "&lt;form method=\"post\" action=\"email.php\"&gt;";
echo "Cognome : &lt;input type=\"text\" name=\"surname\"/&gt;";
echo "&lt;br/&gt;";
echo "Nome : &lt;input type=\"text\" name=\"name\"/&gt;";
echo "&lt;br/&gt;";
echo "E-mail : &lt;input type=\"text\" name=\"mail\"/&gt;";
echo "&lt;br/&gt;";
echo "&lt;img src=\"captcha.php?id=".$captcha_id."&amp;chk=".$chk."\" width=\"110\" height=\"70\"/&gt;";
echo "&lt;input type=\"text\" name=\"captcha_code\"/&gt;";
echo "&lt;br/&gt;";
echo "&lt;input name=\"captcha_id\" type=\"hidden\" id=\"captcha_id\" value=\"".$captcha_id."\"/&gt;";
echo "&lt;br/&gt;";
echo "&lt;input type=\"submit\" name=\"submit\" value=\"Submit\"/&gt;";
echo "&lt;br/&gt;";
echo "&lt;/form&gt;";

echo "&lt;/body&gt;";
?&gt;</pre>
<p>Notare bene che nello script precedente:</p>
<p>l&#8217;immagine Captcha è stata generata dalla richiesta presente nell&#8217;attributo src dell&#8217;immagine<br />
il campo captcha_code conterrà il codice di sicurezza che l&#8217;utente dovrà inserire per validare l&#8217;elaborazione<br />
il campo captcha_id contiene il captcha_id generato precedentemente nella head<br />
Ecco il listato della pagina che genera l&#8217;immagine CAPTCHA, salviamo il codice in un file di testo avendo l&#8217;accortezza di salvarlo come captcha.php :</p>
<pre class="php">&lt;?php
// controllo se è stato fornito l identificativo del codice captcha
if(!isset($_GET['id'])) exit();

// controllo la validità dell identificativo
$captcha_id = $_GET['id'];
if(!preg_match("/^[a-f0-9]{32}$/",$captcha_id)) exit();

// ricreo il codice di controllo e lo confronto con quello passato via GET
$sale = "frase super segreta da cambiare a discrezione.";
$chk = md5($sale . $captcha_id);
if($chk != $_GET['chk']) exit();

// creo l immagine
// ---------------------------------------------------------------

// le dimensioni dell immagine
$size_x = 110;
$size_y = 70;

$img = imagecreatetruecolor($size_x,$size_y);

// alloco un colore per lo sfondo
$backgroung = imagecolorallocate($img,255, 255, 255);

// alloco 3 colori per le 3 lettere da decifrare
// utilizzo il canale alpha per impostare la trasparenza
$color[] = imagecolorallocatealpha($img,110,110,110,60);
$color[] = imagecolorallocatealpha($img,3,187,63,60);
$color[] = imagecolorallocatealpha($img,255,0,0,70);

// mischio l ordine dei colori
shuffle($color);

// coloro lo sfondo creando un rettangolo
imagefilledrectangle($img,0,0,$size_x-1,$size_y-1,$backgroung);

// i caratteri da utilizzare per il codice di sicurezza
$caratteri = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";

// inizializzo la variabile che conterrà il codice
$codice = '';

// per ciascuno dei 3 caratteri
for ($i=0 ; $i &lt; 3 ; $i++){
// estraggo un carattere a caso
$codice .= $caratteri{rand(0,34)};
// disegno il carattere
imagettftext(
$img,
50,
-5+rand(0,10), // rotazione casuale
($i+0.3)*24,
60,
$color[$i],
'./VeraMono.ttf',
$codice{$i});
}

// inserisco identificativo e codice nel DB
// ---------------------------------------------------------------
mysql_connect('IP_MIO_SERVER_MYSQL','USER_MYSQL','PASS_MYSQL');
mysql_select_db('NOME_DB_MYSQL');

mysql_query("REPLACE INTO captcha (captcha_id,code,`timestamp`)
values ('$captcha_id','$codice',UNIX_TIMESTAMP())");

// con prob. impostata da $probabilità cancello i record più vecchi
$probabilità = 5; // 5%
if(mt_rand(1,100) &lt;= $probabilità){
$durata_captcha = 60*60;
mysql_query("DELETE FROM captcha WHERE `timestamp`&lt;(UNIX_TIMESTAMP()-$durata_captcha)");
}

// invio l immagine al browser
// ---------------------------------------------------------------
header("Content-type: image/png");
imagepng($img);
?&gt;</pre>
<p>Da notare che nello script precedente si utilizza un font per generare l&#8217;immagine (VeraMono.ttf)  il quale può essere modificato a proprio piacimento con un qualsiasi font installato nel proprio pc o scaricato da internet. Per scaricare il font utilizzato nell&#8217;esempio cliccare qui. Nell&#8217;esempio il font in questione è posizionato all&#8217;interno della stessa cartella dove sono stati posizionati gli script.</p>
<p>Passiamo ora ad esaminare la pagina che invierà l&#8217; e-mail e che si occuperà anche di verificare la validità dell&#8217;elaborazione, copiamo il codice sottostante e incolliamolo su un file di testo avendo l&#8217;accortezza di salvarlo come email.php.</p>
<pre class="php">&lt;?php
//Inclusione file esterni
 require_once('send_mail.php');

// Recupero dei dati POST
$surname = $_POST['surname'];
$name = $_POST['name'];
$mail = $_POST['mail'];

// dopo quanto tempo i dati nella tabella del DB scadono
$durata_captcha = 60*60;

// ci sono tutti i dati?
if(!isset($_POST['captcha_code']) OR !isset($_POST['captcha_id'])) exit;
$captcha_code = $_POST['captcha_code'];
$captcha_id = $_POST['captcha_id'];

// controlla la validità del $captcha_id
if(!preg_match("/^[a-f0-9]{32}$/",$captcha_id)){
// se il $captcha_id non è valido termino la procedura
echo '$captcha_id non valido';
}else{
// controlla la validità del $captcha_code
if (!preg_match("/^[a-zA-Z0-9]{3}$/", $captcha_code)){
// se il $captcha_code non è valido non faccio la ricerca nel DB
echo '$captcha_code non valido';
}else{
// $captcha_id e $captcha_code sono ben formattati, posso fare la verifica
// rendo tutte le lettere del $captcha_code maiuscole e
// sostituisco gli zeri con le O
$captcha_code = strtoupper($captcha_code);
$captcha_code = str_replace('0','O',$captcha_code);

mysql_connect('IP_MIO_SERVER_MYSQL','USER_MYSQL','PASS_MYSQL') or die(mysql_error());
mysql_select_db('NOME_DB_MYSQL') or die(mysql_error());

// nella verifica non considero dati più vecchi di $durata_captcha secondi
$res = mysql_query("SELECT code FROM captcha WHERE captcha_id = '$captcha_id' AND code = '$captcha_code' AND `timestamp` &gt; (UNIX_TIMESTAMP() - $durata_captcha)") or die (mysql_error());
if(mysql_num_rows($res) != 1){
// verifica fallita
echo '$captcha_code errato';
}else{
// cancello i vecchi codici e quello corrente
mysql_query("DELETE FROM captcha WHERE captcha_id = '$captcha_id' OR `timestamp` &lt; (UNIX_TIMESTAMP() - $durata_captcha)");

//Scrittura parametri email
$from_name  = $name." ".$surname;
$from_email = $mail;
$to_name    = "NOME_DEL_DESTINATARIO";
$to_email   = "MAIL_DEL_DESTINATARIO";
$subject    = "Invio email sicura dal tuo sito";
$text_message = "This is HTML email and your email client software ain't support HTML email.";
$html_message = "&lt;!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"&gt;\n";
$html_message.= "&lt;html&gt;&lt;head&gt;&lt;title&gt;&lt;/title&gt;\n";
$html_message.= "&lt;meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\"&gt;\n";
$html_message.= "&lt;/head&gt;\n";
$html_message.= "&lt;body&gt;";
$html_message.= "Ciao, questa è un email sicura inviata dal tuo sito";
$html_message.= "&lt;/body&gt;&lt;/html&gt;";

//Creo l'allegato
$attachment = array ("PATH_ALLEGATO_SUL_SERVER");

//Invio l'email con la funzione sendmail
sendmail ($from_name, $from_email, $to_name, $to_email, $subject, $text_message, $html_message, $attachment);

echo "&lt;script language=\"Javascript\"&gt;";
echo "&lt;!–-";
echo "alert (\"e-mail inviata con successo\");";
echo "history.go(-1);";
echo "–-&gt;";
echo "&lt;/script&gt;";
}
}
}
?&gt;</pre>
<p>I controlli effettuati all&#8217;inizio del codice illustrato permettono al server web di distinguere se si tratta di una richiesta valida o di una richiesta effettuata da un BOT.</p>
<p>Se i controlli saranno superati si passerà ad invocare la funzione sendmail che si occuperà dell&#8217;invio di una mail in formato HTML con allegati. Alternativamente a questa funzione si pùo invocare la classica funzione mail disponibile nel linguaggio PHP.</p>
<p>Ecco ora il listato della funzione sendmail invocata nel precedente script, che si occupa di inviare una mail in formato HTML. Copiare il codice e salvarlo in un file denominato send_mail.php.</p>
<pre class="php">&lt;?php
function sendmail ($from_name, $from_email, $to_name, $to_email, $subject, $text_message="", $html_message, $attachment=""){
$from = "$from_name &lt;$from_email&gt;";
$to   = "$to_name &lt;$to_email&gt;";
$main_boundary = "----=_NextPart_".md5(rand());
$text_boundary = "----=_NextPart_".md5(rand());
$html_boundary = "----=_NextPart_".md5(rand());
$headers  = "From: $from\n";
$headers .= "Reply-To: $from\n";
$headers .= "X-Mailer: Hermawan Haryanto (<a href="http://hermawan.com)\n">http://hermawan.com)\n</a>";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-Type: multipart/mixed;\n\tboundary=\"$main_boundary\"\n";
$message .= "\n--$main_boundary\n";
$message .= "Content-Type: multipart/alternative;\n\tboundary=\"$text_boundary\"\n";
$message .= "\n--$text_boundary\n";
$message .= "Content-Type: text/plain; charset=\"ISO-8859-1\"\n";
$message .= "Content-Transfer-Encoding: 7bit\n\n";
$message .= ($text_message!="")?"$text_message":"Text portion of HTML Email";
$message .= "\n--$text_boundary\n";
$message .= "Content-Type: multipart/related;\n\tboundary=\"$html_boundary\"\n";
$message .= "\n--$html_boundary\n";
$message .= "Content-Type: text/html; charset=\"ISO-8859-1\"\n";
$message .= "Content-Transfer-Encoding: quoted-printable\n\n";
$message .= str_replace ("=", "=3D", $html_message)."\n";
if (isset ($attachment) &amp;&amp; $attachment != "" &amp;&amp; count ($attachment) &gt;= 1){
for ($i=0; $i&lt;count ($attachment); $i++){
$attfile = $attachment[$i];
$file_name = basename ($attfile);
$fp = fopen ($attfile, "r");
$fcontent = "";
while (!feof ($fp)){
$fcontent .= fgets ($fp, 1024);
}
$fcontent = chunk_split (base64_encode($fcontent));
@fclose ($fp);
$message .= "\n--$html_boundary\n";
$message .= "Content-Type: application/octetstream\n";
$message .= "Content-Transfer-Encoding: base64\n";
$message .= "Content-Disposition: inline; filename=\"$file_name\"\n";
$message .= "Content-ID: &lt;$file_name&gt;\n\n";
$message .= $fcontent;
}
}
$message .= "\n--$html_boundary--\n";
$message .= "\n--$text_boundary--\n";
$message .= "\n--$main_boundary--\n";
@mail ($to, $subject, $message, $headers);
}
?&gt;</pre>
<p>A questo punto possiamo testare lo script chiamando la pagina index.php dal nostro browser.</p>
<p>Alla prossima&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webeng.it/2007/10/13/impedire-linvio-di-spam-da-un-form-html/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
