Guida di PHP (base), Stringhe

Continuiamo il nostro discorso sulle variabili parlando di un altro tipo fondamentale del PHP. Il tipo stringa. Come di consueto, esiste una pagina del manuale PHP che descrive nel dettaglio gli argomenti che introdurremo in questo capitolo, e che è sempre bene tenere sotto mano e consultare in caso di dubbi.

In informatica, in generale, quando si parla di stringhe ci si riferisce genericamente a dei "pezzi" di testo qualsiasi, e in PHP una stringa è esattamente questo: una sequenza di caratteri, come quella che vediamo in questo esempio:

<?php
	$s = "Ciao, io sono una stringa!";
	echo $s;
?>

Notiamo che l'istruzione echo, che fino ad ora eravamo abituati a usare scrivendo direttamente il testo da stampare, ora stampa il contenuto della variabile $s. Una variabile stringa (es. $s) infatti sostituisce in tutto e per tutto una costante stringa (es. "Hello, world!"): PHP le tratterà esattamente allo stesso modo.

Stringhe e tipi dinamici

Come abbiamo già visto con le variabili numeriche, una delle caratteristiche del PHP è la capacità di adattare il tipo di una variabile a seconda dell'uso che se ne fa (una caratteristica che in informatica si chiama tipizzazione dinamica). Questo vale anche per le stringhe, e lo possiamo verificare cercando, ad esempio, di stampare un numero intero:

<?php
	$n = 42;    // Una variabile di tipo 'integer'. PHP riconosce il tipo dal fatto
	            // che 42 è un numero intero.
	            
	$s = "42";  // Una variabile di tipo 'string'. Stavolta PHP riconosce una
	            // stringa, perchè "42" è tra virgolette.

	echo $s;    // È la normale stampa di una stringa.
	
	echo $n;    // Non dovrebbe funzionare, perchè 'echo' si aspetta una stringa...
	            // ...invece funziona, perchè PHP adatta i tipi automaticamente!
?>

In questo esempio, come vediamo dai commenti, stiamo usando una variabile di tipo intero ($n) come argomento dell'istruzione echo (linea 10). In PHP questo è perfettamente lecito, e si può fare tranquillamente; al contrario, nella maggior parte degli altri linguaggi di programmazione produrrebbe un errore, perchè echo si aspetta di ricevere una stringa, e invece si ritrova un numero.

Soffermiamoci un attimo sulla differenza tra i due casi: è normale pensare che non ci sia una gran differenza tra 42 e "42" (con le virgolette). Agli occhi di un computer, però, 42 e "42" sono due cose completamente diverse:

  • $n = 42 (senza virgolette) è un numero intero. Significa, a grandi linee, che il computer memorizza il corrispondente binario di 42 (101010) in una cella di memoria RAM. Questo "oggetto" memorizzato è un numero vero e proprio, che potrà essere passato così com'è al processore per effettuare operazioni matematiche.
  • $s = "42" (con le virgolette) è una stringa. Significa che il computer occuperà diverse celle di memoria RAM per memorizzare i singoli caratteri che compongono il numero 42: una cella per il '4' (che è il carattere numero 52 della tabella ASCII, quindi la cella conterrà 110100, 52 in binario) e una per il due (carattere numero 50 della tabella ASCII, quindi 110010 in binario). Questi codici che vengono memorizzati non hanno nessun senso dal punto di vista numerico, ma servono solo a identificare i caratteri che compongono il numero 42.

Abbiamo visto quindi che le due variabili $n e $s dell'esempio contengono due cose completamente diverse se andiamo a guardare cosa succede in memoria ($n memorizza 00101010, $s memorizza 00110100 00110010). Come però abbiamo già accennato, questo discorso lo facciamo ora per capire la differenza tra i due tipi di dato, ma non ci servirà più, almeno in questa guida: PHP infatti è fatto per convertire automaticamente le variabili da un tipo all'altro quando è necessario, in modo che il programmatore non se ne debba preoccupare.

Questo l'abbiamo visto nell'esempio qui sopra, dove abbiamo stampato un numero intero come se fosse una stringa, ma naturalmente vale anche il contrario: possiamo fare delle operazioni matematiche con le stringhe, trattandole quindi come se fossero numeri:

<?php
	$s = "42";        // Una variabile di tipo 'string'.
	
	$n = $s*2;        // A questo punto PHP converte $s in un numero intero per
	                  // effettuare l'operazione.
	            
	echo gettype($n); // Stampa 'integer', perchè $n è a tutti gli effetti
	                  // un numero (42*2, ovvero 84)
