PHP parse/syntax errors; and how to solve them?
Everyone runs into syntax errors. Even experienced programmers make typos. For newcomers it's just part of the learning process. However, it's often easy to interpret error messages such as:
PHP Parse error: syntax error, unexpected ' E_STRICT); for earlier versions of PHP
– Geo
error_reporting(E_ALL
if/elseif
<?php ?>
elseif/else
}
if
elseif
<?php if ($x) ?>
html
<?php ?>
<?php elseif ($y) ?>
html
<?php ?>
The correct form <?php } elseif
:
<?php } elseif
<?php if ($x) ?>
html
<?php elseif ($y) ?>
html
<?php ?>
This is more or less a variation of incorrect indentation - presumably often based on wrong coding intentions.
You cannot mash other statements inbetween if
and elseif
/else
structural tokens:
if
elseif
else
if (true)
echo "in between"; ←
elseif (false)
?> text <?php ←
else
Either can only occur in `…` code blocks, not in between control structure tokens.
* This wouldn't make sense anyway. It's not like that there was some "undefined" state when PHP jumps between `if` and `else` branches.
* You'll have to make up your mind where print statements belong to / or if they need to be repeated in both branches.
<br><br>
Nor can you **part an if/else** between different control structures:
foreach ($array as $i)
if ($i) …
else …
There is no [syntactic relation](https://stackoverflow.com/questions/567002/unexpected-t-elseif) between the `if` and `else`. The `foreach` lexical scope ends at `}`, so there's no point for the `if` structure to continue.
If an unexpected T_ENDIF is complained about, you're using the alternative syntax style if:
⋯ elseif:
⋯ else:
⋯ endif;
. Which you should really think twice about.
if:
elseif:
else:
endif;
A common pitfall is confusing the eerily similar :
colon for a ;
semicolon. (Covered in "Semicolon too early")
:
;
As indentation is harder to track in template files, the more when using the alternative syntax - it's plausible your endif;
does not match any if:
.
endif;
if:
Using } endif;
is a doubled if
-terminator.
} endif;
if
While an "unexpected $end" is usually the price for a forgotten closing }
curly brace.
}
So, this is not a syntax error, but worth mentioning in this context:
⇓
if ($x = true)
else do_false();
That's not a ==
/===
comparison, but an =
assignment. This is rather subtle, and will easily lead some users to helplessly edit whole condition blocks. Watch out for unintended assignments first - whenver you experience a logic fault / misbeheviour.
==
===
=
Control constructs such as if
, foreach
, for
, while
, list
, global
, return
, do
, print
, echo
may only be used as statements. They usually reside on a line by themselves.
if
foreach
for
while
list
global
return
do
print
echo
Pretty universally have you missed a semicolon in the previous line if the parser complains about a control statement:
⇓
$x = myfunc()
if (true) {
Solution: look into the previous line; add semicolon.
Another location where this occurs is in class declarations. In the class section you can only list property initializations and method sections. No code may reside there.
class xyz {
if (true)
foreach ($var)
Such syntax errors commonly materialize for incorrectly nested
and
. In particular when function code blocks got closed too early.
Most language constructs can only be used as statements. They aren't meant to be placed inside other expressions:
⇓
$var = array(1, 2, foreach($else as $_), 5, 6);
Likewise can't you use an if
in strings, math expressions or elsewhere:
if
⇓
print "Oh, " . if (true) "you!" . " won't work";
// Use a ternary condition here instead, when versed enough.
For embedding if
-like conditions in an expression specifically, you often want to use a ?:
ternary evaluation.
if
?:
The same applies to for
, while
, global
, echo
and a lesser extend list
.
for
while
global
echo
list
⇓
echo 123, echo 567, "huh?";
Whereas print()
is a language builtin that may be used in expression context. (But rarely makes sense.)
print()
You also can't use do
or if
and other language constructs for user-defined functions or class names. (Perhaps in PHP7. But even then it wouldn't be advisable.)
do
if
<
>
Comparison operators such as ==
, >=
, ===
, !=
, <>
, !==
and <=
or <
and >
mostly should be used just in expressions, such as if
expressions. If the parser complains about them, then it often means incorrect paring or mismatched (
)
parens around them.
==
>=
===
!=
<>
!==
<=
<
>
if
(
)
In particular for if
statements with multiple comparisons you must take care to correctly count opening and closing parenthesis:
if
⇓
if (($foo < 7) && $bar) > 5 || $baz < 9) ...
↑
Here the if
condition here was already terminated by the )
if
)
Once your comparisons become sufficiently complex it often helps to split it up into multiple and nested if
constructs rather.
if
A common newcomer is pitfal is trying to combine isset()
or empty()
with comparisons:
isset()
empty()
⇓
if (empty($_POST["var"] == 1)) {
Or even:
⇓
if (isset($variable !== "value")) {
This doesn't make sense to PHP, because isset
and empty
are language constructs that only accept variable names. It doesn't make sense to compare the result either, because the output is only/already a boolean.
isset
empty
>=
=>
Both operators look somewhat similar, so they sometimes get mixed up:
⇓
if ($var => 5) ...
You only need to remember that this comparison operator is called "greater than or equal" to get it right.
See also: If statement structure in PHP
You also can't combine two comparisons if they pertain the same variable name:
⇓
if ($xyz > 5 and < 100)
PHP can't deduce that you meant to compare the initial variable again. Expressions are usually paired according to operator precedence, so by the time the <
is seen, there'd be only a boolean result left from the original variable.
<
See also: unexpected T_IS_SMALLER_OR_EQUAL
You can't compare against a variable with a row of operators:
⇓
$reult = (5 < $x < 10);
This has to be broken up into two comparisons, each against $x
.
$x
This is actually more a case of blacklisted expressions (due to equivalent operator associativity). It's syntactically valid in a few C-style languages, but PHP wouldn't interpret it as expected comparison chain either.
>
<
The greater than >
or less than <
operators don't have a custom T_XXX
tokenizer name. And while they can be misplaced like all they others, you more often see the parser complain about them for misquoted strings and mashed HTML:
>
<
T_XXX
⇓
print "<a href='z">Hello</a>";
↑
This amounts to a string "<a href='z"
being compared >
to a literal constant Hello
and then another <
comparison. Or that's at least how PHP sees it. The actual cause and syntax mistake was the premature string "
termination.
"<a href='z"
>
Hello
<
"
See also:
If you are trying to use the null coalescing operator ??
in a version of PHP prior to PHP 7 you will get this error.
??
<?= $a ?? 2; // works in PHP 7+
<?= (!empty($a)) ? $a : 2; // All versions of PHP
In PHP, and most other programming languages, variables cannot start with a number. The first character must be alphabetic or an underscore.
$1 // Bad
$_1 // Good
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
Comments
Post a Comment