PHP parse/syntax errors; and how to solve them?

The name of the picture

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
Aug 15 '13 at 21:42


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

Popular posts from this blog

Executable numpy error

Trying to Print Gridster Items to PDF without overlapping contents

Mass disable jenkins jobs