What happens if I don’t specify the { }?

Asked

Viewed 214 times

8

I own this code that works normally:

if($time <= time()) {       
     if($time != 0)
         $Server->wsSend(1, 'perfect world');

        foreach ( $Server->wsClients as $id => $client ) 
            $time = time() + $adminMessage['interval'];
}

I can’t modify it because it doesn’t specify the {} of if nor the foreach. If I put { } in the foreach the wsSend no longer works.

Why is it working?

2 answers

12


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.

5

Each if or foreach not accompanied by keys ({ and }) take into account only the next command.

So the code you posted is equivalent to the code snippet below:

if ($time <= time()) {       
    if ($time != 0) {
        $Server->wsSend(1, 'perfect world');
    }
    foreach ($Server->wsClients as $id => $client) {
        $time = time() + $adminMessage['interval'];
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.