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.
|