<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Web Magazine. Blog sul mondo del web design.</title>
	
	<link>http://www.web-magazine.it</link>
	<description>Guide e rubriche per diventare web designer freelance e per gestire l'attività in proprio senza problemi.</description>
	<lastBuildDate>Tue, 21 Feb 2012 14:16:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/web-magazine" /><feedburner:info uri="web-magazine" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>E-mail marketing: Seconda parte</title>
		<link>http://feedproxy.google.com/~r/web-magazine/~3/BEaQqznHClo/</link>
		<comments>http://www.web-magazine.it/2012/02/e-mail-marketing-seconda-parte/#comments</comments>
		<pubDate>Mon, 20 Feb 2012 15:34:08 +0000</pubDate>
		<dc:creator>Dario</dc:creator>
				<category><![CDATA[SEO e Web Marketing]]></category>
		<category><![CDATA[dem]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[email marketing]]></category>
		<category><![CDATA[marketing]]></category>
		<category><![CDATA[Web marketing]]></category>

		<guid isPermaLink="false">http://www.web-magazine.it/?p=2356</guid>
		<description><![CDATA[﻿Come vi accennavo nello scorso articolo, sono poche le newsletter ben fatte  ed è per questo motivo  vorrei condividere con voi  alcune regole fondamentali   per rendere una newsletter degna di questo nome. 1  &#8211; La frequenza ovvero il numero degli invii. Una newsletter giornaliera è davvero impegnativa e spesso funziona solo per le grandi aziende [...]]]></description>
			<content:encoded><![CDATA[<p><img title="email marketing" src="http://www.web-magazine.it/wp-content/uploads/2012/02/More-Email-Marketing-Mistakes2.jpg" alt="email marketing - photo by elviskennedy flickr.com/photos/elviskennedy"  /><br />
﻿Come vi accennavo nello scorso articolo, sono poche le newsletter ben fatte  ed è per questo motivo  vorrei condividere con voi  alcune regole fondamentali   per rendere una newsletter degna di questo nome.</p>
<p><span id="more-2356"></span></p>
<h3>1  &#8211; La frequenza</h3>
<p>ovvero il numero degli invii.</p>
<p>Una newsletter giornaliera è davvero impegnativa e spesso funziona solo per le grandi aziende che hanno molte persone dedicate a questo lavoro, dal punto di vista del cliente, una newsletter quotidiana può essere pesante(chi di voi non è incappato almeno una volta,  nella newsletter di una famosa società che stampa biglietti da visita che inizia con la V) e non è improbabile che si smetta di seguirla. Leggevo da qualche parte che uno dei maggiori motivi per cui si smette di seguire un account di twitter è : il numero elevato di tweet .</p>
<p><strong>Potrebbe essere lo stesso per le e-mail non credete ?</strong></p>
<p>Ultimamente mi sono iscritto ad alcune newsletter, volevo  provare un po’ l’esperienza di  e-mail mandate da grandi aziende, (come sapete la mia preferita ad oggi, è la newsletter della casa giapponese creatrice di Mario Bros, ma anche la casa madre di Topolino non è da meno )  direi che la frequenza ottimale è una al massimo, due volte al mese. Ci sono aziende che sono assolutamente precise e creano newsletter per  i primi del mese (per esempio una compagnia aerea tedesca che inizia con la L) e sono molto efficaci.</p>
<h3>2 &#8211; Cancellazione</h3>
<p>importante mettete ben in evidenza il link <strong>unscribe</strong> e rendete l’esperienza di cancellazione semplice;  non c’è niente di peggio che quelle società che vi fanno cancellare e poi vi iscrivono ad altre newsletter ancora più estenuanti . E’ importante creare un processo di cancellazione  con solo un click.</p>
<h3>3 &#8211; Grafica</h3>
<p>come vi dicevo nello scorso articolo, le newsletter fatte con un blocco note non fanno molta strada, se non finire nello spam, senza essere nemmeno lette. Per cui grafica, grafica e  grafica e  se non siete grafici, esistono dei template davvero fatti bene ad un costo irrisorio. Mi piacciono molto le newsletter con un layout pulito con alcune informazioni in evidenza, e invece non sopporto quelle con mille messaggi che rendono il tutto confuso. Avete molte cose da comunicare? bene, dividetele in più newsletter.</p>
<h3>4 &#8211; Oggetto della mail</h3>
<p><strong> </strong>prima di tutto evitate punti esclamativi e troppe maiuscole nell’oggetto della mail .</p>
<p>Come vi accennavo la scorsa volta è fondamentale usare <strong>pannelli/software</strong> professionali per inviare le e-mail per cui è anche importante inserire i codici di tracciamento ( per capirci : analytics ) così potrete monitorare l’apertura delle e-mail . Se notate che i tassi di apertura sono molto bassi vi consiglio di controllare l’oggetto della mail. L’oggetto deve essere accattivante e deve stimolare la curiosità dell’utente.</p>
<h3>5 &#8211; usare opzione “confirmed opt-in”:</h3>
<p>importante usare questa opzione con la quale l’utente deve cliccare un link per confermare l’iscrizione alla vostra newsletter. Con questa opzione sarete abbastanza sicuri che l’utente è davvero deciso a seguirvi, per cui il tasso di cancellazione sarà molto basso. So che magari avrete paura che alcune persone facciano fatica con il meccanismo, ma vi servono davvero utenti che non sanno neanche aprire un link di conferma ? o che magari controllano la mail due volte l’anno ? <strong>NO non vi servono</strong>.</p>
<h3>6 &#8211; Offerte</h3>
<p>negli ultimi tempi le nostre e-mail sono piene zeppe di messaggi, per esempio newsletter di aziende di terze parti a cui non vi siete iscritti direttamente, ma che in una clausola piccolina all’atto della vostra iscrizione, hanno la possibilità di rigirare il vostro indirizzo e-mail ad altre aziende ( questo succede con molte applicazioni di Facebook per esempio ). Perché un’utente dovrebbe iscriversi alla vostra newsletter che per lui potrebbe essere l’ennesima ?</p>
<p>Cercate di offrire qualcosa in cambio, per esempio vedo molti siti che offrono e-book(anche solo parziali o e-book generici ), promozioni esclusive o contenuti esclusivi per gli iscritti.</p>
<h3>7 &#8211; Nome</h3>
<p>se vi mettete dalla parte dell’utente, non vi sembra molto più familiare essere chiamati per nome, piuttosto che gentile utente. Naturalmente all’atto della registrazione alla vostra newsletter mettete nome ed e-mail e molti pannelli/software per newsletter gestiranno in automatico il tutto .</p>
<h3>8 &#8211; Form</h3>
<p>non esagerate con le richieste all’atto dell’iscrizione alla vostra newsletter, bastano nome ed e-mail ,so benissimo che più dati ottenete e più è facile profilare gli utenti , ma come spesso faccio io, e cioè mi metto dalla parte dell’utente, trovare una form di iscrizione con 100 campi, mi fa scappare immediatamente.</p>
<h3>9 &#8211; Perseverate</h3>
<p>non tutte le vendite vengono effettuate dopo la prima newsletter ( anzi meno del 2% ) la stragrande maggioranza delle vendite (circa l’80 %) viene effettuata dal quinto al dodicesimo contatto .</p>
<p>Per cui non abbattetevi se dopo la prima e-mail, non avrete  ottenuto  grandi risultati in termini di vendita, ci vuole tempo per avere una buona lista di utenti affezionati .</p>
<h3>10 -Testate</h3>
<p><strong> </strong> ho seguito alcuni corsi, e leggo alcuni blog per aggiornarvi, non potete neanche immaginare quanto sia fondamentale il test A/B sulle newsletter, ho visto statistiche importanti con percentuali 93% di un layout e 7 % per il secondo layout solo per aver cambiato una immagine o il colore di un tasto. Ecco il test di una newsletter potrebbe decretare o meno il successo della stessa.</p>
<p>Ultimo importante consiglio aggiornatevi mi raccomando, le regole di internet e dell’interazione utente/sito cambiano velocemente</p>
<p>Per cui continuate ad aggiornarvi e iscrivetevi a quante più newsletter potete (io ho creato un account  mail apposito per l’iscrizione alle varie newsletter) , perché la cosa più importante è imparare e poi sperimentare (lo dico dal primo articolo). Mettetevi sempre nei panni dell’utente, testate  e di sicuro otterrete risultati .</p>
<p>Buon lavoro</p>
]]></content:encoded>
			<wfw:commentRss>http://www.web-magazine.it/2012/02/e-mail-marketing-seconda-parte/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.web-magazine.it/2012/02/e-mail-marketing-seconda-parte/</feedburner:origLink></item>
		<item>
		<title>Creare siti in PHP – (30) – Le espressioni regolari</title>
		<link>http://feedproxy.google.com/~r/web-magazine/~3/WfhZEpoChU0/</link>
		<comments>http://www.web-magazine.it/2012/01/creare-siti-in-php-%e2%80%93-30-%e2%80%93-le-espressioni-regolari/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 06:00:53 +0000</pubDate>
		<dc:creator>Federico</dc:creator>
				<category><![CDATA[scripting]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[regular expressions]]></category>

		<guid isPermaLink="false">http://www.web-magazine.it/?p=2300</guid>
		<description><![CDATA[Ultima puntata della guida base al linguaggio PHP: parleremo di espressioni regolari. Impareremo a conoscere i metacaratteri, i quantificatori e le classi di caratteri e a usarli per creare pattern utili all'interno dei nostri script tramite le funzioni preg_match e preg_replace.]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.web-magazine.it/wp-content/uploads/2011/11/php30.jpg" alt="Le espressioni regolari" /></p>
<p><strong>Siamo arrivati all&#8217;ultima puntata</strong> di <strong>questa guida base al linguaggio PHP</strong>, e per concludere affrontiamo oggi un argomento di sicuro <strong>non semplice</strong> ma che cercheremo di trattare in modo tale da fornire alcuni strumenti utili per la sua comprensione: stiamo parlando delle <strong>espressioni regolari</strong>. In una sola puntata <strong>non riusciremo</strong> a trattare l&#8217;argomento in modo completo al 100% ma con le nozioni che avremo alla fine potremo<strong> eseguire diverse operazioni</strong>.</p>
<p><span id="more-2300"></span></p>
<h3>Le espressioni regolari</h3>
<p>Per iniziare possiamo dire che cosa sono e a che cosa servono le espressioni regolari. Si tratta di particolari <strong>costrutti</strong> che si usano per verificare se all&#8217;interno di una stringa (e quando in PHP si parla di stringa si intende anche <strong>un testo lungo e complesso</strong>) è presente una certa sottostringa. Potreste pensare che in realtà non ci sono novità perché abbiamo già visto, nella puntata dedicata alle funzioni sulle stringhe, come <strong>cercare e sostituire sottostringhe</strong>. In realtà le espressioni regolari <strong>sono uno strumento molto più potente </strong>perché non definiscono semplici sottostringhe ma, data la loro natura versatile, con <strong>un solo</strong> <em><strong>pattern</strong></em> (una <strong>sequenza di caratteri</strong>) possiamo cercare una <strong>grande varietà di sottostringhe</strong>.</p>
<p>Le espressioni regolari possono essere utili per moltissime situazioni: per esempio, nella puntata in cui parlavamo dei form abbiamo fatto un cenno alle espressioni regolari perché abbiamo detto che servono per controllare se l&#8217;utente inserisce <strong>un indirizzo email corretto</strong>. Questo infatti potrebbe essere un utilizzo, ma potremmo usare le espressioni regolari per altre operazioni, per esempio controllare <strong>se un dominio è stato scritto correttamente</strong>, <strong>evidenziare una certa occorrenza</strong> o un insieme di occorrenze in un testo, <strong>cercare tutte le etichette HTML</strong> presenti in un testo, <strong>sostituire doppi apici con virgolette</strong>, <strong>controllare la complessità di una password</strong> e via dicendo.</p>
<h3>I metacaratteri</h3>
<p>Entriamo subito nell&#8217;argomento e iniziamo a parlare di <strong>“metacaratteri”</strong>, ovvero di caratteri speciali inseriti all&#8217;interno di una espressione regolare e che sono dotati <strong>di un significato ben preciso</strong>. Per esempio la sequenza<strong> [a-z] </strong>indica “qualsiasi lettera minuscola compresa tra la a e la z”. Se volessimo invece trovare tutte le lettere non solo minuscole ma anche maiuscole dovremmo scrivere un&#8217;espressione come questa: <strong>[a-zA-Z]</strong>. Avrete quindi intuito che <strong>le parentesi quadre racchiudono un insieme di caratteri</strong>. Vediamo quali sono i metacaratteri:</p>
<table border="1" cellspacing="1" cellpadding="4" >
<tr valign="TOP">
<td width="27%">[] (parentesi quadre)</td>
<td width="73%">Contengono una sequenza di caratteri</td>
</tr>
<tr valign="TOP">
<td width="27%">() (parentesi tonde)</td>
<td width="73%">Contengono una precisa sottostringa</td>
</tr>
<tr valign="TOP">
<td width="27%">. (punto)</td>
<td width="73%">Qualsiasi carattere</td>
</tr>
<tr valign="TOP">
<td width="27%">^ (accento circonflesso)</td>
<td width="73%">Inizio di stringa o negazione</td>
</tr>
<tr valign="TOP">
<td width="27%">$ (dollaro)</td>
<td width="73%">Fine della stringa</td>
</tr>
<tr valign="TOP">
<td width="27%">| (pipe)</td>
<td width="73%">Operatore disgiuntivo OR</td>
</tr>
<tr valign="TOP">
<td width="27%">\ (backslash)</td>
<td width="73%">Carattere di escape</td>
</tr>
</table>
<h3>I quantificatori</h3>
<p>Esistono poi i <strong>quantificatori</strong>, che indicano <strong>quante volte</strong> bisogna cercare un&#8217;occorrenza all&#8217;interno della nostra stringa principale:</p>
<table border="1" cellspacing="0" cellpadding="4">
<tr valign="TOP">
<td width="27%">* (asterisco)</td>
<td width="73%">Zero o più occorrenze</td>
</tr>
<tr valign="TOP">
<td width="27%">? (punto interrogativo)</td>
<td width="73%">Zero o una occorrenza</td>
</tr>
<tr valign="TOP">
<td width="27%">+ (più)</td>
<td width="73%">Una o più occorrenze</td>
</tr>
<tr valign="TOP">
<td width="27%">{} (parentesi graffe)</td>
<td width="73%">Contengono il numero che rappresenta la 			ripetizione di un&#8217;occorrenza.</td>
</tr>
</table>
<h3>Alcuni esempi&#8230;</h3>
<p>Facciamo alcuni esempi per comprendere meglio:</p>
<table border="0" cellspacing="0" cellpadding="4">
<tr valign="TOP">
<td width="27%">[a-zA-Zàèéìòù0-9]</td>
<td width="73%">Tutti i caratteri minuscoli e maiuscoli, le 			lettere accentate e i numeri</td>
</tr>
<tr valign="TOP">
<td width="27%">[^0-9]</td>
<td width="73%">Un qualsiasi carattere che non sia un numero</td>
</tr>
<tr valign="TOP">
<td width="27%">(ciao)</td>
<td width="73%">La sottostringa “ciao”</td>
</tr>
<tr valign="TOP">
<td width="27%">t?o</td>
<td width="73%">La lettera o preceduta da 0 o 1 occorrenze della 			lettera t (se il testo è “gatto, canto, albero” ci saranno 			tre risultati utili e cioè la sequenza “to” di gatto, la 			sequenza “to” di canto e la “o” di albero)</td>
</tr>
<tr valign="TOP">
<td width="27%">t*o</td>
<td width="73%">La lettera o preceduta da 0 o più occorrenze 			della lettera t (per il testo precedente ci saranno tre risultati 			utili e cioè “tto” di gatto, “to” di canto e “o” di 			albero)</td>
</tr>
<tr valign="TOP">
<td width="27%">t+o</td>
<td width="73%">La lettera o preceduta da 1 o più occorrenze 			della lettera t (due risultati utili, “tto” di gatto e “to” 			di canto)</td>
</tr>
<tr valign="TOP">
<td width="27%">t{2}o</td>
<td width="73%">La lettera o preceduta da 2 occorrenze della 			lettera t (un risultato, “tto” di gatto)</td>
</tr>
<tr valign="TOP">
<td width="27%">t{3,5}o</td>
<td width="73%">La lettera o preceduta da un minimo di 3 fino a 			un massimo di 5 occorrenze della lettera t (nessun risultato)</td>
</tr>
<tr valign="TOP">
<td width="27%">[^t]t{1}o</td>
<td width="73%">Un&#8217;occorrenza della lettera t seguita dalla 			lettera o e preceduta da qualsiasi carattere purché non sia una t 			(un risultato, “to” di canto)</td>
</tr>
<tr valign="TOP">
<td width="27%">[a-s](to)</td>
<td width="73%">Qualsiasi carattere compreso tra a e s seguito 			dalla sottostringa “to” (un solo risultato, “to” di 			canto).</td>
</tr>
<tr valign="TOP">
<td width="27%">(2\+2)</td>
<td width="73%">La stringa “2+2”</td>
</tr>
<tr valign="TOP">
<td width="27%">.$</td>
<td width="73%">Qualsiasi carattere purché sia l&#8217;ultimo della 			stringa</td>
</tr>
<tr valign="TOP">
<td width="27%">(to)|(ro)</td>
<td width="73%">La sottostringa “to” o la sottostringa “ro” 			(tre risultati: “to” di gatto, “to” di canto e “ro” di 			albero</td>
</tr>
</table>
<h3>&#8230; e altri esempi, più pratici</h3>
<p>E così via. A questo punto abbiamo quindi gli strumenti per creare dei pattern utili&#8230; partiamo dall&#8217;esempio più semplice, ovvero <strong>un pattern per validare una partita IVA</strong> che come tutti sappiamo è composta da undici numeri:</p>
<p><code>^[0-9]{11}$</code></p>
<p>Non facciamo altro che creare una sequenza [0-9] <strong>che indica un qualsiasi numero</strong>, e la facciamo seguire subito dalla sequenza {11} che indica che il numero <strong>deve obbligatoriamente occorrere undici volte</strong>. L&#8217;accento circonflesso e il dollaro indicano ovviamente <strong>l&#8217;inizio e la fine della stringa</strong>. Se omettessimo uno dei due, <strong>avremmo vanificato il controllo</strong> in quanto potremmo inserire un qualsiasi numero prima o dopo la nostra partita IVA e il pattern verrebbe comunque validato perché il nostro script non saprebbe <strong>da dove inizia o dove finisce la stringa</strong>.</p>
<p>Possiamo poi creare un <strong>pattern che controlli che un dato file sia un&#8217;immagine</strong>:</p>
<p><code>^.+\.(jpeg|jpg|png|gif)$</code></p>
<p>Abbiamo qui il punto che indica <strong>una qualsiasi sequenza di caratteri</strong>, seguito da un “vero” punto (per essere considerato tale, <strong>deve essere preceduto dal carattere di escape</strong>) e quindi dalle estensioni tipiche delle immagini “da web” (jpeg, jpg, png, gif) <strong>tra parentesi tonde</strong> e separate tra di loro per mezzo dell&#8217;<strong>operatore disgiuntivo</strong>.</p>
<p>Prendiamo poi, per esempio, <strong>un controllo per validare una data</strong>:</p>
<p><code>^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{4}$</code></p>
<p>In questo caso non facciamo altro che creare tre sequenze [0-9] <strong>rispettivamente per i giorni, i mesi e gli anni</strong>: nei primi due casi il numero può comparire <strong>da un minimo di una a un massimo di due volte </strong>e deve essere seguito da un punto (con cui separiamo i numeri della data&#8230; gusti personali) a sua volta preceduto da un <strong>backslash</strong>. Per quanto riguarda l&#8217;anno invece il numero deve essere <strong>obbligatoriamente presente quattro volte</strong>.</p>
<p>Più complesso invece è il <strong>pattern per validare un indirizzo email</strong>:</p>
<p><code>^[a-zA-Z0-9_\.\-]+@[a-zA-Z0-9_\.\-]+\.[a-z]{2,6}$</code></p>
<p>Nella prima sequenza tra parentesi quadre inseriamo <strong>tutti i caratteri alfanumerici insieme all&#8217;underscore, al punto e al trattino</strong> e indichiamo che possono ricorrere <strong>una o più volte</strong> attraverso l&#8217;uso del segno +, a fui facciamo seguire <strong>la chiocciola</strong>. Questa prima sequenza rappresenta il nome utente dell&#8217;indirizzo. Dopo la chiocciola inseriamo un&#8217;altra sequenza tra parentesi quadre simile alla prima e poi inseriamo <strong>il punto preceduto dal carattere di escape</strong>. Abbiamo quindi <strong>il nome del dominio</strong>, a cui facciamo seguire l&#8217;espressione [a-z] che può ricorrere <strong>da un minimo di 2 fino a un massimo di 6 volte</strong>: è nient&#8217;altro che <strong>l&#8217;estensione del dominio</strong>.</p>
<h3>Le classi di caratteri</h3>
<p>Per alcune delle espressioni che abbiamo utilizzato esistono poi le cosiddette <strong>“classi di caratteri”</strong>, ovvero <strong>caratteri che corrispondono a precise sequenze</strong> e che possono accorciare molto il nostro lavoro. Vediamone alcune:</p>
<table border="1" cellspacing="0" cellpadding="4" width="100%">
<col width="128*"></col>
<col width="128*"></col>
<tbody>
<tr valign="TOP">
<td width="27%">\w</td>
<td width="73%">Corrisponde a [a-zA-Z0-9_]</td>
</tr>
<tr valign="TOP">
<td width="27%">\W</td>
<td width="73%">Corrisponde a [^a-zA-Z0-9_]</td>
</tr>
<tr valign="TOP">
<td width="27%">\d</td>
<td width="73%">Corrisponde a [0-9]</td>
</tr>
<tr valign="TOP">
<td width="27%">\D</td>
<td width="73%">Corrisponde a [^0-9]</td>
</tr>
<tr valign="TOP">
<td width="27%">\s</td>
<td width="73%">Cerca gli spazi</td>
</tr>
<tr valign="TOP">
<td width="27%">\S</td>
<td width="73%">Cerca tutto ciò che non sia uno spazio</td>
</tr>
<tr valign="TOP">
<td width="27%">[:alnum:]</td>
<td width="73%">Corrisponde a [a-zA-Z0-9]</td>
</tr>
<tr valign="TOP">
<td width="27%">[:alpha:]</td>
<td width="73%">Corrisponde a [a-zA-Z]</td>
</tr>
<tr valign="TOP">
<td width="27%">[:lower:]</td>
<td width="73%">Corrisponde a [a-z]</td>
</tr>
<tr valign="TOP">
<td width="27%">[:upper:]</td>
<td width="73%">Corrisponde a [A-Z]</td>
</tr>
<tr valign="TOP">
<td width="27%">[:punct:]</td>
<td width="73%">Cerca i caratteri di punteggiatura</td>
</tr>
</tbody>
</table>
<p>Negli ultimi cinque casi, le parentesi quadre sono parte integrante della sequenza, quindi se vogliamo cercare i i segni di interpunzione nella nostra stringa il pattern dovrà essere strutturato in questo modo:</p>
<p>[[:punct:]]</p>
<p>Con le classi di caratteri, le stringhe per la validazione di partite IVA e indirizzi email, tanto per prendere due degli esempi che abbiamo fatto in precedenza, potrebbero diventare una cosa di questo tipo:</p>
<p><code>^\d{11}$</code></p>
<p><code>^\S+@[\w.-]+\.[a-z]{2,6}$</code></p>
<h3>Espressioni regolari e PHP: preg_match e preg_replace</h3>
<p>Ma come fare per <strong>eseguire il controllo nel nostro script PHP</strong>? Abbiamo bisogno di una funzione, <em>preg_match</em>, che riceve come parametri <strong>il pattern e la stringa da controllare</strong> e nel caso in cui nel testo ci sia almeno una coincidenza con il pattern, la funzione restituirà come risultato 1 (true), e in caso contrario il risultato sarà 0 (false).</p>
<p>Per esempio, poniamo il caso di uno script che controlla se un utente, attraverso un form, <strong>ha caricato un&#8217;immagine con estensione corretta</strong> (il nome dell&#8217;immagine sarà stato precedentemente memorizzato in una variabile $immagine).</p>
<p><code>if (preg_match('/^.+\.(jpeg|jpg|png|gif)$/', $immagine)) {<br />
echo "Grazie per aver caricato l'immagine!";<br />
}<br />
else {<br />
echo "L'immagine ha un'estensione non valida";<br />
}</code></p>
<p>I due slash inseriti dopo gli apici del primo parametro della funzione sono <strong>i delimitatori</strong>: se non inseriti,<strong> lo script restituirà un errore</strong>. Il meccanismo della funzione è molto semplice: il blocco if controlla che il risultato sia true e in caso affermativo stampa la scritta “Grazie per aver caricato l&#8217;immagine!”, mentre in caso contrario la scritta mostrata all&#8217;utente sarà “L&#8217;immagine ha un&#8217;estensione non valida”.</p>
<p>La funzione può essere usata anche, ovviamente, <strong>nel modo inverso</strong>, al negativo, facendo precedere la funzione <strong>dal punto esclamativo che indica negazione</strong>:</p>
<p><code>if (!preg_match('/^[a-zA-Z0-9_\.\-]+@[a-zA-Z0-9_\.\-]+\.[a-z]{2,6}$/', $indirizzoemail)) {<br />
echo "Indirizzo email non valido";<br />
}<br />
else {<br />
echo "Indirizzo email valido!";<br />
}</code></p>
<p>In questo caso <strong>abbiamo controllato un indirizzo email</strong>. La documentazione ufficiale della funzione <em>preg_match</em> si può trovare all&#8217;indirizzo <a href="http://php.net/manual/en/function.preg-match.php">http://php.net/manual/en/function.preg-match.php</a>.</p>
<p>Abbiamo detto poi che attraverso le espressioni regolari possiamo poi anche fare <strong>sostituzioni all&#8217;interno di un testo</strong>. Questa operazione si può eseguire attraverso l&#8217;utilizzo della funzione <em>preg_replace</em> che riceve <strong>tre parametri</strong>: l&#8217;espressione regolare che definisce <strong>le sequenze da sostituire</strong>, <strong>la sottostringa sostituta</strong> e <strong>la stringa all&#8217;interno della quale compiere la sostituzione</strong>. Con un esempio banale:</p>
<p><code>$testo = "Cane, gatto, topo, cavallo, pecora, mucca";<br />
echo preg_replace ("/[aeiou]/", "*", $testo);</code></p>
<p>Attraverso l&#8217;utilizzo della funzione <em>preg_replace</em> (il cui risultato sarà direttamente stampato attraverso <em>echo</em>) cerchiamo nella stringa $testo tutte le volte in cui <strong>occorre una vocale</strong> tramite la sequenza <strong>[aeiou]</strong>, e <strong>sostituiamo ogni vocale con un asterisco</strong>. Questa funzione si presta a diversi utilizzi&#8230; per esempio, stiamo costruendo un blog e vogliamo censurare le parolacce dei nostri commentatori (farò un esempio&#8230; senza parolacce ma che funziona allo stesso modo).</p>
<p><code>$testo = "Il gatto mangia il topo";<br />
echo preg_replace ("/(gatto|topo)/", "***", $testo);</code></p>
<p>In questo caso la parola “gatto” e la parola “topo” vengono sostituite dalla sequenza ***. Possiamo poi adoperare la funzione anche per <strong>sostituire etichette HTML</strong>:</p>
<p><code>$testo = "&lt;strong&gt;Ciao&lt;/strong&gt;!!!!!";<br />
$testo = preg_replace("/(&lt;strong&gt;)/", "&lt;em&gt;", $testo);<br />
echo preg_replace("/(&lt;\/strong&gt;)/", "&lt;/em&gt;", $testo);</code></p>
<p>In questo caso sostituiamo <strong>tutte le parole marcate in grassetto con parole marcate in corsivo</strong>. Questi non sono che alcuni esempi, e <strong>la versatilità delle espressioni regolari</strong> dà modo a ognuno di <strong>sfruttarle al meglio per le proprie esigenze</strong>. Per chiunque fosse interessato all&#8217;argomento, consiglio di approfondire facendo una ricerca sul web: si trovano davvero molti siti che sapranno spiegare meglio di me e in modo più completo l&#8217;utilizzo di questo affascinante strumento.</p>
<h3>Ciao a tutti!!!</h3>
<p>Benissimo, con la puntata di oggi termina anche la nostra guida di base al linguaggio PHP!</p>
<p>Mi auguro che la guida sia stata di vostro gradimento, che possa essere stata utile per imparare qualcosa di nuovo o per ripassare e che possa in generale dare un piccolo aiuto a chiunque voglia cimentarsi con PHP. Ringrazio Laura per avermi fornito questo spazio e ovviamente un grazie a tutti quelli che mi hanno seguito fino a questo punto, a quelli che hanno seguito anche poche puntate, a chi si è collegato una volta sola e a tutti coloro che hanno commentato e hanno tentato di risolvere gli esercizi <img src='http://www.web-magazine.it/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Un grande saluto!!!!!!!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.web-magazine.it/2012/01/creare-siti-in-php-%e2%80%93-30-%e2%80%93-le-espressioni-regolari/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://www.web-magazine.it/2012/01/creare-siti-in-php-%e2%80%93-30-%e2%80%93-le-espressioni-regolari/</feedburner:origLink></item>
		<item>
		<title>Creare siti in PHP – (29) – La sicurezza in PHP: session hijacking</title>
		<link>http://feedproxy.google.com/~r/web-magazine/~3/chNdUfg9B8A/</link>
		<comments>http://www.web-magazine.it/2012/01/creare-siti-in-php-%e2%80%93-29-%e2%80%93-la-sicurezza-in-php-session-hijacking/#comments</comments>
		<pubDate>Mon, 23 Jan 2012 06:00:40 +0000</pubDate>
		<dc:creator>Federico</dc:creator>
				<category><![CDATA[scripting]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sessioni]]></category>
		<category><![CDATA[sicurezza]]></category>

		<guid isPermaLink="false">http://www.web-magazine.it/?p=2296</guid>
		<description><![CDATA[Nella penultima puntata della guida base a PHP parliamo di session hijacking nelle sue due forme più temibili: session fixation e session sidejacking. Impariamo come difenderci utilizzando la funzione session_regenerate_id ed eseguendo controlli sullo user agent]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.web-magazine.it/wp-content/uploads/2011/11/php29.jpg" alt="La sicurezza in PHP: session hijacking " /></p>
<p>Terminiamo oggi la breve panoramica sui più comuni problemi di sicurezza con una puntata sul <strong>session hijacking</strong>, che consiste nel <strong>“furto dell&#8217;identità”</strong> di un utente che si collega a un sito web.</p>
<p><span id="more-2296"></span></p>
<h3>Session hijacking: che cos&#8217;è</h3>
<p>Che cosa fa il malintenzionato che sottopone l&#8217;utente di un sito a session hijacking? Non fa altro che <strong>rubare l&#8217;identificativo di sessione dell&#8217;utente</strong> (ogni sessione <strong>ha un proprio id</strong>) per poi loggarsi al sito <strong>spacciandosi per l&#8217;utente</strong> a cui ha rubato le credenziali. Uno dei metodi più comuni per rubare le credenziali è <strong>sfruttare il cross-site scripting</strong>: abbiamo però già parlato nell&#8217;episodio precedente di come difenderci da questo tipo di attacchi, quindi vedremo oggi come coprirci anche da un furto ottenuto tramite <strong>“session fixation”</strong>: con la <strong>session fixation</strong>, i dati verranno rubati tramite <strong>una sessione creata </strong><em><strong>ad hoc</strong></em> dal malintenzionato.</p>
<p>Certo, affinché si verifichi una session fixation<strong> devono essere soddisfatte due condizioni</strong>: <strong>codice vulnerabile</strong> e <strong>utente sprovveduto</strong>. Nella puntata sulle sessioni non abbiamo parlato del modo in cui l&#8217;id di sessione <strong>viene propagato</strong>: ciò può avvenire <strong>tramite un cookie</strong> che viene appositamente creato per contenere l&#8217;id (cookie che si estinguerà alla chiusura del browser) oppure, nel caso in cui i cookie siano stati disabilitati, <strong>tramite metodi get e post</strong>. Il ladro di sessioni può convincere l&#8217;utente del nostro sito (magari tramite una mail o con un post su un blog) a collegarsi a un indirizzo simile a questo: www.nostrosito.it/login.php?PHPSESSID=12345 dove, <strong>attraverso la query string</strong> e ipotizzando che l&#8217;id di sessione venga <strong>propagato tramite get</strong>, decide il numero di sessione.</p>
<h3>Simuliamo un attacco</h3>
<p>Per comprendere meglio il meccanismo di un attacco session fixation proviamo a simularne uno (ma, come detto nella scorsa puntata, solo affinché vi possiate difendere). Per prima cosa assicuriamoci che nelle impostazioni del nostro PHP sia abilitata la trasmissione dei dati di sessione <strong>attraverso url</strong>: clicchiamo quindi sull&#8217;icona di Wamp, andiamo sotto la voce PHP e quindi apriamo il file php.ini. Cerchiamo adesso la direttiva <em>session.use_trans_sid</em>, che è quella che consente la <strong>tramissione degli id di sessione via url</strong> (a proposito: i commenti sopra di essa vi diranno che <strong>abilitarla sottopone a rischi di sicurezza</strong>). Se è a 1 lasciamola com&#8217;è, altrimenti se è impostata a 0 dobbiamo settarla a 1. Cerchiamo poi la direttiva <em>session.use_only_cookies</em> (permette la trasmissione degli id di sessione <strong>solo tramite cookie</strong>) e impostiamola a 0.</p>
<p>A questo punto creiamo un semplice codice PHP che al nostro collegamento dà inizio a una sessione che memorizza <strong>il numero di volte in cui visualizziamo la pagina</strong> con il nostro browser:</p>
<p><code>&lt;?php<br />
session_start();<br />
if (!isset($_SESSION['conto'])) {<br />
$_SESSION['conto'] = 0;<br />
} else {<br />
$_SESSION['conto']++;<br />
}<br />
echo "Numero:" . $_SESSION['conto']."";<br />
?&gt;</code></p>
<p>Tutto molto semplice. Con la solita funzione <em>isset </em>controlliamo che la variabile $_SESSION['conto'] non sia stata inizializzata: se non esiste, la creiamo e la impostiamo a 0, se invece esiste già la incrementiamo. Terminato il blocco if stampiamo la nostra variabile.</p>
<p>Salvate il file chiamandolo, per esempio, “fixation.php” e inseritelo in una cartella “prova” all&#8217;interno della cartella “www” di Wamp. A questo punto aprite il vostro browser preferito (per esempio Firefox), <strong>eliminate tutti i cookie</strong> di localhost e collegatevi a questo indirizzo: http://localhost/prova/fixation.php?PHPSESSID=12345. Aggiornate la pagina un qualsiasi numero di volte, arriviamo per esempio a 9.</p>
<p>A questo punto chiudete pure il browser. Riaprite un altro browser (esempio, Chrome), magari anche su un altro computer se fate la prova su un server remoto, e provate a collegarvi allo stesso indirizzo: come potrete notare il conto non ripartirà da 0 ma partirà da dove siete rimasti prima (nel nostro caso vedremo “10”). Cosa significa questo? Abbiamo simulato <strong>un ipotetico utente A</strong> che utilizza Firefox, apre la pagina con il link <strong>che gli è stato suggerito dal malintenzionato utente B </strong>e dà inizio a una sessione. L&#8217;utente B aprirà poi il suo Chrome <strong>con l&#8217;id di sessione da lui stesso creato</strong> e <strong>potrà accedere ai dati dell&#8217;utente A</strong>. In questo caso si tratta semplicemente del numero di volte che ha aggiornato la pagina, ma questo tipo di attacco funziona tranquillamente anche su script molto più complessi (per esempio un login a un sito web: il malintenzionato B potrà accedere indisturbato a tutti i dati personali dell&#8217;utente A) che però <strong>hanno seri problemi di sicurezza</strong>.</p>
<h3>Come difendersi: session_regenerate_id</h3>
<p>Come difendersi da questo attacco? Il metodo più semplice è <strong>rigenerare spesso l&#8217;id di sessione</strong>, in modo da rendere inefficaci gli attacchi: questo si può fare agevolmente tramite l&#8217;apposita funzione <em>session_regenerate_id</em>, che si applica in modo molto semplice:</p>
<p><code>session_regenerate_id();</code></p>
<p>E in genere va fatto <strong>dopo aver dato il via alla sessione </strong>con <em>session_start</em>. La documentazione ufficiale di questa funzione si trova all&#8217;indirizzo <a href="http://php.net/manual/en/function.session-regenerate-id.php">http://php.net/manual/en/function.session-regenerate-id.php</a>. Inoltre sarebbe bene che le direttive di cui sopra,  <em>session.use_trans_sid</em> e  <em>session.use_only_cookies</em>, fossero impostate rispettivamente a 0 e 1. Comunque l&#8217;utilizzo di <em>session_regenerate_id </em>è di per sé già sufficiente per difendersi. È quindi bene <strong>rigenerare spesso</strong>, anche <strong>prima che l&#8217;utente abbia fatto login</strong> (inserendo quindi la funzione nella pagina di login, per esempio).</p>
<h3>Come difendersi: controllo sullo user agent</h3>
<p>Infine potremmo eseguire <strong>un controllo aggiuntivo sullo user agent dell&#8217;utente</strong> (perché niente impedisce che <strong>uno stesso id di sessione</strong>, come abbiamo visto, <strong>possa essere utilizzato da due utenti diversi</strong>): questo consente anche di avere una difesa contro attacchi di tipo <strong>“session sidejacking”</strong>. Attraverso questo tipo di attacco, comunque difficile da mettere in atto, il malintenzionato cerca di <strong>intercettare l&#8217;id di sessione attraverso i pacchetti di rete</strong> che vengono scambiati tra il server e il browser dell&#8217;utente. Per ovviare a questa minaccia può essere utile fare in modo che <strong>l&#8217;accesso venga impedito</strong> nel caso in cui lo <em>user agent</em> di chi richiede l&#8217;accesso al nostro sito<strong> non corrisponda </strong>a quello dell&#8217;utente che ha effettuato il login.</p>
<p>Per fare questo abbiamo bisogno della variabile superglobale <strong>$_SESSION</strong>: dovremo associare a essa il valore dell&#8217;elemento <strong>HTTP_USER_AGENT</strong> della variabile superglobale <strong>$_SERVER</strong>, <strong>meglio se codificato tramite funzione md5</strong>. Il tutto nella pagina o nella funzione che consente il login:</p>
<p><code>$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);</code></p>
<p>In questo modo abbiamo creato un elemento della sessione chiamato HTTP_USER_AGENT a cui abbiamo associato nient&#8217;altro che il nostro user agent criptato con md5. A questo punto, per eseguire il controllo, potremmo utilizzare un codice simile a questo:</p>
<p><code>if (isset($_SESSION['HTTP_USER_AGENT'])) {<br />
if ($_SESSION['HTTP_USER_AGENT'] != md5($_SERVER['HTTP_USER_AGENT'])) {<br />
logout();<br />
}<br />
}</code></p>
<p>Con questo script non facciamo altro che controllare, sempre tramite la funzione<em> isset</em>, se esiste la sessione con elemento “HTTP_USER_AGENT”: in caso affermativo, se il suo valore <strong>è diverso dallo user agent</strong>, sempre criptato con md5, <strong>dell&#8217;utente che sta eseguendo lo script</strong> (in altre parole se <strong>chi si è loggato ha uno user agent diverso</strong> rispetto a quello <strong>dell&#8217;utente che sta cercando di forzare l&#8217;accesso al sito</strong>), rimandiamo l&#8217;utente a una ipotetica funzione logout <strong>che distruggerà la sessione</strong>.</p>
<p>Anche per oggi la puntata è arrivata alla fine: vi do appuntamento alla prossima, la trentesima nonché ultima della nostra guida!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.web-magazine.it/2012/01/creare-siti-in-php-%e2%80%93-29-%e2%80%93-la-sicurezza-in-php-session-hijacking/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://www.web-magazine.it/2012/01/creare-siti-in-php-%e2%80%93-29-%e2%80%93-la-sicurezza-in-php-session-hijacking/</feedburner:origLink></item>
		<item>
		<title>Creare siti in PHP – (28) – La sicurezza in PHP: XSS e SQL Injection</title>
		<link>http://feedproxy.google.com/~r/web-magazine/~3/wYDFi3Imocc/</link>
		<comments>http://www.web-magazine.it/2012/01/creare-siti-in-php-%e2%80%93-28-%e2%80%93-la-sicurezza-in-php-xss-e-sql-injection/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 06:00:34 +0000</pubDate>
		<dc:creator>Federico</dc:creator>
				<category><![CDATA[scripting]]></category>
		<category><![CDATA[web design]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sicurezza]]></category>
		<category><![CDATA[sql injection]]></category>
		<category><![CDATA[strip_tags]]></category>
		<category><![CDATA[xss]]></category>

		<guid isPermaLink="false">http://www.web-magazine.it/?p=2291</guid>
		<description><![CDATA[Prima di due puntate dedicate alla sicurezza in PHP. Parliamo oggi di cross-site scripting (XSS) e di SQL injection e impariamo alcune semplici tecniche su come difendere il nostro sito. E ricordiamoci di filtrare sempre tutti gli input!]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.web-magazine.it/wp-content/uploads/2011/11/php28.jpg" alt="La sicurezza in PHP: XSS e SQL Injection" /><br />
Iniziamo oggi una breve panoramica su due dei <strong>problemi di sicurezza più comuni</strong> degli script PHP.</p>
<p><span id="more-2291"></span></p>
<h3>XSS: Cross-site scripting</h3>
<p>Partiamo dal cosiddetto <strong>“Cross-site scripting”</strong>, noto anche come <strong>XSS</strong>: si tratta di un problema, molto diffuso, che riguarda <strong>la sicurezza dei form</strong> e in particolare i form che <strong>non applicano controlli sui campi</strong>. Il malintenzionato può, tramite il form, far eseguire un codice JavaScript che magari <strong>rimanda a un suo sito</strong> dove è contenuto <strong>uno script dannoso</strong>. A proposito: ricordo a tutti quelli che leggono (visti i numerosi accessi al sito) che alcune delle cose che sto per illustrare, se messe in pratica, <strong>costituiscono un reato penalmente perseguibile</strong>. <strong>Ve ne parlo solo affinché vi possiate difendere</strong>.</p>
<p>Tornando al nostro XSS, prendiamo un semplicissimo form per inserire un messaggio:</p>
<p><code>&lt;form action="xss.php" method="get"&gt;<br />
Nome:&lt;br /&gt;<br />
&lt;input type="text" name="nome" /&gt;&lt;br /&gt;<br />
Messaggio: &lt;br /&gt;<br />
&lt;textarea rows="10" cols="20" name="messaggio"&gt;&lt;/textarea&gt;&lt;br /&gt;<br />
&lt;input type="submit" name="invia" value="Invia!" /&gt;&lt;br /&gt;<br />
&lt;/form&gt;</code></p>
<p>E supponiamo che il codice della pagina xss.php sia strutturato in questo modo:</p>
<p><code>&lt;?php<br />
echo "Nome: {$_GET['nome']}";<br />
echo "&lt;br /&gt;&lt;br /&gt;Messaggio: &lt;br /&gt;&lt;br /&gt;";<br />
echo stripslashes($_GET['messaggio']);<br />
?&gt;</code></p>
<p>Bene, questo è <strong>un codice del tutto insicuro </strong>perché <strong>non ci sono controlli di sicurezza</strong>. Nel campo “messaggio” l&#8217;hacker può <strong>facilmente inserire un codice JavaScript </strong>di questo tipo:</p>
<p><code>&lt;script language="text/javascript"&gt;document.location.href="http://www.web-magazine.it";&lt;/script&gt;</code></p>
<p>Dove ovviamente al posto di web-magazine.it c&#8217;è <strong>un sito malvagio</strong>. Attraverso la stampa con <em>echo</em>, il codice <strong>viene inserito nella pagina xss.php e quindi eseguito</strong>. E ovviamente, date le tante cose che si possono fare con JavaScript, il reindirizzamento non è che <strong>una possibilità</strong>: il malintenzionato può infatti anche <strong>installare script dannosi direttamente all&#8217;interno del sito</strong>. E questo tipo di attacco funziona sia che il nostro form abbia metodo <strong>get</strong>, sia che abbia metodo <strong>post</strong>. Tipicamente, gli script XSS vengono utilizzati per <strong>rubare cookie</strong> ai malcapitati.</p>
<h3>Come difendersi dal cross-site scripting</h3>
<p>Difendersi da questo tipo di attacchi <strong>è veramente molto semplice</strong>: bisogna <strong>solo tenerlo a mente</strong>! Basterà fare in modo che i<strong> caratteri riservati del linguaggio HTML </strong> <strong>vengano sostituiti con le relative entità</strong> (per esempio la parentesi uncinata aperta con &amp;lt;) o che le etichette HTML vengano del tutto cancellate.</p>
<p>Per fare questo abbiamo tre funzioni: <em>htmlspecialchars</em>, <em>htmlentities</em> e <em>strip_tags</em>. <strong>Funzionano tutte allo stesso modo</strong>: ricevono come parametro <strong>la stringa per la quale dobbiamo sostituire i caratteri</strong>. Ecco quindi qual è il codice corretto e sicuro da utilizzare nella pagina xss.php:</p>
<p><code>&lt;?php<br />
echo "&lt;br /&gt;&lt;br /&gt;Messaggio: &lt;br /&gt;&lt;br /&gt;";<br />
echo htmlspecialchars(stripslashes($_GET['messaggio']));<br />
?&gt;</code></p>
<p>Oppure</p>
<p><code>echo htmlentities(stripslashes($_GET['messaggio']));</code></p>
<p>O ancora</p>
<p><code>echo strip_tags(stripslashes($_GET['messaggio']));</code></p>
<h3>htmlspecialchars, htmlentities e strip_tags</h3>
<p>Ci sono ovviamente <strong>alcune differenze tra le tre funzioni</strong>. La differenza tra <em>htmlspecialchars</em> e <em>htmlentities</em> consiste nel fatto che la prima converte in entità <strong>solo i caratteri riservati di HTML</strong>, mentre la seconda converte <strong>anche i caratteri speciali</strong> (per esempio, se dovessimo scrivere in tedesco, la o con la dieresi – ö – sarebbe convertita in &amp;ouml;). La funzione <em>strip_tags</em> invece <strong>elimina del tutto le etichette HTML</strong>. In ogni caso, il codice immesso dal malintenzionato verrebbe <strong>stampato sullo schermo e non eseguit</strong>o (anzi, nel caso di <em>strip_tags</em> <strong>le tag verrebbero del tutto eliminate</strong>). E<strong> ricordate sempre</strong>: uno dei migliori metodi per difendersi dagli attacchi è <strong>filtrare tutto ciò che arriva in input sul nostro sito</strong>. In questo caso abbiamo visto come filtrare attraverso le tre funzioni di cui abbiamo parlato: potete trovare le documentazioni ufficiali delle funzioni a queste pagine: <a href="http://www.php.net/manual/en/function.htmlspecialchars.php">http://www.php.net/manual/en/function.htmlspecialchars.php</a> (<em>htmlspecialchars</em>), <a href="http://php.net/manual/en/function.htmlentities.php">http://php.net/manual/en/function.htmlentities.php</a> (<em>htmlentities</em>), <a href="http://it.php.net/manual/en/function.strip-tags.php">http://it.php.net/manual/en/function.strip-tags.php</a> (<em>strip_tags</em>).</p>
<h3>SQL Injection</h3>
<p>Il secondo problema di vulnerabilità che vediamo oggi è la cosiddetta <strong>SQL Injection</strong> (iniezione di SQL). Anche in questo caso l&#8217;attacco prende di mira <strong>form scritti male </strong>per eseguire<strong> un codice SQL malevolo</strong>, e adesso vedremo nel dettaglio in cosa consiste questa pratica e <strong>perché è tanto pericolosa</strong>. Prendiamo per esempio questo semplice form per connettersi a un sito:</p>
<p><code>&lt;form action="login.php?step=2" method="post"&gt;<br />
Nickname:&lt;br /&gt;<br />
&lt;input type="text" name="nickname" /&gt;&lt;br /&gt;<br />
Password: &lt;br /&gt;<br />
&lt;input type="password" name="psw" /&gt;&lt;br /&gt;<br />
&lt;input type="submit" name="invia" value="Invia!" /&gt;&lt;br /&gt;<br />
&lt;/form&gt;</code></p>
<p>In questo caso il nostro form, invece di rimandare a una nuova pagina, rimanda alla stessa ma con l&#8217;aggiunta della query string <strong>?step=2</strong>, in modo da scrivere <strong>tutto nella stessa pagina</strong>. L&#8217;azione del form andrà quindi scritta in un blocco if di questo tipo:</p>
<p><code>if (isset($_GET['step']) &amp;&amp; $_GET['step'] == 2) {<br />
// azione<br />
}<br />
else {<br />
}</code></p>
<p>Ipotizziamo anche che il gestore del sito o del blog sia stato così sprovveduto da aver fatto in modo che le password <strong>vengano inserite in chiaro nel database</strong> (quindi senza criptarle attraverso il form di registrazione). Ora prendiamo il pessimo script che esegue il controllo sui dati immessi dall&#8217;utente:</p>
<p><code>$query = "SELECT * FROM autori WHERE Nickname = '{$_POST['nickname']}' AND Password = '{$_POST['psw']}'";<br />
$risultato = mysql_query($query);<br />
if (mysql_num_rows($risultato) == '1') {<br />
echo "Benvenuto, utente autenticato";<br />
// codice che mostra l'eventuale pagina personale dell'utente<br />
}<br />
else {<br />
echo "Spiacente, password errata";<br />
}</code></p>
<p>Chiariamo subito la funzione nuova, <em>mysql_num_rows</em>: restituisce <strong>il numero dei record trovati dalla query </strong>(nel nostro caso uno, anche perché si suppone che<strong> gli username siano univoci</strong>) e riceve come parametro il risultato della query. Qua si trova la documentazione ufficiale della funzione: <a href="http://php.net/manual/en/function.mysql-num-rows.php">http://php.net/manual/en/function.mysql-num-rows.php</a>. Pertanto se la funzione dà come risultato 1 (e quindi trova il record), <strong>l&#8217;utente sarà loggato</strong>, in caso contrario ci sarà un messaggio che informerà l&#8217;utente di <strong>aver inserito una password errata</strong>.</p>
<p>Questo codice <strong>è estremamente vulnerabile</strong>, soprattutto nel caso in cui l&#8217;impostazione <em>magic quotes gpc</em> di PHP sia disattivata: in locale potete controllarlo su WAMP cliccando sull&#8217;icona nella barra delle applicazioni, quindi andare alla voce PHP e ancora andare su Impostazioni PHP. Se la voce “magic quotes gpc” è spuntata significa che è attiva e avete <strong>maggiori protezioni contro le SQL Injection</strong>. Ci sono però tanti provider che non attivano le <em>magic quotes</em> sui loro server. <strong>Ma cosa sono le magic quotes</strong>? Si tratta di un processo che <strong>aggiunge in automatico i caratteri di escape alle stringhe</strong>, ma dobbiamo sapere che a partire dalla versione 5.3.0 di PHP, <strong>magic quotes è deprecato</strong> e nella versione 6<strong> addirittura non c&#8217;è più</strong>.</p>
<p>Vediamo quindi cosa può fare il malintenzionato. Nella casella nickname può inserire il nome “Federico”, e fin qui niente di strano. Ma nella casella password può tranquillamente inserire questa stringa:</p>
<p><code>' OR Nickname='Federico </code></p>
<p>Così facendo, il nostro codice eseguirebbe questa query:</p>
<p><code>$query = "SELECT * FROM autori WHERE Nickname = 'Federico' AND Password =<br />
'' OR Nickname='Federico'";</code></p>
<p>La clausola OR inserita dal malintenzionato <strong>vanificherà il controllo sulla password</strong>: questo perché la query strutturata in tal modo dice di selezionare tutti i record della tabella autori il cui nickname sia Federico e la cui password sia vuota <strong>oppure</strong>, <strong>in alternativa a quest&#8217;ultima clausola</strong>, il cui nickname sia Federico. Dal momento che la seconda clausola è soddisfatta il malintenzionato <strong>riuscirà a entrare agevolmente </strong>al posto di Federico all&#8217;interno del sito, spacciandosi per lui e magari rubando i suoi dati&#8230; o insomma facendo tutto ciò che di cattivo si può fare entrando nel profilo di un&#8217;altra persona.</p>
<h3>Criptiamo la password con md5</h3>
<p>La prima operazione da fare è <strong>criptare la password </strong>attraverso la funzione <em>md5</em>: nel database <strong>non dovrà essere inserita in chiaro </strong>ma andrà fatta passare attraverso questa funzione (in un&#8217;ipotetica query con comando INSERT INTO metteremo tra i VALUES &#8216;md5($_POST['password']&#8216;). <strong>MD5</strong> è un <strong>algoritmo crittografico di hashing</strong> che fu realizzato nel 1991 da <strong>Ronald Linn Rivest</strong>, un crittografo statunitense: l&#8217;algoritmo <strong>trasforma una stringa in un&#8217;altra stringa a 128 bit</strong>, e <strong>non è possibile risalire alla stringa originale</strong> (se non andando&#8230; a tentativi). La funzione md5 di PHP riceve come parametro semplicemente la stringa da criptare e la documentazione ufficiale si trova qui: <a href="http://it.php.net/manual/en/function.md5.php">http://it.php.net/manual/en/function.md5.php</a>.</p>
<p>Questo è solo uno dei tanti modi per criptare una password: parliamo di questo perché <strong>è il più semplice da utilizzare</strong>, ma c&#8217;è chi usa anche <strong>sistemi più sofisticati</strong>. Il nostro codice pertanto dovrà presentarsi in questa forma:</p>
<p><code>$query = "SELECT * FROM autori WHERE Nickname = '{$_POST['nickname']}' AND Password = '". md5($_POST['psw']). "'";</code></p>
<p>Dove i punti che separano md5($_POST['psw']) dal resto del codice sono un modo per concatenare valori all&#8217;interno di una variabile (le virgole non funzionano).</p>
<p>In questo caso ci salviamo dal malintenzionato che immette i dati di cui sopra, <strong>ma siamo ancora vulnerabili</strong>. Questo perché l&#8217;hacker potrebbe scrivere nella casella del nickname <strong>questa stringa cattivissima</strong>:</p>
<p><code>Federico' --</code></p>
<p>E magari può anche lasciare in bianco il campo della password. In tal modo la query diventerebbe questa:</p>
<p><code>$query = "SELECT * FROM autori WHERE Nickname = 'Federico' -- AND Password =<br />
''";</code></p>
<p>I <strong>due trattini </strong>nel <strong>linguaggio SQL</strong> indicano<strong> i commenti</strong>: pertanto tutto ciò che viene dopo i due trattini <strong>sarà ignorato</strong>. Capite quindi <strong>la pericolosità della cosa</strong> malgrado il controllo tramite algoritmo md5. Sarà un giochetto per il malintenzionato riuscire a entrare nel sito e magari carpire tutta la lista degli utenti registrati o a far di peggio: pensate se potesse <strong>entrare con l&#8217;account dell&#8217;amministratore</strong>.</p>
<h3>Come difendersi dalla SQL injection</h3>
<p>Qual è pertanto <strong>il modo più sicuro per difendersi da questo tipo di attacco</strong>? Non dovremo far altro che <strong>aggiungere una funzione per controllare i dati immessi dall&#8217;utente </strong>(ricordate&#8230; <strong>filtrare sempre tutto</strong>), e si tratta della funzione <em>mysql_real_escape_string</em>, che inserisce i giusti<strong> caratteri di escape</strong> prima dei caratteri “pericolosi”. Riceve come parametro semplicemente <strong>la stringa a cui aggiungere i parametri di escape</strong>. Quindi la nostra query dovrà assumere questa forma per evitare attacchi:</p>
<p><code>$query = "SELECT * FROM autori WHERE Nickname = '". mysql_real_escape_string($_POST['nickname']) ."' AND Password = '". mysql_real_escape_string($_POST['psw']). "'";</code></p>
<p>Riusciremo così a <strong>rendere inoffensivo</strong> l&#8217;attacco del malintenzionato, perché l&#8217;ultima stringa che abbiamo visto risulterà invece in questo modo:</p>
<p><code>$query = "SELECT * FROM autori WHERE Nickname = 'Federico\' -- AND Password = ''";</code></p>
<p>Questa funzione va utilizzata solo nel caso in cui <em>magic quotes gpc</em> sia disattivo. Per essere però del tutto sicuri utilizziamo la funzione <em>get_magic_quotes_gpc</em>, che controlla la configurazione delle <em>magic quotes</em> (non riceve alcunché come parametro), e inseriamola in un blocco if:</p>
<p><code>if(get_magic_quotes_gpc()) {<br />
$query = "SELECT * FROM autori WHERE Nickname = '". $_POST['nickname'] ."' AND Password = '".<br />
$_POST['psw']. "'";<br />
}<br />
else {<br />
$query = "SELECT * FROM autori WHERE Nickname = '". mysql_real_escape_string($_POST['nickname']) ."'<br />
AND Password = '". mysql_real_escape_string($_POST['psw']). "'";<br />
}</code></p>
<p>Controlliamo con il ciclo che il processo <em>magic quotes gpc</em> sia attivo, e in caso affermativo creiamo la nostra query senza la funzione <em>mysql_real_escape_string</em>, e in caso contrario ovviamente la aggiungiamo. Trovate la documentazione ufficiale di queste due funzioni qui <a href="http://it.php.net/manual/en/function.mysql-real-escape-string.php">http://it.php.net/manual/en/function.mysql-real-escape-string.php</a> (<em>mysql_real_escape_string</em>) e qui <a href="http://php.net/manual/en/function.get-magic-quotes-gpc.php">http://php.net/manual/en/function.get-magic-quotes-gpc.php</a> (<em>get_magic_quotes_gpc</em>).</p>
<p>Vi aspetto come sempre alla prossima puntata!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.web-magazine.it/2012/01/creare-siti-in-php-%e2%80%93-28-%e2%80%93-la-sicurezza-in-php-xss-e-sql-injection/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.web-magazine.it/2012/01/creare-siti-in-php-%e2%80%93-28-%e2%80%93-la-sicurezza-in-php-xss-e-sql-injection/</feedburner:origLink></item>
		<item>
		<title>Un logo non è un pareo di Donna Moderna. (to be continued…)</title>
		<link>http://feedproxy.google.com/~r/web-magazine/~3/6_lyw9csXok/</link>
		<comments>http://www.web-magazine.it/2012/01/un-logo-non-e-un-pareo-di-donna-moderna-to-be-continued/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 19:24:42 +0000</pubDate>
		<dc:creator>Laura</dc:creator>
				<category><![CDATA[pianeta freelance]]></category>
		<category><![CDATA[freelance]]></category>
		<category><![CDATA[logo]]></category>
		<category><![CDATA[storie]]></category>

		<guid isPermaLink="false">http://www.web-magazine.it/?p=2335</guid>
		<description><![CDATA[...io che non voglio che i loghi vengano considerati come accessori gratuiti di un sito, come il bicchiere che il supermercato ti regala se acquisti il latte, come il cioccolatino che ti offre il bar mentre ti serve il caffè, come il pareo che esce da Donna Moderna ad Agosto. Ecco, il logo non è il pareo di Donna Moderna.]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone" title="pareo" src="http://www.web-magazine.it/wp-content/uploads/2012/01/pareo.jpg" alt="Un logo non è un pareo di Donna Moderna" width="500" height="160" /></p>
<p>Ce ne ho messo di tempo ma alla fine ho pensato che sarebbe stato giusto dare delle spiegazioni.<br />
Il mio problema è che non ho capacità di sintesi per cui mi sa che queste spiegazioni dureranno parecchi post.</p>
<p><span id="more-2335"></span></p>
<p>Spiegazioni riguardo due cose principalmente.</p>
<p><strong>La prima è il blog, e la carenza di aggiornamenti.</strong></p>
<p>Web Magazine non si è fermato ma quasi, tempo di scrivere non ne ho più e non credo che ne avrò mai, e se non fosse per i miei preziosi <strong><a href="http://www.web-magazine.it/author/Federico/">Federico</a></strong> e <strong><a href="http://www.web-magazine.it/author/Dario/">Dario</a></strong>, rispettivamente Mr. Php e Mr. Seo, il blog sarebbe quasi defunto.</p>
<p>Lunga vita ai miei collaboratori!</p>
<p>Leggete i loro post Leggete i loro post Leggete i loro postLeggete i loro post Leggete i loro post Leggete i loro postLeggete i loro post..</p>
<p>i ragazzi si impegnano! <img src='http://www.web-magazine.it/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><strong>La seconda spiegazione è il perchè dopo anni in cui ho professato la cosiddetta missione freelance io sia tornata a timbrare cartellini.</strong></p>
<p>Facciamo però un passo indietro, anticipando prima di tutto che questo non è un post tecnico, nè un tutorial nè una guida, è un post assolutamente personale dedicato ai miei storici seguaci e a chi proprio non sa farsi gli affari propri.</p>
<p>Leggendo questo post non imparerete nulla, qualcuno si farà due risate e straccerà il mio ebook&#8230; dopo averlo stampato.</p>
<p>Ma se pensate che le esperienze vissute possano in qualche modo arricchire allora vi racconto la mia vita negli ultimi sei mesi e cercheremo anche di dare un senso a quel titolo assurdo.</p>
<p><strong>Giugno 2011 </strong>-  Dopo un breve scambio di email decido di accettare un prestigioso nonchè <em>molto-ma-mooolto-ben-pagato </em>incarico, rigorosamente freelance, come <em>interface designer</em> per un progetto della Commissione Europea, progetto che mi avrebbe portato a 900km da casa per sei mesi fino ad un massimo di tutta la vita, se lo avessi voluto.<br />
Progetto che puoi andare a sbandierare in giro perchè oggettivamente lavorare in una ex centrale nucleare in un contesto europeo dove si parla esclusivamente in inglese è una cosa maledettamente fica, non facciamo i falsi modesti.</p>
<p>A quel punto se fossimo stati in una di quelle storie di Topolino con il &#8220;bivio&#8221; (si ok, leggevo topolino ma mi stava sulle palle) avrei imboccato la strada cosiddetta: Ricca e alquanto infelice. Ma qui ci arriveremo.</p>
<p>Aspettavo quindi  la partenza di Settembre, potevo godermi le vacanze certa del fatto che sarei poi partita per <em>soldolandia </em>e nel frattempo avrei fatto giusto qualche lavoretto da casa, il bello di lavorare e abitare praticamente su una spiaggia è che in estate fare pausa pranzo in costume ti ripaga da tutte le rotture di palle che ti portano i clienti.. ma invece no, niente relax pre partenza, accetto una consulenza.</p>
<p>In realtà era una sorta di sostituzione di un web designer, quindi sarei dovuta restare  per 6 settimane in una web agency di Napoli non potendo lavorare da casa per questo tipo di incarico, ma l&#8217;agenzia già in fase di colloquio mi aveva impressionata positivamente. Persone umili ma assolutamente competenti, idee chiare in termini di business e un ambiente allegro e giovanile che, diciamocela tutta, non potevo di certo trovare nelle 4 mura del mio studiolo casalingo.</p>
<p>E si, accetto, nonostante la spiaggia, il costume, e il perenne e dolcissimo suono del mare.</p>
<p>Prendo l&#8217;auto e torno ai rumori della città, al caos delle agenzie, e alla bellezza di poter scambiare opinioni dal vivo con un collega.</p>
<p>E il primo giorno in agenzia, mentre mi sentivo come una scolaretta di trent&#8217;anni che aveva tanta voglia di fare bella figura,  vengo assalita dal panico.</p>
<p>Mi viene assegnato il primo incarico: <strong>Disegnare un logo</strong><strong>.</strong></p>
<p>Io, che non ho problemi a dire ad un cliente che se vuole il logo lo pagherà il doppio semplicemente perchè odio fare i loghi;</p>
<p>io, che ho fatto le migliori litigate nella speranza di chiarire il  concetto che un web designer e un grafico pubblicitario sono due figure  assolutamente diverse..</p>
<p>io che non voglio che i loghi vengano considerati come accessori gratuiti di un sito, come il  bicchiere che il supermercato ti regala se acquisti il latte, come il cioccolatino che ti offre il bar mentre ti serve il caffè, come il  pareo che esce da Donna Moderna ad Agosto.</p>
<p>Ecco, il logo non è il pareo di Donna Moderna.</p>
<p>Io dovevo disegnare un logo???</p>
<p>Pensavo mi considerassero una discreta web designer, e mi hanno chiesto di disegnare un logo.</p>
<p>Il primo giorno di lavoro.</p>
<p>Ma ora ho tanta fame quindi il resto lo scriverò poi.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.web-magazine.it/2012/01/un-logo-non-e-un-pareo-di-donna-moderna-to-be-continued/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://www.web-magazine.it/2012/01/un-logo-non-e-un-pareo-di-donna-moderna-to-be-continued/</feedburner:origLink></item>
		<item>
		<title>Creare siti in PHP – (27) – Le sessioni e i cookie</title>
		<link>http://feedproxy.google.com/~r/web-magazine/~3/L-iQiqF0E9A/</link>
		<comments>http://www.web-magazine.it/2012/01/creare-siti-in-php-%e2%80%93-27-%e2%80%93-le-sessioni-e-i-cookie/#comments</comments>
		<pubDate>Mon, 16 Jan 2012 06:10:33 +0000</pubDate>
		<dc:creator>Federico</dc:creator>
				<category><![CDATA[scripting]]></category>
		<category><![CDATA[web design]]></category>
		<category><![CDATA[cookie]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sessioni]]></category>
		<category><![CDATA[setcookie]]></category>

		<guid isPermaLink="false">http://www.web-magazine.it/?p=2287</guid>
		<description><![CDATA[Panoramica sull'utilizzo delle sessioni e dei cookie in PHP per memorizzare dati sulla navigazione: come creare sessioni e cookie, come recuperarne i valori, come eliminarli. ]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.web-magazine.it/wp-content/uploads/2011/11/php27.jpg" alt="Le sessioni e i cookie" /></p>
<p>Con la puntata di oggi vedremo in che modo, con PHP, è possibile <strong>conservare informazioni durante la navigazione</strong>: si tratta di un aspetto <strong>molto utile </strong>soprattutto se è necessario costruire un sito web che debba consentire ai propri utenti di <strong>fare il login</strong> e di navigare le pagine in qualità di <strong>utenti registrati</strong>. Per fare questo abbiamo <strong>due strumenti a nostra disposizione</strong>: il primo è costituito dalle <strong>sessioni</strong>, il secondo dai <strong>cookie</strong>.</p>
<p><span id="more-2287"></span></p>
<h3>Le sessioni</h3>
<p>Iniziamo dalle <strong>sessioni</strong>: dobbiamo immaginare le sessioni come “contenitori” in cui possiamo inserire <strong>diverse informazioni</strong>. Queste informazioni verranno <strong>memorizzate sul server</strong> e dureranno il tempo di una&#8230; “sessione”, appunto, perché quando il browser verrà chiuso tutte queste informazioni <strong>saranno cancellate</strong>.</p>
<h3>La funzione session_start</h3>
<p><strong>PHP </strong>mette a disposizione di chiunque voglia creare una sessione <strong>la variabile superglobale $_SESSION</strong>, che funziona proprio come tutte le altre variabili superglobali di cui abbiamo già parlato nelle puntate scorse. Prima di tutto però c&#8217;è <strong>un&#8217;operazione preliminare da compiere</strong>, ovvero <strong>avviare la sessione</strong>. Lo si fa con una sezione apposita, <em>session_start</em>, che deve obbligatoriamente essere inserita <strong>prima di qualsiasi tipo di output </strong>all&#8217;interno del nostro file PHP:</p>
<p><code>&lt;?php<br />
session_start();<br />
// codice...<br />
?&gt;</code></p>
<h3>Creare sessioni</h3>
<p>La funzione <em>session_start</em> (la cui documentazione ufficiale si può trovare all&#8217;indirizzo <a href="http://php.net/manual/en/function.session-start.php">http://php.net/manual/en/function.session-start.php</a>) non solo permette di <strong>creare una sessione</strong>, ma permette anche di <strong>recuperare dati </strong>da una sessione <strong>creata in un&#8217;altra pagina</strong>. Ma come si fa a <strong>creare una sessione</strong>? Basta semplicemente <strong>utilizzare la variabile superglobale $_SESSION</strong> e <strong>associare a essa le informazioni</strong>:</p>
<p><code>$_SESSION['nome'] = "Federico";<br />
$_SESSION['id'] = "1";<br />
$_SESSION['livello'] = "3";</code></p>
<p>Ovviamente queste informazioni, nel caso di un utente che si collega al nostro sito, si possono agevolmente <strong>recuperare da un database </strong>(nell&#8217;esempio ometterò, per semplicità, la query, perché parleremo <strong>nella prossima puntata</strong> di come recuperare <strong>in modo corretto</strong> e allo stesso tempo semplice i dati immessi da un utente per fare un login):</p>
<p><code>$query = // ipotetica select per verificare i dati inseriti dall'utente<br />
$result = mysql_query($query);<br />
$numero_record = mysql_num_rows($result);<br />
if($numero_record == 1) {<br />
while($row = mysql_fetch_array($result, MYSQL_ASSOC)) {<br />
$_SESSION['id'] = $row['id'];<br />
$_SESSION['nome'] = $row['nome'];<br />
$_SESSION['livello'] = $row['livello'];<br />
}<br />
echo "Login effettuato con successo!";<br />
}</code></p>
<p>In tutte le pagine che vorremo riservare agli utenti registrati, dovremo inserire <strong>prima di qualsiasi altra cosa</strong> la funzione <em>session_start</em>: se omettessimo la funzione, la pagina non potrebbe ricevere le informazioni delle sessioni. Se per esempio con un blocco if controlliamo che l&#8217;utente sia loggato (per esempio verificando, tramite <em>isset</em>, che sia impostato il <strong>livello dell&#8217;utente </strong>a sua volta memorizzato nella variabile superglobale $_SESSION) ma allo stesso tempo <strong>dimentichiamo</strong> di inserire la funzione <em>session_start</em>, la conseguenza sarà che la pagina non conoscerà le informazioni memorizzate nella sessione e la nostra applicazione si comporterà come se l&#8217;utente <strong>non si fosse mai loggato al sito</strong>. Attenzione anche a <strong>non dichiarare due volte la funzione</strong> (spesso, includendo file nella pagina, può capitare di farlo), perché <em>session_start </em>può essere dichiarata <strong>una volta soltanto</strong>.</p>
<h3>Come azzerare o eliminare le sessioni</h3>
<p>Le sessioni possono essere poi <strong>azzerate o eliminate</strong>: per fare questo è possibile utilizzare le funzioni <em>session_unset</em> e <em>session_destroy</em>. La differenza consiste nel fatto che la prima funzione <strong>elimina soltanto i dati</strong> (senza cancellare <strong>gli elementi dell&#8217;array</strong> che abbiamo dichiarato in precedenza), la seconda invece <strong>elimina dati e array</strong>. Pertanto in seguito a<em> session_destroy </em><strong>sarà necessario dichiarare nuovamente</strong> <em>session_start</em>. Sono utili in funzioni di <strong>logout</strong> e si invocano in modo molto semplice:</p>
<p><code>session_unset();<br />
session_destroy();</code></p>
<h3>I cookie</h3>
<p>Parliamo adesso dei <strong>cookie</strong>: molti di voi li avranno già sentiti nominare. I cookie (letteralmente “biscotti”) sono <strong>informazioni </strong>che vengono inviate <strong>dal server al client</strong>: e proprio qui sta la prima differenza rispetto alle sessioni, perché queste ultime <strong>rimangono sul server</strong>. Un&#8217;altra differenza consiste nel fatto che la sessione viene <strong>cancellata</strong> nel momento in cui il browser <strong>viene chiuso</strong>: il cookie invece <strong>persiste fino alla sua scadenza</strong>, impostata quando il cookie viene creato. Data la natura dei cookie, questi ci torneranno utili se vogliamo creare un modulo di login che si <strong>“ricordi”</strong> dell&#8217;utente <strong>una volta chiuso il browser</strong>, per evitargli magari di immettere nuovamente nome e password al collegamento successivo. Un altro esempio può essere dato da <strong>un sito multilingua</strong>: se il nostro sito accoglie l&#8217;utente in italiano, ma quest&#8217;ultimo preferisce l&#8217;inglese, potrebbe rendersi necessario un cookie che <strong>si ricordi dell&#8217;impostazione settata dall&#8217;utente</strong> (ovvero “sito in lingua inglese”) <strong>ogni volta che si collega</strong>.</p>
<h3>La funzione setcookie e i suoi parametri</h3>
<p>Per creare un cookie esiste un&#8217;apposita funzione, <em>setcookie</em>, che riceve tre parametri principali: <strong>il nome del cookie</strong>, le <strong>informazioni</strong> e la <strong>durata</strong>:</p>
<p><code>setcookie("nome", "Federico", time()+3600);</code></p>
<p>La durata si imposta utilizzando la funzione <em>time</em>: quest&#8217;ultima restituisce<strong> il numero di secondi trascorsi dal 1 gennaio 1970 alle ore 00:00:00</strong>. Si tratta della data di inizio del tempo calcolato sui <strong>sistemi Unix</strong> ed è, come già detto, <strong>espresso in secondi</strong>: si intuisce quindi che al valore restituito da time bisognerà aggiungere<strong> un numero di secondi equivalente al periodo di durata </strong>del nostro cookie. Nel caso dell&#8217;esempio, 3600 secondi: significa che il cookie <strong>avrà la durata di un&#8217;ora</strong> (formata da 3600 secondi). Si intuisce quindi che è possibile settare una durata qualsiasi per il nostro cookie, <strong>anche di anni</strong>!</p>
<p><code>setcookie("nome", "Federico", time()+3600*24); //un giorno</code></p>
<p><code>setcookie("nome", "Federico", time()+3600*24*30); // un mese</code></p>
<p><code>setcookie("nome", "Federico", time()+3600*24*365); // un anno</code></p>
<p>Se invece la scadenza non viene impostata, il cookie scadrà semplicemente <strong>alla fine della sessione</strong>. La documentazione ufficiale della funzione time è disponibile all&#8217;indirizzo <a href="http://php.net/manual/en/function.time.php">http://php.net/manual/en/function.time.php</a>.</p>
<p>Quello che abbiamo visto sopra è <strong>l&#8217;esempio più tipico</strong>, ma in realtà si possono estendere a <strong>sette </strong>i parametri che la funzione setcookie può ricevere, perché oltre a nome, valore e scadenza possiamo specificare anche <strong>percorso</strong> (ovvero la directory per cui è valido il cookie), il <strong>dominio</strong> (come per il percorso, ma si estende a tutto il dominio), la <strong>sicurezza</strong> (che se settata a <em>true</em> fa in modo che il cookie venga trasmesso solo attraverso protocollo sicuro https) e <strong>httponly</strong> (funziona come la sicurezza: se settato a<em> true</em>, fa in modo che il cookie venga trasmesso solo tramite protocollo http, e di conseguenza non sarà accessibile a linguaggi di scripting come JavaScript). Per esempio:</p>
<p><code>setcookie("nome", "Federico", time()+3600, "/prova/", "web-magazine.it", true, true);</code></p>
<p>In questo caso il cookie è valido solo per la cartella “prova” del sito “web-magazine.it” (che non va scritto con “www” anteposto), si trasmette solo in presenza di una connessione sicura ed è accessibile solo al protocollo http.</p>
<p><code>setcookie("nome", "Federico", time()+3600, "/");</code></p>
<p>In questo caso invece abbiamo creato, attraverso la formula &#8220;/&#8221;, un cookie che è valido per tutte le cartelle del sito.</p>
<h3>Recuperare il valore dei cookie</h3>
<p>Per recuperare il valore di un cookie che abbiamo impostato in precedenza, sarà necessario utilizzare <strong>la variabile superglobale $_COOKIE</strong>, e il nome dell&#8217;elemento dell&#8217;array non sarà altro che<strong> il primo valore</strong> che abbiamo passato <strong>come parametro</strong> alla funzione <em>setcookie</em>:</p>
<p><code>echo $_COOKIE['nome']; // stampa “Federico”</code></p>
<p>È ovvio che possiamo anche inizializzare variabili a cui abbinare i valori delle nostre sessioni o dei nostri cookie:</p>
<p><code>$nome = $_SESSION['nome'];<br />
$cognome = $_COOKIE['cognome'];</code></p>
<p>Per poi<strong> utilizzarle comodamente</strong> all&#8217;interno del nostro codice, magari su blocchi condizionali. Tipicamente, ci si assicura che prima le variabili di sessione e i cookie siano settati tramite funzione <em>isset</em>, onde evitare di veder comparire <em>warning </em>sul sito nel caso in cui sessioni e cookie <strong>non siano ancora stati scritti </strong>(per esempio quando l&#8217;utente si è appena collegato al sito <strong>e non ha ancora fatto login</strong>).</p>
<h3>Eliminare i cookie</h3>
<p>Abbiamo visto prima come <strong>eliminare una sessione</strong>. I cookie <strong>non hanno una specifica funzione</strong> per eliminarli, ma per farlo basta semplicemente utilizzare, di nuovo, la funzione <em>setcookie</em> (a proposito, la pagina di documentazione ufficiale è <a href="http://php.net/manual/en/function.setcookie.php">http://php.net/manual/en/function.setcookie.php</a>) impostando però, come scadenza, <strong>un tempo negativo</strong>:</p>
<p><code>setcookie("nome", "Federico", time()-3600);</code></p>
<p>E così facendo <strong>avremo eliminato il nostro cookie</strong>. Sempre la solita funzione si utilizza se vogliamo <strong>modificare</strong> i valori di un cookie: basterà semplicemente invocare setcookie con i nuovi parametri.</p>
<p>E anche per oggi la puntata arriva al termine&#8230; arrivederci al prossimo episodio!!!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.web-magazine.it/2012/01/creare-siti-in-php-%e2%80%93-27-%e2%80%93-le-sessioni-e-i-cookie/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.web-magazine.it/2012/01/creare-siti-in-php-%e2%80%93-27-%e2%80%93-le-sessioni-e-i-cookie/</feedburner:origLink></item>
		<item>
		<title>Urgente: cercasi web interface designer</title>
		<link>http://feedproxy.google.com/~r/web-magazine/~3/ytFpEF92Gy4/</link>
		<comments>http://www.web-magazine.it/2011/12/2311/#comments</comments>
		<pubDate>Tue, 20 Dec 2011 09:34:59 +0000</pubDate>
		<dc:creator>Laura</dc:creator>
				<category><![CDATA[lavoro e professioni]]></category>
		<category><![CDATA[cercasi]]></category>
		<category><![CDATA[lavoro]]></category>
		<category><![CDATA[Web designer]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://www.web-magazine.it/?p=2311</guid>
		<description><![CDATA[Totalcup s.r.l. nuovo social network dedicato all'organizzazione di incontri sportivi di squadra, cerca un web interface designer da inserire nel team di sviluppo, che si occuperà del disegno e sviluppo front end, delle interfacce utente e di tutti gli aspetti legati alla usabilità e User Experience del portale.]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone" src="http://totalcup.it/images/logo.gif" alt="" width="500" /><br />
La ricerca di un web designer  e front end developer è ancora aperta, ripubblico la proposta e aspetto i vostri CV.</p>
<p><span id="more-2311"></span><br />
Se ritenete di avere le caratteristiche adatte e avete voglia di lavorare  in un ambiente giovane e stimolante inviate il vostro curriculum a <a title="invia curriculum" href="mailto:info@totalcup.com"><strong>info@totalcup.com</strong></a> e non dimenticate di citare i vostri lavori web più rappresentativi, in particolare specificate il vostro ruolo nel progetto!</p>
<h3>Cercasi web designer!</h3>
<p>Totalcup s.r.l.  nuovo social network dedicato all&#8217;organizzazione di incontri sportivi di  squadra, cerca un <strong><em>web interface designer</em></strong> da inserire nel team di sviluppo, che si occuperà del disegno e sviluppo  front end, delle interfacce utente e  di tutti gli aspetti legati alla usabilità e User Experience  del portale.</p>
<p>Si richiede  esperienza nella progettazione e disegno di layout web e conoscenza approfondita di xhtml, css e framework Javascript.</p>
<p>Il lavoro è a Napoli, full time. Non vengono prese in consiederazione candidature per telelavoro.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.web-magazine.it/2011/12/2311/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.web-magazine.it/2011/12/2311/</feedburner:origLink></item>
		<item>
		<title>E-mail Marketing</title>
		<link>http://feedproxy.google.com/~r/web-magazine/~3/aM5Zz0_LkTQ/</link>
		<comments>http://www.web-magazine.it/2011/12/e-mail-marketing/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 20:44:50 +0000</pubDate>
		<dc:creator>Dario</dc:creator>
				<category><![CDATA[SEO e Web Marketing]]></category>
		<category><![CDATA[dem]]></category>
		<category><![CDATA[email marketing]]></category>
		<category><![CDATA[mailing list]]></category>

		<guid isPermaLink="false">http://www.web-magazine.it/?p=2244</guid>
		<description><![CDATA[Inizio questo post con un’ immagine che dice moltissimo sul valore delle e-mail, e soprattutto su quanto siano usate ad oggi. Questa infografica ci fa vedere benissimo il rapporto tra: il numero degli account dei vari social network, dei siti e delle e-mail e la loro attività quotidiana, le e-mail battono tutti; con circa 3 [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.web-magazine.it/wp-content/uploads/2011/12/infographic_abs_final.jpg"><img class="alignnone size-full wp-image-2308" title="infographic_abs_final" src="http://www.web-magazine.it/wp-content/uploads/2011/12/infographic_abs_final-e1323809020858.jpg" alt="" width="500" height="486" /></a></p>
<p>Inizio questo post con un’ immagine che dice moltissimo sul valore delle e-mail, e soprattutto su quanto siano usate ad oggi.</p>
<p><span id="more-2244"></span></p>
<p>Questa infografica ci fa vedere benissimo il rapporto tra: il numero degli account dei vari social network, dei siti e delle e-mail e la loro attività quotidiana, le e-mail battono tutti; con circa 3 miliardi di utenti e 188 miliardi di attività giornaliere (intese come messaggi ).</p>
<h3>Proviamo a distinguere i vari tipi di E-mail :</h3>
<h4><strong>E-mail Personali</strong></h4>
<p>sono i tipici messaggi inviati da una persona alla seconda in modo diretto e personale</p>
<h4><strong>E-mail Transazionali</strong></h4>
<p><strong> </strong>sono i messaggi (solitamente automatici) che<strong> notificano qualcosa</strong>, ad esempio la registrazione ad un portale, solleciti, scadenze,bonifici etc . Solitamente questo tipo di e-mail non sono inviati in modo massivo .</p>
<h4><strong>E-mail pubblicitarie (DEM)</strong></h4>
<div id="_mcePaste">sono le e-mail che <strong>promuovono direttamente un prodotto</strong>, o la promozione di un’offerta su un prodotto.  Sono messaggi, solitamente molto curati graficamente e invitano l’utente a cliccare un bottone per vedere meglio i dettagli della promozione. Non sono messaggi continui, ma sono inviati con periodicità occasionale. Le e-mail pubblicitarie sono anche dette <strong>Direct e-mailing (DEM)</strong> e sono inviate in maniera massiva,a liste proprietarie dell’azienda che promuove il prodotto  oppure sono inviate a liste di proprietà di terzi (liste di terzi in affitto ).</div>
<h4><strong>Newsletter</strong></h4>
<p><strong> </strong> sono <strong>messaggi periodici</strong> che l’ azienda invia ai propri clienti o  collaboratori o a tutte quelle persone che sono interessati al prodotto o all’azienda stessa. Come detto sono comunicazioni inviati con cadenza periodica come per esempio mensile o quindicinali.</p>
<p>Le newsletter non fanno riferimento a promozioni in particolare ma sono indispensabili per mantenere viva una linea di comunicazione tra l’azienda e l’utente interessato .</p>
<p><strong>Ora che abbiamo visto le varie tipologie di messaggi, proviamo a vedere alcuni principi fondamentali dell’e-mail marketing .</strong></p>
<p>Solitamente si invia un messaggio per incrementare le vendite, incrementare gli iscritti o per coltivare la fedeltà del cliente, bisogna seguire delle strategie precise  come : dare informazioni di valore, tempestive e rilevanti in cambio di un po’ di tempo ed attenzione da parte dell’utente.</p>
<p>Il cliente è disposto a condividere con noi  alcuni dei suoi dati personali, se : la nostra pubblicità non risulta invasiva e fastidiosa, se rispettiamo la sua privacy e se riusciamo a personalizzare sempre di più i messaggi che gli inviamo.</p>
<p>Io personalmente credo che una e-mail risulti più <strong>efficace </strong>quanto più è bella graficamente e soprattutto quando non è inviata 10 volte a settimana .</p>
<p>Sicuramente molti di voi saranno iscritti ad alcune newsletter; provate a pensare qual è secondo voi la migliore e perché, io nella mia hit parade ho quella di un noto marchio giapponese di videogiochi (quella di Mario per intenderci ).</p>
<p>Nei commenti inviatemi le vostre .</p>
<p>In commercio esistono molte società che vendono dei pannelli per newsletter molto efficaci per l’invio di grosse quantità di e-mail. Basta fare una ricerca su un motore di ricerca e se ne trovano davvero tanti .</p>
<p>E’ fondamentale usare <strong>software/pannelli </strong> appositi per newsletter, e non fare invii con outlook  (questo per non violare le regole,sempre più severe, antispam dei server ), i vari software o pannelli online, oltre ad avere plugin particolari come per esempio :  gestioni delle liste di e-mail, anteprima delle e-mail e in alcuni casi anteprime delle varie e-mail dei riceventi (per esempio yahoo, hotmail, gmail etc è molto importante per vedere se il layout si apre bene su tutti i vari browser) e naturalmente <em>unscribe </em>molto veloce da parte dell’utente e dei servizi che servono a vedere se il messaggio ha una buona probabilità o meno di finire nei vari filtri antispam .</p>
<p>Mi raccomando: se superate 50-100 e-mail per invio non usate il vostro client o provider per mandare le e-mail, se alcune filtri vi inseriscono nell’antispam diventa un problema per il vostro dominio e per la vosta reputazione online.</p>
<p>Una delle principali critiche che ricevo dai clienti è : perché devo pagare un servizio di newsletter, visto che l’e-mail è gratis ?</p>
<p>Nelle righe precedenti ho provato a spiegarlo, oltre a tutti i <strong>vantaggi</strong> nell’usare prodotti creati apposta per inviare newsletter, è fondamentale non finire nelle <strong>black list</strong> dei servizi antispam .</p>
<h3>Come costruire una lista di indirizzi</h3>
<p>Diciamo subito che <strong>acquistare migliaia di indirizzi </strong>(anche se ben profilati dalla società da cui li acquistiamo) non ha un gran ritorno (rispetto all’investimento ). Le e-mail ben profilate costano e l’apertura del messaggio non è sempre scontata da persone che non conoscono il nostro brand o i nostri prodotti.</p>
<p>Questo è sempre un discorso particolare, se mandate 2 milioni di e-mail sicuramente dei risultati li avrete e sicuramente venderete i vostri prodotti e servizi, ma bisogna vedere quanto costano 2 milioni di e-mail  e soprattutto è molto alta la possibilità che siano utenti/clienti  una “tantum” e non clienti selezionati e affiliati.</p>
<p>La soluzione migliore è costruirsi il proprio database di propri utenti, un primo consiglio è inserire un piccolo spazio nel proprio sito, dove inserire un box con “<strong>Iscriviti alla newsletter</strong>” . Ricordatevi di inserire <strong>l’autorizzazione al trattamento dei dati</strong> perché come tutti saprete, l’indirizzo di posta elettronica è un dato personale, in base alle norme sul trattamento dei dati , l’interessato ha tutto il diritto ad opporsi al trattamento dei dati che lo riguardano.</p>
<p>Detto questo, ci sono ormai moltissime aziende che fanno confermare un link inviato alla propria mail , solo dopo la conferma dell’iscrizione inseriscono l’ e-mail nel proprio database. Questo metodo a molti sembra complicato e fa perdere delle iscrizioni, ma sei davvero sicuro ti serva un’ utente che non apre la casella di posta e non sa cliccare un link ?</p>
<p>Un secondo consiglio, ben più complicato del primo è di realizzare campagne pubblicitarie, a misura del proprio business/prodotto e realizzare delle landing page .</p>
<p>Delle buone <strong>landing page</strong> o meglio delle<strong> squeeze page</strong> (che sono delle particolari pagine di arrivo che hanno come unico obiettivo, la raccolta dell’indirizzo e-mail) sono capaci di popolare un database di e-mail , molto in fretta e, cosa davvero più importante , le e-mail sono profilate sulle richieste  dell’azienda .</p>
<p>Nel prossimo post vorrei completare questo argomento con : “come creare messaggi e-mail efficaci&#8221;e se avete altre curiosità sulle e-mail marketing, chiedetelo nei commenti</p>
<p>Dario</p>
]]></content:encoded>
			<wfw:commentRss>http://www.web-magazine.it/2011/12/e-mail-marketing/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.web-magazine.it/2011/12/e-mail-marketing/</feedburner:origLink></item>
		<item>
		<title>Creare siti in PHP – (26) – Costruiamo un form di ricerca con PHP/MySQL</title>
		<link>http://feedproxy.google.com/~r/web-magazine/~3/JgFPmD6ZaLY/</link>
		<comments>http://www.web-magazine.it/2011/11/creare-siti-in-php-%e2%80%93-26-%e2%80%93-costruiamo-un-form-di-ricerca-con-phpmysql/#comments</comments>
		<pubDate>Mon, 28 Nov 2011 06:00:46 +0000</pubDate>
		<dc:creator>Federico</dc:creator>
				<category><![CDATA[scripting]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.web-magazine.it/?p=2253</guid>
		<description><![CDATA[In questo episodio impariamo a costruire un semplicissimo form di ricerca per eseguire ricerche all'interno del nostro database. Impariamo l'utilizzo dell'operatore LIKE e della specifica ESCAPE.]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.web-magazine.it/wp-content/uploads/2011/11/php26.jpg" alt="Costruiamo un form di ricerca con PHP/MySQL" /></p>
<p>Con la puntata di oggi metteremo in pratica i concetti appresi negli ultimi episodi della guida e vedremo come costruire un semplice<strong> form di ricerca PHP/MySQL</strong> per fare ricerche all&#8217;interno del nostro blog. Come sempre, in occasione di puntate “pratiche”, faremo un ripasso generale degli ultimi concetti ma introdurremo anche qualcosa di nuovo.</p>
<p><span id="more-2253"></span></p>
<h3>Costruiamo il form</h3>
<p>Allora, iniziamo a costruire il nostro form, in maniera molto semplice, come siamo abituati:</p>
<p><code>&lt;form name="ricerca" action="ricerca.php" method="post"&gt;<br />
&lt;input type="text" name="cerca" /&gt;<br />
&lt;input type="submit" name="vai" value="Cerca!" /&gt;<br />
&lt;/form&gt;</code></p>
<p>Si tratta, come vedete, di un semplicissimo<strong> form con metodo post </strong>che rimanda a una pagina “ricerca.php”. Il nostro form ha un campo, che servirà all&#8217;utente per <strong>immettere il testo da ricercare</strong>, e un <strong>bottone per inviare i dati</strong>.</p>
<p>Nel costruire la pagina “ricerca.php”, come prima cosa assicuriamoci di <strong>fare un controllo sul pulsante</strong>: se è stato premuto, quindi se l&#8217;utente <strong>proviene dalla pagina del form</strong>, <strong>sarà eseguito il codice</strong>, e in caso contrario (se per esempio l&#8217;utente arriva alla pagina ricerca.php semplicemente digitandola nella barra degli indirizzi) <strong>non dovrà succedere alcunché</strong>. Vediamo:</p>
<p><code>if(isset($_POST['vai'])) {<br />
// codice<br />
// codice<br />
// codice<br />
}<br />
else {<br />
}</code></p>
<h3>Iniziamo a riempire la pagina dei risultati&#8230;</h3>
<p>Vediamo ora come <strong>riempire il blocco if</strong>. Per prima cosa dobbiamo decidere se la ricerca riguarderà <strong>soltanto i post o i commenti</strong>. Noi vedremo tre esempi: il primo <strong>per i post</strong>, il secondo <strong>per i commenti</strong> e il terzo <strong>per entrambi</strong>.</p>
<p>Iniziamo dalla ricerca nei soli post. Per prima cosa stampiamo una scritta per indicare all&#8217;utente che <strong>la ricerca è stata compiuta </strong>e quindi inizializziamo una variabile, a cui <strong>assoceremo la parola cercata</strong>:</p>
<p><code>echo "Ecco i risultati della tua ricerca:&lt;br /&gt;&lt;br /&gt; ";<br />
$parolacercata = $_POST['cerca'];</code></p>
<p>Fatto questo è arrivato il momento di creare la nostra query per la ricerca all&#8217;interno della base di dati:</p>
<p><code>$query = "SELECT * FROM Post WHERE Titolo LIKE '%$parolacercata%' OR TestoHTML LIKE '%$parolacercata%'";</code></p>
<h3>L&#8217;operatore LIKE e i suoi utilizzi</h3>
<p>Bene, vedete che abbiamo <strong>due “novità”</strong>: la prima è <strong>l&#8217;operatore LIKE</strong>, e la seconda sono <strong>i due simboli di percentuale </strong>prima e dopo la variabile. Procediamo con ordine.</p>
<p>LIKE è <strong>un operatore di confronto</strong>, come l&#8217;uguale, il maggiore, il minore e tutti gli altri. Funziona <strong>più o meno come l&#8217;operatore di uguaglianza</strong>, ma con <strong>una differenza molto significativa</strong>: con l&#8217;uguale avremmo cercato la parola precisa, invece con LIKE eseguiamo una ricerca <strong>“non precisa”</strong>. I due caratteri di percentuale prima e dopo la variabile della parola cercata servono infatti per dare una <strong>“connotazione”</strong> all&#8217;operatore LIKE, nel senso che immettendolo <strong>prima della variabile</strong>, dichiariamo che <strong>potrebbero esserci altri caratteri prima della parola che abbiamo cercato</strong>, e invece immettendolo dopo non facciamo altro che dichiarare che potrebbero esserci altri caratteri <strong>subito dopo</strong>.</p>
<p>Ma vediamo un esempio concreto. Supponiamo di avere tre post, il primo che si intitola “Ciao”, il secondo che si intitola “Ciao a tutti!” e il terzo “Un ciao ai miei amici!”. E supponiamo anche di avere alcune <strong>query di ricerca</strong> (per semplicità operiamo soltanto sul titolo):</p>
<p><code>$query = "SELECT * FROM Post WHERE Titolo = '$parolacercata'";</code></p>
<p><code>$query = "SELECT * FROM Post WHERE Titolo LIKE '$parolacercata'";</code></p>
<p><code>$query = "SELECT * FROM Post WHERE Titolo LIKE '%$parolacercata'";</code></p>
<p><code>$query = "SELECT * FROM Post WHERE Titolo LIKE '$parolacercata%'";</code></p>
<p><code>$query = "SELECT * FROM Post WHERE Titolo LIKE '%$parolacercata%'";</code></p>
<p>Supponiamo adesso di cercare la parola “ciao”. Vediamo i risultati per i cinque casi che abbiamo elencato sopra:</p>
<ul>
<li><em>Caso 1</em>: viene 	trovato <strong>soltanto il post intitolato “Ciao”</strong>, perché 	abbiamo chiesto informazioni precise, ovvero i post il cui titolo è 	<strong>esattamente uguale alla parola cercata</strong> (maiuscole e minuscole 	non contano perché <strong>SQL non è case sensitive </strong>come abbiamo 	avuto già modo di rimarcare);</li>
<li><em>Caso 2</em>: <strong>è 	del tutto equivalente</strong> al caso 1 (quindi <strong>è praticamente 	inutile usare LIKE da solo</strong>);</li>
<li><em>Caso 3</em>: 	vengono trovati i post che contengono la parola cercata <strong>anche se 	ci sono caratteri che la precedono</strong>. Nel nostro caso troviamo 	soltanto “Ciao”, perché è vero che il post “Un ciao ai miei 	amici!” ha la parola “ciao” preceduta da altri caratteri, ma è 	anche seguita da un&#8217;altra sequenza (“ ai miei amici”), quindi 	<strong>non soddisfa i requisiti di ricerca</strong>. Se avessimo avuto un 	post intitolato “Un ciao”, sarebbe stato restituito come 	risultato;</li>
<li><em>Caso 4</em>: <strong>il 	contrario del precedente</strong>, vengono trovati “Ciao” e “Ciao a 	tutti!”. Abbiamo infatti cercato i record dove il campo titolo 	contiene la parola cercata ma <strong>può anche contenere una stringa di 	caratteri dopo</strong>. “Ciao” e “Ciao a tutti!” soddisfano 	questa condizione;</li>
<li><em>Caso 5</em>: 	vengono trovati tutti e tre i post, dal momento che abbiamo detto di 	estrarre i record il cui campo titolo contiene la parola cercata, 	che può essere <strong>o preceduta o seguita da altre sequenze di 	caratteri</strong>.</li>
</ul>
<p>Possiamo poi anche fare <strong>ricerche “negative”</strong>:</p>
<p><code>$query = "SELECT * FROM Post WHERE Titolo NOT LIKE '%$parolacercata%'";</code></p>
<p>In questo caso, anteponendo quindi <strong>la parola NOT all&#8217;operatore LIKE</strong>, la nostra interrogazione fa in modo che vengano estratti i post il cui titolo<strong> non contiene la parola cercata</strong>, preceduta o seguita da altre stringhe di caratteri. E poi abbiamo anche un altro carattere speciale, l&#8217;<strong>underscore</strong>:</p>
<p><code>$query = "SELECT * FROM Post WHERE Titolo LIKE '_$parolacercata_'";</code></p>
<p>In questo caso la nostra interrogazione estrae tutti i post che contengono la parola cercata, <strong>preceduta o seguita da un solo carattere</strong>: pertanto, se il carattere di percentuale equivale a <strong>“qualsiasi numero di caratteri”</strong>, l&#8217;underscore equivale a<strong> “un solo carattere”</strong>.</p>
<h3>La specifica ESCAPE</h3>
<p>Potremmo però voler cercare una parola che sia <strong>effettivamente preceduta da un underscore</strong>, e quindi non volerlo considerare come carattere speciale. In questo caso dovremo scrivere questo:</p>
<p><code>$query = "SELECT * FROM post WHERE Titolo NOT LIKE '_$parolacercata' ESCAPE";</code></p>
<p>Aggiungendo <strong>la specifica ESCAPE</strong> facciamo capire che quello che precede la variabile cercata è un vero underscore e non un carattere speciale.</p>
<p>Bene, una volta inviata la nostra interrogazione possiamo procedere con la stampa:</p>
<p><code>while ($record = mysql_fetch_array($risultato, MYSQL_ASSOC)) {<br />
echo $record['Titolo']; echo "&lt;br /&gt;";<br />
}</code></p>
<h3>Riepiloghiamo&#8230;</h3>
<p>In questo caso stampiamo soltanto il titolo, ma possiamo decidere a piacere come far apparire all&#8217;utente il risultato della nostra ricerca. Quindi riepiloghiamo tutto il codice della pagina “ricerca.php”:</p>
<p><code>if(isset($_POST['vai'])) {<br />
echo "Ecco i risultati della tua ricerca:&lt;br /&gt;&lt;br /&gt; ";<br />
$parolacercata = $_POST['cerca'];<br />
$query = "SELECT * FROM post WHERE Titolo NOT LIKE '%$parolacercata%'";<br />
$risultato = mysql_query($query);<br />
while ($record = mysql_fetch_array($risultato, MYSQL_ASSOC)) {<br />
echo $record['Titolo']; echo "&lt;br /&gt;";<br />
}<br />
}<br />
else {<br />
}</code></p>
<p>E anche per oggi è tutto&#8230; vi aspetto alla prossima!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.web-magazine.it/2011/11/creare-siti-in-php-%e2%80%93-26-%e2%80%93-costruiamo-un-form-di-ricerca-con-phpmysql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.web-magazine.it/2011/11/creare-siti-in-php-%e2%80%93-26-%e2%80%93-costruiamo-un-form-di-ricerca-con-phpmysql/</feedburner:origLink></item>
		<item>
		<title>Creare siti in PHP – (25) – Operazioni sul database: funzioni aggregate e query annidate</title>
		<link>http://feedproxy.google.com/~r/web-magazine/~3/gtSBf_MX3kU/</link>
		<comments>http://www.web-magazine.it/2011/11/creare-siti-in-php-%e2%80%93-25-%e2%80%93-operazioni-sul-database-funzioni-aggregate-e-query-annidate/#comments</comments>
		<pubDate>Thu, 24 Nov 2011 06:00:23 +0000</pubDate>
		<dc:creator>Federico</dc:creator>
				<category><![CDATA[scripting]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.web-magazine.it/?p=2249</guid>
		<description><![CDATA[Ultima puntata sulle operazioni sul database. Impariamo alcune funzioni aggregate (COUNT, SUM, AVG, MAX e MIN) e impariamo a eseguire query annidate.]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.web-magazine.it/wp-content/uploads/2011/11/php25.jpg" alt="Funzioni aggregate e query annidate" /></p>
<p>Terminiamo il nostro panorama sulle <strong>operazioni </strong>che si possono fare sul <strong>database </strong>parlando oggi di <strong>funzioni aggregate </strong>e di <strong>query annidate</strong>. Iniziamo dalle prime, dette anche <strong>“funzioni di aggregazione”</strong>: si tratta di una serie di <strong>funzioni </strong>che il linguaggio <strong>SQL</strong> ci mette a disposizione per estrarre <strong>diversi tipi di informazione</strong> dal nostro database, perlopiù di tipo <strong>statistico</strong>.</p>
<p><span id="more-2249"></span></p>
<h3>La funzione COUNT</h3>
<p>Supponiamo, per esempio, di voler creare una pagina all&#8217;interno della quale inserire una serie di statistiche relative al nostro blog. Potremmo iniziare dal <strong>numero complessivo</strong> dei post presenti nel blog (e quindi nel database). Come fare per sapere quanti sono? Utilizziamo la funzione aggregata <strong>COUNT</strong>, che invocheremo sulla tabella dando un <strong>nome al risultato</strong> che verrà estratto tramite la clausola <strong>AS</strong>. Vediamo la sintassi:</p>
<p><code>$query = "SELECT COUNT(*) AS TotalePost FROM Post";<br />
$risultato = mysql_query($query);</code></p>
<p>Tutte le funzioni devono essere invocate dopo il comando <strong>SELECT</strong>. Nel nostro caso, invochiamo la funzione COUNT <strong>su tutti i campi </strong>(*) e quindi chiamiamo il risultato TotalePost. Possiamo poi stampare il tutto come abbiamo visto finora:</p>
<p><code>while ($record = mysql_fetch_array($risultato, MYSQL_ASSOC)) {<br />
echo "Totale post presenti nel blog: "; echo $record['TotalePost'];<br />
}</code></p>
<h3>La funzione SUM</h3>
<p>Supponiamo invece di voler conoscere il <strong>numero totale dei commenti</strong> ma <strong>senza operare </strong>sulla tabella <em>Commenti</em>: vogliamo utilizzare un campo <em>NumCommenti </em>della tabella <em>Post </em>in cui avremo inserito il numero di commenti per ogni singolo post. In questo caso ci sarà di aiuto la funzione <strong>SUM</strong>, che, come si può intuire dal nome, esegue la <strong>somma dei valori dei record</strong>. Supponiamo di avere quattro post: il primo ha dodici commenti, il secondo cinque, il terzo nove e il quarto quindici per un totale di quarantuno commenti.</p>
<p>La sintassi è del tutto simile a quella di COUNT. Invochiamo SUM subito dopo il comando SELECT, tra parentesi indichiamo <strong>il campo che ci interessa</strong> (ovvero il campo i cui valori saranno sommati tra di loro), diamo un nome al risultato e selezioniamo la tabella:</p>
<p><code>$query2 = "SELECT SUM(NumCommenti) AS TotaleCommenti FROM Post";<br />
$risultato2 = mysql_query($query2);<br />
while ($record2 = mysql_fetch_array($risultato2, MYSQL_ASSOC)) {<br />
echo "Totale commenti presenti nel blog: "; echo $record2['TotaleCommenti'];<br />
}</code></p>
<h3>La funzione AVG</h3>
<p>A questo punto potrebbe essere interessante sapere qual è <strong>il numero medio di commenti</strong> ai post del nostro blog (nel nostro caso è 10,25). Abbiamo anche una funzione per conoscere la media: si tratta di <strong>AVG</strong> (dall&#8217;inglese “average” che significa “media”) e il meccanismo è identico a quello di SUM. Vediamo:</p>
<p><code>$query3 = "SELECT AVG(NumCommenti) AS MediaCommenti FROM Post";<br />
$risultato3 = mysql_query($query3);<br />
while ($record3 = mysql_fetch_array($risultato3, MYSQL_ASSOC)) {<br />
echo "Media commenti ai post: "; echo $record3['MediaCommenti'];<br />
}</code></p>
<h3>Le funzioni MAX e MIN</h3>
<p>Non è cambiato niente, se non la funzione invocata subito dopo il comando SELECT. Potremmo poi voler conoscere qual è il numero dei commenti del <strong>post con il maggior numero di commenti</strong> e al contrario qual è il numero di commenti del <strong>post con il minor numero di commenti</strong>. Per compiere queste due operazioni abbiamo le funzioni <strong>MAX </strong>e <strong>MIN</strong>, e anche in questi due casi il meccanismo è simile a quello delle funzioni che abbiamo appena visto. Diamo un&#8217;occhiata a MAX:</p>
<p><code>$query4 = "SELECT MAX(NumCommenti) AS Massimo FROM Post";<br />
$risultato4 = mysql_query($query4);<br />
while ($record4 = mysql_fetch_array($risultato4, MYSQL_ASSOC)) {<br />
echo "Numero commenti massimo: "; echo $record4['Massimo'];<br />
}</code></p>
<p>E adesso MIN:</p>
<p><code>$query5 = "SELECT MIN(NumCommenti) AS Minimo FROM Post";<br />
$risultato5 = mysql_query($query5);<br />
while ($record5 = mysql_fetch_array($risultato5, MYSQL_ASSOC)) {<br />
echo "Numero commenti minimo: "; echo $record5['Minimo'];<br />
}</code></p>
<h3>Le query annidate</h3>
<p>Ma cosa dovremmo fare se volessimo sapere <strong>qual è il post con il maggior numero di commenti</strong> (e quindi non solo qual è il numero di commenti del post con il maggior numero di commenti)? Dobbiamo ricorrere a una <strong>query annidata</strong>, detta anche <strong>“subquery”</strong>: le query annidate sono <strong>interrogazioni che si trovano all&#8217;interno di altre interrogazioni</strong>. Il caso che prendiamo in esame noi è <strong>il più semplice</strong>: una interrogazione viene posta come <strong>condizione della clausola WHERE</strong>. Vediamo come funziona:</p>
<p><code>$query6 = "SELECT Titolo FROM Post WHERE NumCommenti = (SELECT MAX(NumCommenti) FROM Post)";<br />
$risultato6 = mysql_query($query6);</code></p>
<p>Fino al WHERE quindi <strong>niente di strano</strong>: dopo l&#8217;uguale però inseriamo <strong>un nuovo comando SELECT</strong>, che dovrà estrarre <strong>il numero massimo di commenti presenti in un post</strong>. La query “più grande” estrarrà quindi il titolo il cui numero di commenti sarà uguale al massimo numero di commenti per un post presenti nel nostro database. Stampiamo poi molto semplicemente così:</p>
<p><code>while ($record6 = mysql_fetch_array($risultato6, MYSQL_ASSOC)) {<br />
echo "Post con il maggior numero di commenti: "; echo $record6['Titolo'];<br />
}</code></p>
<p>Ripetiamo la stessa cosa anche per conoscere il post con il minor numero di commenti. Possiamo poi creare dei comandi SELECT che <strong>estraggono informazioni dai risultati di altri comandi SELECT</strong>, come in questo caso:</p>
<p><code>$query = "SELECT * FROM (SELECT * FROM Post WHERE Id &gt; 5) AS PrimaSelect WHERE NumCommenti &gt; 6";<br />
$risultato = mysql_query($query);</code></p>
<p>Che è una complicazione inutile in quanto avremmo ottenuto lo stesso risultato con un solo comando SELECT, ma è utile per capire il meccanismo delle query annidate. In questo caso selezioniamo tutti i risultati tratti a loro volta dai risultati di una prima selezione, che dovrà obbligatoriamente essere nominata (AS PrimaSelect), altrimenti la query non funzionerà e ci sarà un errore. La prima selezione, quella interna, estrae tutti i record dalla tabella <em>Post </em>che hanno un id maggiore di 5, e da questa selezione, il comando SELECT principale estrae i post che hanno più di sei commenti.</p>
<h3>L&#8217;esercizio di oggi</h3>
<p>Vi lascio come sempre con un esercizio: create una query che esegua la somma di tutti i commenti presenti nel database escludendo però il post con il maggior numero di commenti. Alla prossima!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.web-magazine.it/2011/11/creare-siti-in-php-%e2%80%93-25-%e2%80%93-operazioni-sul-database-funzioni-aggregate-e-query-annidate/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://www.web-magazine.it/2011/11/creare-siti-in-php-%e2%80%93-25-%e2%80%93-operazioni-sul-database-funzioni-aggregate-e-query-annidate/</feedburner:origLink></item>
	</channel>
</rss>

