3.Php: Operatori
7.Operatori

Un altro mattone fondamentale di qualsiasi linguaggio di programmazione è dato dagli operatori.

Un operatore è un componente sintattico che permette di compiere operazioni sugli oggetti; per esempio, in questo frammento di codice:

$saldo = $saldo_contabile + $interessi

viene fatta un’operazione matematica utilizzando l’operatore + e il risultato viene poi assegnato a una variabile attraverso l’operatore =.

7_1.Operatori aritmetici

Gli operatori aritmetici disponibili in PHP sono i classici operatori unari (cioè che agiscono su un unico argomento) e binari dei più evoluti linguaggi di programmazione, elencati nella tabella seguente.

Operatore Descrizione Tipo
+ Somma binario
- Sottrazione binario
* Moltiplicazione binario
/ Divisione binario
% Modulo binario
++ Pre/Post incremento unario
-- Pre/Post decremento unario

Ecco un esempio di utilizzo degli operatori.

<html>
   <head>
      <title>Operatori</title>
   </head>
   <body>
      <?php
        $left = 54;
        $right = 12;
        print("$left + $right = " . ($left + $right) . "<br>");
        print("$left - $right = " . ($left - $right) . "<br>");
        print("$left * $right = " . ($left * $right) . "<br>");
        print("$left / $right = " . ($left / $right) . "<br>");
        print("$left % $right = " . ($left % $right) . "<br>");
        print("$left++ : prima: $left esecuzione: " . ($left++) . " dopo: $left<br>");
        print("++$left : prima: $left esecuzione: " . (++$left) . " dopo: $left<br>");
        print("$right-- : prima: $right esecuzione: " . ($right--) . " dopo: $right<br>");
        print("--$right : prima: $right esecuzione: " . (--$right) . " dopo: $right<br>");
      ?>
   </body>
</html>

Come si può vedere, il comportamento degli operatori è piuttosto intuitivo: c’è una corrispondenza biunivoca tra gli operatori PHP e gli operatori aritmetici.

Gli unici operatori che si discostano dallo standard sono gli operatori unari di pre/post incremento e pre/post decremento (++ e --):

  • operatore di preincremento: ++numero;
  • operatore di postincremento: numero++;
  • operatore di predecremento: --numero;
  • operatore di postdecremento: numero--.

Le regole generali di utilizzo di questi operatori sono le seguenti:

  • l’operatore di preincremento incrementa l’argomento prima di utilizzarlo;
  • l’operatore di postincremento incrementa l’argomento dopo averlo utilizzato;
  • l’operatore di predecremento decrementa l’argomento prima di utilizzarlo;
  • l’operatore di postdecremento decrementa l’argomento dopo averlo utilizzato.

Tale è la spiegazione del comportamento del codice di esempio.

In particolare, il codice:

$left = 54;
print("$left " . ($left++) . " $left");

produce la stampa della sequenza: "54 54 55".

Questo perché lo script stampa il valore della variabile $left, poi, quando si trova a dover stampare il valore dell’espressione $left++, che contiene un operatore di post-incremento che deve essere eseguito soltanto dopo l’utilizzo della variabile, prima stampa il valore della variabile originale e solo successivamente lo incrementa.

Il valore così incrementato viene poi stampato successivamente.

Allo stesso modo il codice:

$left = 54;
print("$left " . (++$left) . " $left");

produce la stampa della sequenza: "54 55 55". Infatti, questa volta si utilizza un operatore di preincremento e pertanto la variabile viene prima incrementata e successivamente stampata.

7_2.Operatori di assegnamento

L’unico vero operatore di assegnamento è naturalmente il simbolo di uguale che consente, come sappiamo, di assegnare alla variabile di sinistra lo stesso valore della variabile di destra secondo la sintassi:

$left = 54

PHP, però, fornisce anche una serie di operatori di assegnamento particolari che sono in grado di compattare e rendere elegante il codice prodotto.

In particolare si tratta di operatori binari che associano alla variabile a sinistra il valore prodotto dall’applicazione di un certo operatore sui valori delle variabili sinistra e destra.

Ciascun operatore quindi rappresenta una contrazione del codice più prolisso che sarebbe necessario per ottenere lo stesso risultato. Vediamoli nel dettaglio:

L’operatore: è la contrazione di:
$a += $b $a = $a + $b
$a -= $b $a = $a - $b
$a *= $b $a = $a * $b
$a /= $b $a = $a / $b
$a %= $b $a = $a % $b
$a &= $b $a = $a & $b
$a |= $b $a = $a | $b
$a ^= $b $a = $a ^ $b
$a.= $b $a = $a . $b