?>

Definire una stringa

I doppi apici, che abbiamo utilizzato finora, non sono in realtà l'unico modo per definire le stringhe. PHP mette a disposizione quattro modi diversi per raggiungere lo stesso obbiettivo:

  • doppi apici
  • apici singoli
  • sintassi "heredoc"
  • sintassi "nowdoc"

Doppi apici

Abbiamo già visto come usare i doppi apici per definire una stringa in PHP:

<?php
	echo "Hello, world!";
?>

Non abbiamo però parlato di alcune particolari caratteristiche di questa sintassi. Ad esempio, due o più stringhe possono essere concatenate usando il carattere punto (.), come mostrato nell'esempio seguente:

<?php
	$s1 = "porta";
	$s2 = "matite";
	
	$s  = $s1.$s2;     // $s contiene 'portamatite'
?>

La concatenazione, come tutte le altre operazioni sulle stringhe, può essere effettuata, oltre che sulle variabili, anche sulle costanti; questo può servire per inserire variabili in mezzo al testo, o per "spezzare" linee di testo troppo lunghe:

<?php
	$s  = "una variabile";
	
	echo "In mezzo al testo inserisco ".$s;
	// stampa: 'In mezzo al testo inserisco una variabile'
	
	echo "Questa linea di testo è troppo lunga... ".
	     "quindi la spezzo in due!";
	// stampa: 'Questa linea di testo è troppo lunga... quindi la spezzo in due!'
?>

Una particolarità dei doppi apici è la possibilità di inserire delle variabili direttamente nel testo, senza bisogno di usare la concatenazione:

<?php
	$s  = "una variabile";
	
	echo "In mezzo al testo inserisco ".$s; // Variabile inserita con la concatenazione

	echo "In mezzo al testo inserisco $s";  // Stesso risultato, senza concatenazione
?>

Ogni volta che inseriamo il simbolo del dollaro ($) in mezzo al testo, quindi, PHP andrà a cercare la variabile corrispondente ai caratteri che seguono il dollaro. A volte PHP non può distinguere correttamente il nome di una variabile; in questo caso si usano le parentesi graffe, come mostrato in questo esempio:

<?php
	$s = "tre";
	
	echo "Trenta$s"            // Ok: stampa 'Trentatre'
	echo "Trenta$s $sntini";   // Non funziona: PHP cerca una variabile di nome
	                           // $sntini...
	echo "Trenta$s {$s}ntini"; // Ok: stampa 'Trentatre trentini'
	echo "Trenta$s ${s}ntini"; // Ok: stampa 'Trentatre trentini'
?>

L'ultima caratteristica interessante dei doppi apici riguarda i caratteri speciali. Infatti, esistono specifiche combinazioni di caratteri (dette anche sequenze di escape) che iniziano sempre con un back-slash (\), e permettono di inserire simboli particolari nel testo. La seguente tabella mostra i più importanti (l'elenco completo si trova, come al solito, nel manuale di PHP):

Sequenza di escape Significato
\n A capo. Nota: gli 'a capo' riguardano il codice HTML della pagina che PHP sta producendo; sono importanti per rendere leggibile il codice HTML, ma non dimentichiamo che non verranno visualizzati nel browser (per quello dovremmo usare appositi tag HTML come, ad esempio, <br />).
\" Stampa i doppi apici. Notare che senza il back-slash i doppi apici verrebbero scambiati per la fine della stringa (es. echo "Ho incontrato Gianni e gli ho detto "Ciao!""; produce un errore, perchè PHP scambia l'apertura delle virgolette, prima della parola Ciao, per la fine della stringa; al contrario, echo "Ho incontrato Gianni e gli ho detto \"Ciao!\""; funziona correttamente).
\$ Stampa il segno del dollaro. Notare che senza il back-slash il dollaro verrebbe scambiato per l'inizio di una variabile, come abbiamo visto nel paragrafo precedente.
\\ Stampa un back-slash.

Apici singoli

In PHP le stringhe possono anche essere delimitate da apici singoli:

<?php
	echo "Hello, world!";    // Stampa di una stringa con apici doppi
	echo 'Hello, world!';    // Stesso risultato, ma con apici singoli.
?>

