Why the problem exists in PHP
As C has become an extremely popular language, and to succeed, others seek to copy its syntax, as is the case with PHP.
The problem
This is the so-called dangling Else. Technically you’re not wearing one else
but the problem is essentially the same. This is a problem created by the way the C language decided the syntax of if
, where you can have either a single logical line of execution or a block of execution.
If you need to run only one line just put that line right after the condition. It can be placed on the same physical line as the if
or later, what will determine that you have finished is the semicolon.
If you need an execution block you need to explicitly delimit them through the keys. This way you can put as many lines (ie as many semicolons) you want inside the block, what will determine your end is the "key closes".
Although it seems a good idea to save typing and make the code slightly more concise when it has only one line, it is very common to lose control of this and end up creating an unwanted logic. This occurs when the programmer plans to have a line and ends up needing to put more than one. Then he forgets that keys become mandatory.
Indentation does not count for anything to determine what will be executed, it serves only for the programmer to better visualize what it is doing. Then your code in the background should be indented like this (which would probably make you realize the error):
if ($time <= time()) {
if ($time != 0)
$Server->wsSend(1, 'perfect world');
foreach ( $Server->wsClients as $id => $client )
$time = time() + $adminMessage['interval'];
}
Or to better visualize:
if ($time <= time()) {
if ($time != 0) {
$Server->wsSend(1, 'perfect world');
}
foreach ( $Server->wsClients as $id => $client ) {
$time = time() + $adminMessage['interval'];
}
}
So clearly the foreach
is not inside the if
. If your intention was that he was, the only solution would be:
if ($time <= time()) {
if ($time != 0) {
$Server->wsSend(1, 'perfect world');
foreach ( $Server->wsClients as $id => $client )
$time = time() + $adminMessage['interval'];
}
}
I’d do even better:
if ($time <= time()) {
if ($time != 0) {
$Server->wsSend(1, 'perfect world');
foreach ( $Server->wsClients as $id => $client ) {
$time = time() + $adminMessage['interval'];
}
}
}
I put in the Github for future reference.
The solution
Just because you can, doesn’t mean you should avoid the keys when you only have one line. Keeping the standard of always using the keys, regardless of whether it is necessary or not, you avoid these undesirable errors.
An alternative is to use everything on the same line, there is no confusion with the block.