Per fare un esempio di come possano essere utilizzati questi operatori di assegnamento. Vediamo il codice seguente:

$number = 54;
print($number += 21);

Il risultato di questo script è naturalmente la stampa della stringa "75" in quanto, secondo quanto detto in precedenza, lo script potrebbe essere scritto in questo modo:

$number = 54;
$number = $number + 21;
print($number);

7_3.Operatori relazionali

Un operatore relazionale mette in una specifica relazione due oggetti e se questa relazione è verificata restituisce il valore booleano TRUE. In caso contrario, restituisce il valore FALSE.

Ecco una lista degli operatori relazionali supportati da PHP.

Operatore Descrizione
== Uguale
=== Identico
< Minore
<= Non maggiore
> Maggiore
>= Non minore
!= Non uguale
!== Non identico

Segue un semplice script PHP che utilizza gli operatori relazionali:

<html>
   <head>
      <title>Operatori Relazionali</title>
   </head>
   <body>
      <?php
        $a = 54;
        $b = 12;
        print('$a = : ' . $a . "<br>");
        print('$b = : ' . $b . "<br>");
        print('$a == $b : ' . ($a == $b) . "<br>");
        print('$a === $b : ' . ($a === $b) . "<br>");
        print('$a < $b : ' . ($a < $b) . "<br>");
        print('$a <= $b : ' . ($a <= $b) . "<br>");
        print('$a > $b : ' . ($a > $b) . "<br>");
        print('$a >= $b : ' . ($a >= $b) . "<br>");
        print('$a != $b : ' . ($a != $b) . "<br>");
        print('$a !== $b : ' . ($a !== $b) . "<br>");
      ?>
   </body>
</html>

Guardando il risultato dell’esecuzione, visibile nella Figura 2.13, appare chiaro quale sia il comportamento di questi operatori relazionali. Il risultato booleano che questi operatori producono viene convertito, in modo conforme alle regole di conversione che abbiamo visto, nella stringa "1" se il valore è TRUE e in una stringa vuota se il valore è FALSE.

Analizzando la tabella degli operatori relazionali può sorgere il dubbio su quale sia la differenza tra gli operatori che testano l’uguaglianza e l’identicità di due variabili.

In generale, si può dire che due valori sono uguali se hanno lo stesso valore dopo essere stati convertiti a un certo tipo che li renda confrontabili.

Due valori invece sono identici se hanno lo stesso valore ma anche lo stesso tipo.

Segue un esempio:

<html>
   <head>
      <title>Identità e Uguaglianza</title>
   </head>
   <body>
      <?php
       $number = 54;
       $stringa = "54";
       if ($number==$stringa)
       {
          print('$number e $stringa sono uguali' . "<br>");
          if ($number===$stringa)
             { print('$number e $stringa sono identici' . "<br>"); }
          else
             { print('$number e $stringa non sono identici' . "<br>"); }
       }
       else
       {
       print('$number e $stringa non sono uguali' . "<br>");
       }
      ?>
   </body>
</html>

In questo script, abbiamo due variabili di tipo diverso, un numerico e una stringa.

Il loro valore, al netto delle conversioni classiche, è lo stesso, pertanto un test di uguaglianza ritornerà TRUE.

Il test di identicità, invece, poiché effettua anche una verifica sul tipo delle variabili, ritorna il valore FALSE.

7_4.Operatori logici

Agli operatori relazionali, che restituiscono sempre valori booleani, è possibile associare operatori logici in modo da creare vere e proprie espressioni booleane complesse.

Un’espressione booleana è, infatti, la composizione di più elementi booleani attraverso l’utilizzo di operatori logici.

Gli operatori logici supportati da PHP sono elencati di seguito.

Operatore Descrizione
&& AND
AND AND
|| OR
OR OR
XOR OR Esclusivo
! NOT

L’utilizzo di questi operatori logici è piuttosto semplice. Ecco alcuni esempi:

if ((condizione1) && (condizione2))
{
   // istruzioni
}

if ((condizione1) || (condizione2))
{
   // istruzioni
}

if ((condizione1) XOR (condizione2))
{
   // istruzioni
}

if (!(condizione))
{
   // istruzioni
}

7_5.Operatori di casting