Anche se apici singoli e apici doppi si usano esattamente allo stesso modo, le due notazioni non sono del tutto equivalenti: possiamo vedere gli apici singoli come una versione ridotta di quelli doppi. Infatti, gli apici singoli non permettono di inserire variabili o caratteri speciali nel testo: il contenuto della stringa viene stampato così com'è.

Le stringhe tra apici singoli, quindi, sono svantaggiose quando si tratta di usare variabili e caratteri speciali, ma hanno anche un lato positivo: sono più veloci, perchè l'interprete PHP stampa la stringa così com'è, e quindi non deve perdere tempo a cercare variabili e caratteri speciali nel testo (in gergo si dice che non viene effettuato il parsing della stringa).

È importante ricordare che la concatenazione con gli apici singoli funziona esattamente come abbiamo visto per gli apici doppi. Inserire una variabile nel testo è sempre possibile, quindi, a patto di usare la concatenazione:

<?php
	$s = "una variabile";
	
	echo 'Inserisco '.$s.' tra apici singoli';
	// Stampa: Inserisco una variabile tra apici singoli
	
	echo 'Inserisco $s tra apici singoli';
	// Stampa: Inserisco $s tra apici singoli
	// PHP non riconosce la variabile $s. La riconoscerebbe, se fosse tra doppi apici.
?>

Inoltre, non è del tutto vero che non esistono caratteri speciali tra apici singoli: ne esiste uno, l'apice singolo stesso.

Sequenza di escape Significato
\' Un apice singolo.

Questa sequenza di escape è essenziale quando vogliamo inserire un apostrofo nel testo. Ad esempio, il seguente codice non è corretto:

<?php
	echo 'Quando serve, uso l'apostrofo';    // Errore! PHP interpreta l'apostrofo 
	                                         // come la chiusura della stringa. 
?>

L'errore può essere facilmente corretto inserendo un back-slash prima dell'apostrofo:

<?php
	echo 'Quando serve, uso l\'apostrofo';    // Ok: il back-slash fa sì che
	                                          // PHP tratti l'apostrofo come un
	                                          // qualsiasi altro carattere.
?>

Sintassi "heredoc"

Sebbene apici e doppi apici siano i modi più comunemente usati per delimitare le stringhe in PHP, questo linguaggio ne mette a disposizione di altri. Un esempio è la sintassi heredoc, che risulta comoda quando il testo da scrivere si estende su più righe:

<?php
	$s = <<<EOT
In questo spazio posso
scrivere quello che voglio
andando a capo, se serve...
EOT;

	echo $s;
?>

