Manca {
o }
dovuta a rientro errato
Le parentesi graffe di codice non corrispondenti sono comuni al codice meno formattato come:
if((!($opt["uniQartz5.8"]!=$this->check58)) or (empty($_POST['poree']))) {if
($true) {echo"halp";} elseif((!$z)or%b){excSmthng(False,5.8)}elseif (False){
Se il tuo codice è simile al seguente, ricominciare da capo! Altrimenti non è riparabile per te o per chiunque altro. Non ha senso mostrarlo su Internet per chiedere aiuto.
Sarai in grado di risolverlo solo se puoi seguire visivamente la struttura nidificata e la relazione dei condizionali if / else e dei loro {
blocchi di codice }
. Usa il tuo IDE per vedere se sono tutti abbinati.
if (true) {
if (false) {
…
}
elseif ($whatever) {
if ($something2) {
…
}
else {
…
}
}
else {
…
}
if (false) { // a second `if` tree
…
}
else {
…
}
}
elseif (false) {
…
}
Qualsiasi doppio }
}
non chiuderà solo un ramo, ma una struttura di condizioni precedente. Quindi attenersi a uno stile di codifica; non mescolare e abbinare in alberi nidificati if / else.
A parte la coerenza qui, risulta utile evitare anche condizioni prolungate. Utilizzare variabili o funzioni temporanee per evitare if
espressioni illeggibili .
IF
non può essere usato nelle espressioni
Un errore sorprendentemente frequente per i nuovi arrivati sta cercando di utilizzare if
un'istruzione in un'espressione, come un'istruzione print:
⇓
echo "<a href='" . if ($link == "example.org") { echo …
Che ovviamente non è valido.
È possibile utilizzare un condizionale ternario , ma attenzione agli impatti della leggibilità.
echo "<a href='" . ($link ? "http://yes" : "http://no") . "</a>";
In caso contrario, rompere tali costrutti uscita Up: Usa multipla if
s e echo
s .
Meglio ancora, usa le variabili temporanee e posiziona i tuoi condizionali prima di:
if ($link) { $href = "yes"; } else { $href = "no"; }
echo "<a href='$href'>Link</a>";
Anche la definizione di funzioni o metodi per tali casi ha spesso senso.
I blocchi di controllo non restituiscono "risultati"
Ora questo è meno comune, ma alcuni programmatori provano persino a trattare if
come se potesse restituire un risultato :
$var = if ($x == $y) { "true" };
Che è strutturalmente identico all'utilizzo if
all'interno di una concatenazione / espressione di stringhe.
- Ma le strutture di controllo (if / foreach / while) non hanno un "risultato" .
- La stringa letterale "vero" sarebbe anche solo un'istruzione nulla.
Dovrai utilizzare un compito nel blocco di codice :
if ($x == $y) { $var = "true"; }
In alternativa, ricorrere a un ?:
confronto ternario.
If in If
Non è possibile nidificareif
all'interno di una condizione:
⇓
if ($x == true and (if $y != false)) { ... }
Il che è ovviamente ridondante, poiché il and
(o or
) consente già il concatenamento di confronti.
;
Punto e virgola dimenticato
Ancora una volta: ogni blocco di controllo deve essere un'istruzione. Se il pezzo di codice precedente non è terminato da un punto e virgola, si tratta di un errore di sintassi garantito:
⇓
$var = 1 + 2 + 3
if (true) { … }
A proposito, anche l'ultima riga di un {…}
blocco di codice richiede un punto e virgola.
Punto e virgola troppo presto
Ora è probabilmente sbagliato dare la colpa a un particolare stile di codifica, poiché questa trappola è troppo facile da trascurare:
⇓
if ($x == 5);
{
$y = 7;
}
else ←
{
$x = -1;
}
Il che succede più spesso di quanto tu possa immaginare.
- Quando si termina l'
if ()
espressione con;
essa, verrà eseguita un'istruzione void. Il ;
diventa un vuoto a {}
sé stante!
- Il
{…}
blocco quindi è staccato da if
, e funzionerebbe sempre.
- Quindi il
else
non aveva più una relazione con un if
costrutto aperto , motivo per cui ciò avrebbe portato a un errore di sintassi T_ELSE imprevisto.
Il che spiega anche una variazione altrettanto sottile di questo errore di sintassi:
if ($x) { x_is_true(); }; else { something_else(); };
Dove il ;
dopo il blocco di codice {…}
termina l'intero if
costrutto, tagliando il else
ramo in modo sintattico.
Non si utilizzano blocchi di codice
È sintatticamente permesso omettere parentesi graffe {
... }
per blocchi di codice in if
/ elseif
/else
branch. Che purtroppo è uno stile di sintassi molto comune ai programmatori non convertiti. (Con il falso presupposto questo è stato più veloce da digitare o leggere).
Tuttavia, è molto probabile che si verifichi la sintassi. Prima o poi le dichiarazioni aggiuntive troveranno la loro strada nei rami if / else:
if (true)
$x = 5;
elseif (false)
$x = 6;
$y = 7; ←
else
$z = 0;
Ma in realtà usare i blocchi di codice, è c'è bisogno di scrivere {
... }
come tali!
Anche i programmatori esperti evitano questa sintassi senza bretelle, o almeno la comprendono come un'eccezione eccezionale alla regola.
Else / Elseif nell'ordine sbagliato
Una cosa da ricordare è l' ordine condizionale , ovviamente.
if ($a) { … }
else { … }
elseif ($b) { … }
↑
Puoi avere quanti elseif
s vuoi, ma else
deve andare per ultimo . È così.
Dichiarazioni di classe
Come accennato in precedenza , non è possibile avere istruzioni di controllo in una dichiarazione di classe:
class xyz {
if (true) {
function ($var) {}
}
O hai dimenticato una definizione di funzione o chiusa }
troppo presto in questi casi.
T_ELSEIF / T_ELSE imprevisto
Quando si mescolano PHP e HTML, la chiusura }
di un if/elseif
deve essere nello stesso blocco PHP <?php ?>
del successivo elseif/else
. Ciò genererà un errore poiché la chiusura }
delle if
esigenze deve far parte di elseif
:
<?php if ($x) { ?>
html
<?php } ?>
<?php elseif ($y) { ?>
html
<?php } ?>
La forma corretta <?php } elseif
:
<?php if ($x) { ?>
html
<?php } elseif ($y) { ?>
html
<?php } ?>
Questa è più o meno una variazione di rientro errato, presumibilmente spesso basato su intenzioni di codifica errate.
Non si può schiacciare altre dichiarazioni inbetween if
e elseif
/ else
gettoni strutturali:
if (true) {
}
echo "in between"; ←
elseif (false) {
}
?> text <?php ←
else {
}
Entrambi possono verificarsi solo in {…}
blocchi di codice, non tra i token della struttura di controllo.
- Questo non avrebbe comunque senso. Non è che ci sia stato uno stato "indefinito" quando PHP salta tra
if
e i else
rami.
- Dovrai decidere dove appartengono le dichiarazioni di stampa / o se devono essere ripetute in entrambi i rami.
Né puoi separare un if / else tra diverse strutture di controllo:
foreach ($array as $i) {
if ($i) { … }
}
else { … }
Non esiste una relazione sintattica tra il if
e else
. L' foreach
ambito lessicale termina a }
, quindi non ha senso che la if
struttura continui.
T_ENDIF
Se si lamenta un T_ENDIF imprevisto, si sta utilizzando lo stile di sintassi alternativo if:
⋯ elseif:
⋯ else:
⋯ endif;
. Di cui dovresti davvero pensarci due volte.
Una trappola comune sta confondendo i due punti stranamente simili :
per un ;
punto e virgola . (Coperto in "Punto e virgola troppo presto")
Poiché il rientro è più difficile da tracciare nei file modello, tanto più quando si utilizza la sintassi alternativa: è plausibile endif;
che non corrisponda a nessuno if:
.
L'uso } endif;
è un termostato raddoppiato if
.
Mentre un "fine $ inatteso" è di solito il prezzo di un }
tutore di chiusura chiuso dimenticato .
Compito vs. confronto
Quindi, questo non è un errore di sintassi, ma vale la pena ricordare in questo contesto:
⇓
if ($x = true) { }
else { do_false(); }
Non è un ==
/ ===
confronto, ma un =
compito . Questo è piuttosto sottile e porterà facilmente alcuni utenti a modificare in modo impotente interi blocchi di condizioni. Fai attenzione prima agli incarichi non intenzionali: quando si verifica un errore logico / comportamento errato.