Abbiamo visto negli esempi precedenti che PHP ha al suo interno delle regole di conversione automatica che consentono di risolvere i più classici conflitti di tipo.

Può accadere però che la regola di conversione adottata da PHP non sia quella ottimale per il codice che stiamo scrivendo, e per questo motivo esistono degli operatori espliciti di cast che consentono di specificare esplicitamente il tipo di una variabile da utilizzare per la conversione.

Vediamo un esempio:

<html>
   <head>
      <title>Cast</title>
   </head>
   <body>
      <?php
       $intero = 54;
       $reale = 123.32;

       print('$intero + $reale = ' . ($intero + $reale) . "<br>");
       print('$intero + $reale = ' . ($intero + (int)$reale) . "<br>");
       print('$intero + $reale = ' . (boolean)($intero + $reale) . "<br>");

      ?>
   </body>
</html>

Si vede chiaramente che la conversione standard di PHP converte la variabile $intero in un numero in virgola mobile per poter eseguire la somma senza perdere le informazioni dei decimali.

Se invece utilizziamo un cast esplicito, attraverso l’operatore di cast (int), specificando che la variabile $reale è in realtà di tipo intero, allora il motore PHP trova due interi e li somma senza effettuare ulteriori conversioni.

Allo stesso modo un cast esplicito effettuato con l’operatore (boolean) converte, secondo le regole standard di conversione, il numero (che è diverso da zero) nel valore booleano TRUE e questo viene riconvertito nella stringa "1" per poter essere stampato.

7_6.Altri operatori

Il motore di PHP fornisce molti altri operatori dagli usi più disparati. Essi sono costrutti sintattici molto interessanti che contribuiscono ad arricchire il linguaggio e permettono una stesura più semplice e pulita del codice.

Iniziamo a vedere gli operatori base del linguaggio; più avanti, quando ci occuperemo di oggetti e classi, vedremo anche quelli specifici della gestione object oriented di PHP5.

Concatenazione

L’operatore di concatenazione, come già visto negli esempi precedenti, è un semplice punto frapposto tra due stringhe, e il suo risultato è semplicemente una concatenazione tra queste.

Ecco un piccolo esempio:

print('Paperino e ' . 'Topolino ' . 'sono amici?');

Prima di eseguire questa istruzione il motore PHP deve occuparsi di risolvere tutte le espressioni eventualmente contenute nelle parentesi. Pertanto, la riga precedente viene riscritta in questo modo:

print('Paperino e Topolino sono amici?');

A questo punto l’istruzione può essere eseguita stampando la stringa che ci aspettiamo.

7_7.Variabili di variabili

Come sappiamo è possibile dichiarare una qualsiasi variabile attraverso la sintassi:

$nome = "paperino";

Attraverso un particolare operatore di referenza indiretta è possibile scrivere questa riga di codice (notate il doppio simbolo del dollaro):

$$nome = "topolino";

Poiché la variabile $nome ha il valore che abbiamo impostato precedentemente, la sintassi che abbiamo appena utilizzato è assolutamente equivalente a questa:

$paperino = "topolino";

Abbiamo cioè creato nel codice una variabile il cui nome interno è il valore di un’altra variabile.

Per accedere alle informazioni contenute in queste variabili si possono utilizzare due sintassi alternative. La prima è:

print($paperino);

e la seconda:

print(${$nome});

Questo meccanismo è molto potente e permette di scrivere codice molto sofisticato anche se nasconde insidie di lettura del codice (da usare quindi con cautela).

7_8.Operatore ternario

In PHP, così come in tutti i linguaggi dalla sintassi derivata dal C, esiste un operatore detto ternario che consente di scrivere codice compatto senza scomodare, per semplici test, gli operatori classici di confronto.

Ecco un esempio di come si può usare:

$number = 54;
print(($number > 20) ? "maggiore di venti" : "minore o uguale a venti");

La sintassi è la seguente:

condizione ? istruzione per true : istruzione per false

Nel caso dell’esempio precedente la condizione è un test per verificare che la variabile abbia un valore maggiore di 20; se questa condizione è vera allora viene eseguita la prima istruzione, in caso contrario la seconda.

Per chiarire meglio questo concetto vediamo questo semplice esempio:

$x = 54;
$y = 78;
print("Il max tra x e y è: " . (($x>$y)?$x:$y));

Per stampare il valore massimo tra due variabili si utilizza l’operatore ternario; se la condizione ($x>$y) è vera viene stampata la variabile $x, in caso contrario la $y.