La sintassi heredoc (dall'inglese Here document) è nata nel mondo Unix qualche decina di anni fa, per consentire ai programmatori di inserire in libertà lunghi frammenti di testo nel loro codice. Cerchiamo di capire come funziona:

  • La stringa è aperta alla linea 2. Notiamo che, al posto dei soliti apici, si trova il codice <<<EOT
    • <<< è il "segnale" grazie a cui l'interprete PHP capisce che sta per essere definita una stringa heredoc.
    • EOT è un identificatore che può essere scelto a piacimento dal programmatore. Questo stesso codice dovrà essere usato per chiudere la stringa. Nell'esempio è stato usato il codice EOT (che sta per End Of Transmissions, "Fine delle trasmissioni" in italiano); questo dice all'interprete di trattare tutto il testo che segue come una stringa, finchè non viene incontrato di nuovo il codice EOT (il che avverrà alla linea 6).
    Dopo l'apertura di una stringa heredoc, è necessario andare a capo.
  • Le linee 3, 4 e 5 contengono il testo vero e proprio che sarà memorizzato nella variabile $s.
  • La linea 6, come abbiamo accennato, è la chiusura della stringa. Le cose da notare sono due:
    1. Il codice di chiusura può essere scelto a piacere, a patto che, come abbiamo detto, sia lo stesso usato nell'apertura della stringa (linea 2, nell'esempio).
    2. Il codice di chiusura (EOF, nell'esempio) deve essere essere posizionato all'inizio della riga. Nessun carattere può precedere il codice, nemmeno spazi bianchi o tabulazioni.
  • La linea 8 contiene una normale echo: la stringa $s viene stampata come qualsiasi altra stringa.

Il testo contenuto in una stringa heredoc si comporta esattamente come il testo tra doppi apici: le variabili contenute al suo interno sono sostituite col valore in esse contenuto, ed è possibile includere gli stessi caratteri speciali di cui abbiamo parlato nel paragrafo Doppi apici e che sono descritti nel manuale. Oltre a qesto, in una stringa heredoc possiamo usare tranquillamente i doppi apici senza usare la sequenza di escape \" (che abbiamo incontrato in Doppi apici), perchè non rischiano più di essere scambiati per la chiusura della stringa.

<?php
	$sito = 'RePNI';
	$indirizzo = 'http://www.repni.it/';

	$testo = <<<REPNIROCKS
<p>Il mio sito preferito è <span style="color:red;">$sito</span>, clicca su <a href="$indirizzo">questo link</a> per visitarlo!</p>
<p>Su $sito ho imparato che in una stringa heredoc posso inserire variabili e doppi apici (").</p>
<p>Utilizzando le sequenze di escape, posso anche inserire caratteri speciali come il dollaro (\$) o il back-slash (\\).</p>
REPNIROCKS;

	echo $testo;
?>

Questo codice produrrà il seguente risultato quando aperto nel browser:

Il mio sito preferito è RePNI, clicca su questo link per visitarlo!

Su RePNI ho imparato che in una stringa heredoc posso inserire variabili e doppi apici (").

Utilizzando le sequenze di escape, posso anche inserire caratteri speciali come il dollaro ($) o il back-slash (\).

Notare che tutti i nomi di variabile sono stati sostituiti con le variabili stesse (es. $sito è stato sostituito con RePNI), i doppi apici sono stati stampati come qualsiasi altro carattere (quelli alla riga 6 chiaramente non si vedono perchè sono parte dell'HTML necessario per definire il link), e i caratteri preceduti da back-slash sono stati riconosciuti e stampati come caratteri speciali.

Si potrebbe dire ancora qualcos'altro su heredoc, ma si tratta di sottigliezze che per il momento non ci interessano. Chi fosse curioso può sempre approfondire leggendo la pagina di mannuale corrispondente.

Sintassi "nowdoc"

Così come le stringhe a doppi apici hanno un corrispettivo "light", anche la sintassi heredoc ha una versione più leggera, ossia la sintassi newdoc.

Una stringa newdoc è definita in modo quasi identico ad una stringa heredoc:

<?php
	$variabile = 'Un testo che non sarà usato...';

	$testo = <<<'EOT'
Questa è una stringa newdoc.
All'apparenza è simile a heredoc, ma ha meno funzionalità
infatti se scrivo $variabile, leggo semplicemente $variabile...
EOT;

	echo $testo;
?>

Notiamo subito che l'unica differenza con heredoc sta nel fatto che l'identificatore di chiusura (EOT, alla linea 4) è qui racchiuso tra apici singoli.

Per il resto, il comportamento differisce solo nel fatto che, in nowdoc, PHP non "perde tempo" a cercare variabili e caratteri speciali nel testo, ma stampa tutto così com'è; in gergo si dice che non viene effettuato il parsing della stringa. Ad esempio, alla linea 7 troviamo $variabile nella stringa; Se la stringa fosse stata definita con heredoc (cioè senza apici singoli attorno a EOT) $variabile sarebbe riconosciuto come un identificatore di variabile, e quindi sostituito con il contenuto di $variabile (definito alla linea 2); invece, proprio come avverrebbe se usassimo gli apici singoli, l'output del programma sarà semplicemente $variabile.

In breve...

In questo capitolo abbiamo visto che...

  • Con il termine stringa in informatica ci si riferisce ad una qualsiasi sequenza di caratteri, come ad esempio un frammento di testo.
  • In PHP una variabile può essere di tipo stringa, ovvero contenere del testo.
    • Grazie alla tipizzazione dinamica, in PHP non ci dobbiamo preoccupare dei tipi di variabile, perchè essi, quando possibile, sono adattati automaticamente a seconda della necessità.
  • Una stringa può essere definita in quattro modi: apici doppi, apici singoli, heredoc e nowdoc
    • Una stringa tra apici doppi espande automaticamente le variabili contenute al suo interno, e riconosce un certo numero di caratteri speciali
    • Una stringa tra apici singoli è più veloce da elaborare, ma non espande il contenuto delle variabili e non gestisce altri caratteri speciali che non gli apici singoli stessi.
    • Una stringa heredoc si comporta come una stringa tra doppi apici, ma è più comoda da usare quando il testo occupa più righe, non necessita l'escape dei doppi apici.
    • Una stringa nowdoc è il corrispettivo delle stringhe tra apici singoli rispetto a heredoc.