La precedenza di un operatore specifica come esso tenga legate assieme "strettamente" due
espressioni. Per esempio, nell'espressione 1 +
5 * 3, la risposta è 16 e non
18 perché l'operatore di moltiplicazione ("*")
ha una precedenza più alta rispetto all'operatore di addizione ("+").
Le parentesi possono essere usate per forzare la precedenza, se necessario. Per
esempio: (1 + 5) * 3 viene valutata
18.
Quando gli operatori hanno precedenza identica, la loro associatività decide
come gli operatori sono raggruppati. Per esempio "-" è associativo a sinistra, quindi
1 - 2 - 3 è raggruppato come (1 - 2) - 3
e valutato come -4. D'altra parte "=" è
associativo a destra, quindi $a = $b = $c è raggruppato come
$a = ($b = $c).
Operatori di uguale precedenza che non sono associativi non possono essere usati
vicini l'uno all'altro, per esempio 1 < 2 > 1 è
illegale in PHP. D'altra parte l'espressione 1 <= 1 == 1
è legale, perchè l'operatore == ha una minore
precedenza dell'operatore <=.
L'associatività è significativa solo per gli operatori binari (e ternari).
Gli operatori unari sono prefisso o suffisso, quindi questa nozione non è applicabile.
Ad esempio !!$a può essere raggruppato solo come !(!$a).
L'uso delle parentesi, anche quando non strettamente necessario, può spesso aumentare la leggibilità del codice rendendo il raggruppamento esplicito piuttosto che fare affidamento sulla precedenza e sull'associatività implicite degli operatori.
La seguente tabella fornisce una lista della precedenza degli operatori con gli operatori a più alta precedenza elencati prima. Gli operatori presenti nella medesima linea hanno uguale precedenza, in questi casi la loro associativià decide il raggruppamento.
| Associatività | Operatori | Informazioni aggiuntive |
|---|---|---|
| (n/a) |
clone
new
|
clone e new |
| destra | ** |
operatori aritmetici |
| (n/a) |
+
-
++
--
~
(int)
(float)
(string)
(array)
(object)
(bool)
@
|
aritmetici (unari + e -),
incremento/decremento,
bitwise,
casting del tipo e
controllo dell'errore
|
| sinistra | instanceof |
tipo |
| (n/a) | ! |
logici |
| sinistra |
*
/
%
|
aritmetici |
| sinistra |
+
-
.
|
aritmetici (binari + e -),
array e
stringhe (. prima di PHP 8.0.0)
|
| sinistra |
<<
>>
|
bit |
| sinistra | . |
stringhe (a partire da PHP 8.0.0) |
| non associativi |
<
<=
>
>=
|
confronto |
| non associativi |
==
!=
===
!==
<>
<=>
|
operatori di confronto |
| sinistra | & |
operatori sui bit e riferimenti |
| sinistra | ^ |
operatori sui bit |
| sinistra | | |
operatori sui bit |
| sinistra | && |
operatori logici |
| sinistra | || |
operatori logici |
| destra | ?? |
null coalescing |
| non associativi | ? : |
ternari (associativi a sinistra prima di PHP 8.0.0) |
| sinistra |
=
+=
-=
*=
**=
/=
.=
%=
&=
|=
^=
<<=
>>=
??=
|
operatori di assegnazione |
| (n/a) | yield from |
yield from |
| (n/a) | yield |
yield |
| (n/a) | print |
|
| sinistra | and |
operatori logici |
| sinistra | xor |
operatori logici |
| sinistra | or |
operatori logici |
Example #1 Associatività
<?php
$a = 3 * 3 % 5; // (3 * 3) % 5 = 4
// l'associatività dell'operatore ternario differisce da quella di C/C++
$a = true ? 0 : true ? 1 : 2; // (true ? 0 : true) ? 1 : 2 = 2 (prima di PHP 8.0.0)
$a = 1;
$b = 2;
$a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5
?>La precedenza e l'associatività dell'operatore determinano solo come le espressioni sono raggruppate, esse non specificano un ordine di valutazione. PHP non specifica (nel caso generale) in quale ordine un'espressione è valutata e un codice che presuppone uno specifico ordine di valutazione dovrebbe essere evitato, perchè il comportamento può cambiare tra le versioni di PHP o in base al codice circostante.
Example #2 Ordine di valutazione indefinito
<?php
$a = 1;
echo $a + $a++; // può stampare 2 o 3
$i = 1;
$array[$i] = $i++; // può impostare l'indice 1 o 2
?>Example #3 +, - e . hanno la stessa precedenza (prima di PHP 8.0.0)
<?php
$x = 4;
// questa linea potrebbe causare un risultato inaspettato:
echo "x minus one equals " . $x-1 . ", or so I hope\n";
// perché è valutata come questa linea (prima di PHP 8.0.0):
echo (("x minus one equals " . $x) - 1) . ", or so I hope\n";
// la precedenza desiderata può essere forzata usando le parentesi:
echo "x minus one equals " . ($x-1) . ", or so I hope\n";
?>Il precedente esempio visualizzerà:
-1, or so I hope -1, or so I hope x minus one equals 3, or so I hope
Nota:
Sebbene
=abbia una precedenza minore rispetto alla maggior parte degli altri operatori, PHP permette comunque espressioni simili alla seguente:if (!$a = foo()), in questo caso l'output difoo()viene inserito in $a.
| Versione | Descrizione |
|---|---|
| 8.0.0 |
La concatenazione delle stringhe (.) ora ha una precedenza inferiore rispetto
all'addizione/sottrazione aritmetica (+ e -) e
lo spostamento bit a bit a sinistra/destra (<< e >>);
precedentemente aveva la stessa precedenza di + e -
e una precedenza superiore a << e >>.
|
| 8.0.0 |
L'operatore ternario (? :) ora è non-associativo;
precedentemente era associativo a sinistra.
|
| 7.4.0 |
Fare affidamento sulla precedenza della concatenazione di stringhe (.) rispetto all'
addizione/sottrazione aritmetica (+ o -) o
lo spostamento bit a bit a sinistra/destra (<< o >>),
ovvero utilizzarli insieme in un'espressione senza parentesi, è deprecato.
|
| 7.4.0 |
Fare affidamento sull'associatività a sinistra dell'operatore ternario (? :),
ovvero annidare più operatori ternari senza parentesi, è deprecato.
|