venerdì 27 aprile 2012

Introduzione al PHP: Letterali Stringa (Parte 1/2)

Un letterale stringa è una sequenza di caratteri racchiusi tra apice singolo o doppio apice. A seconda del tipo di apice utilizzato, singolo o doppio, cambia il modo in cui il letterale è interpretato da PHP.

//I due letterali producono lo stesso risultato
$stringa1 = "Hello World!";
$stringa2 = 'Hello World!';

Letterale fra singolo apice

Nel caso di letterale stringa fra apice singolo, i caratteri sono interpretati così come sono, e codificati secondo il charset del file sorgente. Fa eccezione il back slash (\ detto anche carattere di escape) se seguito da un altro back slash o da un apice singolo. Abbiamo quindi le seguenti sequenze di escape:


\\
: Interpretato come un singolo back slash
\' : Interpretato come un apice singolo all'interno del letterale stringa

Perché queste due sequenze di escape?
Supponiamo di voler esprimere il letterale "quest'anno" con la notazione ad apice singolo. Otterremo

$stringa = 'Quest'anno'; //Errato

c'è un problema, ossia l'apice singolo dopo Quest è interpretato come chiusura del valore letterale e la parte successiva (anno';) produce un errore di sintassi. Per ovviare a questo problema abbiamo la sequenza di escape \' che permette di scrivere

$stringa = 'Quest\'anno'; //equivale a Quest'anno

producendo il letterale atteso. Risolto questo problema ne esiste un secondo, ovverosia se desideriamo inserire un back slash alla fine di una stringa. Ad esempio vogliamo ottenre /hello world\ racchiuso tra slash e back slash. In prima istanza potremmo pensare di scrivere:

$stringa = '/hello world\'; //Errato

Ma \' è una sequenza di escape e viene interpretata come un apice all'interno del letterale che vogliamo esprimere. Ne consegue che l'interprete PHP non rileva alcun apice di chiusura del letterale producendo un errore in qualche punto successivo a questa riga (il risultato e punto dell'errore dipende da quel che segue questa svista).

Per ovviare a questo problema c'è la sequenza di escape \\, che rappresenta il letterale back slash. Possiamo quindi scrivere:

$stringa = '/hello world\\'; //equivale a /hello world\

Ogni back slash all'interno della stringa, che non sia seguito da un secondo back slash o da un apice singolo, è interpretato come il carattere back slash.

$stringa = 'Questo \ e questo \\ sono interpretati come singoli back slash!';

Letterale fra doppio apice

I letterali fra doppia apici hanno anch'essi la possibilità di utilizzare delle sequenze di escape, ed in particolare:

\n : avanzamento linea (LineFeed o LF equivalente al codice ASCII 10)
\r : ritorno carrello (CarrigeReturn o CR con codice ASCII 13)
\t : tabulazione orizzontale (Horizontal Tab o HT con codice ASCII 9)
\\ : back slash
\$ : simbolo del dollaro
\" : simbolo del doppio apice
\xHH : con HH numero esadecimale compreso fra 0 e FF (codifica del carattere da rappresentare)
\OOO : con OOO numero ottale compreso fra 0 e 377 (codifica del carattere da rappresentare)

da PHP 5.2.5 ci sono anche:
\v : tabulazione verticale (Vertical Tab o VT con codice ASCII 11)
\f : avanzamento modulo (FormFeed o FF con codice ASCII 12)

da PHP 5.4 c'è
\e : escape o ESC con codice ASCII 27

\n, \r, \t, \v, \f e \e sono delle scorciatoie a codifiche ASCII specifiche, che si rivelano utili in varie circostanze come ad esempio la corretta formattazione nella comunicazione con un server tramite uno specifico protocollo di comunicazione. 

Le sequenze di escape \\ e \" sappiamo a cosa servono per quanto esposto per le stringhe racchiuse tra apice singolo. In più lo \\ ci permette di differenziare l'escape \n, \v, e così via, dal letterale \n, \v e così via che rappresenteremo come \\n, \\v e così via:

\\rappresenta il carattere di nuova linea
$newline="\n"; 

\\rappresenta la sequenza di caratteri \n non il nuova linea
$letterleSlashN="\\n"; 

\xHH e \OOO ci permettono di rappresentare qualunque sequenza di 8 bit, comprese quelle non ottenibili con i semplici caratteri disponibili sulla tastiera o con le scorciatoie viste prima. Da osservare che i numeri ottali e esadecimali non devono essere costituiti obbligatoriamente da 3 e 2 cifre, ma possono avere al più 2 e 3 cifre. Ciò significa che volendo rappresentare il ! che ha codifica ottale 41, potremo scrivere indifferentemente \041 o \41:

$doppioPuntoEscalmativo = "\41\041";
//notazione ottale che produce !!


In più nel caso della notazione ottale, i valori che eccedono il 377 (255 decimale, FF esadecimale e 1111 1111 binario) sono troncati ai primi 8 bit più bassi ossia al primo byte (unità di memorizzazione delle stringhe che come già detto, in post precedenti, sono degli array di byte).

Per esempio, se scriviamo $o = "\476"; equivalente a 100 111 110 in binario (sono in gruppi di 3 cifre perché ogni cifra ottale è 3 cifre binarie, così come ogni cifra esadecimale è 4 cifre binarie), ed essendo la capacità di immagazzinamento per un elemento di una stringa pari a 1 byte ovvero 8 bit, il valore effettivamente memorizzato sarà costituito dai primi 8 bit di peso minore (i primi otto bit presi da destra verso sinistra), ossia 00 111 110 equivalente a 62 in decimale e \076 ottale, che nella codifica ASCII corrisponde al carattere >.

Infine, ma non meno importante è la sequenza \$. Questa sequenza di escape esiste perché, ogni qual volta inseriamo il simbolo $ all'interno di una stringa letterale racchiusa tra doppi apici, PHP cerca di interpretare quanti più caratteri possibile a seguito del $ come nome di una variabile. Il contenuto della variabile (convertito in stringa) è sostituito al suo nome all'interno del letterale stringa. Se non vogliamo che PHP adotti tale comportamento ma interpreti il $ come simbolo letterale, occorre utilizzare la sequenza di escape \$.