63

Something that really would like to know but never found out are shortcuts in PHP.

I am currently coding a function with a foreach loop with just a single statement inside. I tried to omit the curly braces as you can do in if/else control structures and it works. No errors.

foreach($var as $value)
    $arr[] = $value;

Now I tried to use it the same way but putting an if/else block inside it. Again, working and no errors.

foreach($var as $value)
    if(1 + 1 == 2) {
        $arr[] = $value;
    };

Then, I thought like "why is this working?" and omitted the closing semicolon. Still working. So I tried to use the if/else statement without curly braces inside the foreach loop and again, still working and no errors. But is the foreach loop really closed/ended right now?

foreach($var as $value)
    if(1 + 1 == 2)
        $arr[] = $value;

At least I omitted the closing semicolon again and (as expected) a parsing error occurred.

So my big question is: When can I omit the curly braces and in which structure/loop/function? I know that I can definitely do so in if and else. But what about while, for and foreach?

And yes, I know that it is not safe, smart, whatever to code without curly braces and there are shorthands like $condition ? true : false; and if: doSomething(); endif;, endfor; and endforeach;. I don't wanna learn about shorthands I just want to understand the conditions about when and where it is possible to omit the curly brackets.

Cœur
  • 37,241
  • 25
  • 195
  • 267
headacheCoder
  • 4,503
  • 8
  • 30
  • 33
  • 4
    By the way, it is not necessary to put a semicolon after a closing brace. The syntactic meaning of this is adding an empty statement between them. This is true of all C-like languages, except for declarations of `struct` and `class` in C and C++. – Eric Jan 04 '12 at 12:06
  • You need to learn the difference between statements and expressions to understand when curlys are omittable. And then a strong understanding of expression cohesion is necessary still. – mario Jan 04 '12 at 12:10

14 Answers14

100

When you omit the braces it will only treat the next statement as body of the condition.

if ($x) echo 'foo';

is the same as

if ($x) { echo 'foo'; }

but remember that

if ($x)
  echo 'foo';
  echo 'bar';

will always print "bar"

Internally it's the other way around: if will only look at the next expression, but PHP treats everything in {} as a single "grouped" expression.

Same for the other control statements (foreach, and so on)

KingCrunch
  • 128,817
  • 21
  • 151
  • 173
  • Very nice and short explanation, thanks! :) Is it working on every control structure? – headacheCoder Jan 04 '12 at 11:56
  • It should. currently don't know (and cannot test) whats about `do{}while($X);`, or `switch´. – KingCrunch Jan 04 '12 at 11:58
  • 1
    @headacheCoder Yes, it works for `for`, `while`, `foreach` and `if`. Also it is like this for every language with a C-like syntax. Do note @tkone's answer, about how it is Good Practice to always use braces. – Eric Jan 04 '12 at 12:01
  • @headacheCoder: It's working with every expression even, see http://php.net/expressions . – hakre Jan 04 '12 at 12:02
  • @Eric Yes, I noted it but that was not part of my question. I always try to write clean and usable code. It was more about just understanding the syntax. :) – headacheCoder Jan 04 '12 at 12:08
  • 3
    There's an exception; it doesn't work with [Exceptions](http://php.net/manual/en/language.exceptions.php). Pun totally intended. – Francisco Presencia Mar 13 '13 at 04:55
  • @FrankPresenciaFandos You mean `try-catch`? Because `Exception` is a class in the first place ;) Yes, an alternative syntax for `try-catch` simply doesn't exists (don't know, if this has a deeper reason, or it is just "forgotten"). – KingCrunch Mar 13 '13 at 08:35
  • XDebug will not stop on / step into a statement within a conditional block that has no braces. Please use braces! – Jon Hudson Feb 19 '15 at 12:10
  • Even for single statement it doesn't always work. `if ( true ) function myFunc() { return true; }` yields error `Syntax error, unexpected T_STRING, expecting '('` – s3c Jan 07 '21 at 09:42
37

There are places where you can, but you never should.

Explicit is always better than implicit.

Who knows when you're going to have to go back and modify old code. It's so easy to miss that stuff and there's nothing gained by doing it.

tkone
  • 22,092
  • 5
  • 54
  • 78
16

It will work fine if you only have one argument inside!. But if you want to omit curly brace you can use colon and end. example:

if(a < 1 ) :
    echo "a is less than 1";
else :
    echo "a is greater than 1";
endif;
site stats
  • 264
  • 2
  • 4
10

As have said you don't wanna learn about shorthand's and accepted answer gives good example about omitting curly braces, but there is something to add. As you can see it's fine to omit curly braces in case of if ($x) echo 'foo';. There is nothing wrong with code, no performance or other issues and it is readable by other developers. And example also shows you that if you write

if ($x)
    echo 'foo';
    echo 'bar';

instead of

if ($x)
    echo 'foo';

echo 'bar';

You can run into unwanted results where bar is printed while you don't want it to be printed and if your code is full of such statements then it will make it harder for you to read your own code and even more harder for others to read it.

I don't wanna learn about shorthand's I just want to understand the conditions about when and where it is possible to omit the curly brackets.

These things are closely related so if you really want to understand where it is possible to omit curly brackets then that should be a must that you understand or are at least aware of shorthand's , have read

  1. PHP Control Structures
  2. The PHP ternary conditional operators and expressions in general

So my big question is: When can I omit the curly braces and in which structure/loop/function?

The curly brace is not required however, for readability and maintenance, many developers would consider it bad style not to include them. Previous 2 links should give you information needed to make your own decisions when you could omit curly brace. for example there is nothing wrong with following code snippets which all do exactly same thing.

With curly brace

if (PHP_VERSION_ID < 70000)
{
    print "PHP >= 7.0 required yours is ";
    print phpversion();
    print "\n";
    exit(1);
}

Is same as

if (PHP_VERSION_ID < 70000) :
    print "PHP >= 7.0 required yours is ";
    print phpversion();
    print "\n";
    exit(1);
endif;

Or you can use the dot operator

if (PHP_VERSION_ID < 80000)
    (print "PHP >= 7.0 required yours is ") . (print phpversion()) . (print "\n") . exit(1);

And you can make use of the ternary conditional operator and even omit if it self besides omitting curly braces

(PHP_VERSION_ID > 70000) ?: (print "PHP >= 7.0 required yours is ") . (print phpversion()) . (print "\n") . exit(1);

Since we only print we can shorten that and strip some print string functions which were here to represent more than one function in statement without curly braces

(PHP_VERSION_ID > 70000) ?: (print "PHP >= 7.0 required yours is " . phpversion() . "\n") . exit(1);

As from php 7 we can use Null coalescing operator

(PHP_VERSION_ID > 70000) ?: null ?? (print "PHP >= 7.0 required yours is ".phpversion() . "\n") . exit(1);

As one can see that there is many ways you can get exactly the same result. That not only applies for this if example but same can be practiced with structure/loop/function. So there is no one answer for your big question. One should consider mainly following.

  1. Is the code you are writing easy to maintain.
  2. Can you answer for your self is there something you win by omitting curly braces.
mkungla
  • 3,390
  • 1
  • 26
  • 37
  • Hmm, I didn't know they added a null coalescing operator to the Elvis operator... neat. But which side of the operator is null, and does it allow unset variables in the conditional block ? – Ber Jun 21 '16 at 05:03
  • 1
    `$I_want_value = $if_im_not_null_use_me ?? $if_first_is_null_use_me ?? $if_second_is_null_use_me;` So You can have as many alternatives as you which if previous variable is NULL; [PHP 7 New-features](http://php.net/manual/en/migration70.new-features.php) – mkungla Jun 21 '16 at 14:14
  • Interesting, so it's an infininary operator... but does it work on undefined variables? I will check the doc. I would think that's the sole purpose of having a null coalescing operator, otherwise why not just use Elvis. ?:) – Ber Jun 22 '16 at 04:27
  • Ah so, ?? does work on unset variables, says the docs. wonderful! This may decrease the massive cruft of isset() calls in PHP. – Ber Jun 22 '16 at 05:11
3

You can use it for simple things like:

if($a === true) continue;

But for some more complicated sub-conditions it may cause you problems:

    $a = false;
    $b = false;
    if ($a === true)
        if ($b === true)
            echo 1;
    else
        echo 2;

With the code above, you would expect to see "2" as output, but you won't.

Iliya Kolev
  • 406
  • 3
  • 4
2

To complement @Marko's answer, be aware that when using the dot operator for this matter, you should enclose each operation in parentheses, otherwise it will reverse the order.

For instance, this code below will print PHP >= 7.0 required yours is 5.6.15.

(print "PHP >= 7.0 required yours is ") . (print phpversion()) . (print "\n");

While this will print 5.6.151PHP >= 7.0 required yours is 1.

print("PHP >= 7.0 required yours is ") . print(phpversion()) . print("\n");

You can also use the and operator for this to work. Like so:

if (PHP_VERSION_ID < 70000)
    print("PHP >= 7.0 required yours is ") and
    print(phpversion()) and
    print("\n");
Community
  • 1
  • 1
Renan Decarlo
  • 53
  • 1
  • 10
2

I omit curly braces in my PHP templates. E.g. you can use loops as follows:

<ul>
    <?php foreach ($var as $value): ?>
        <li><?php echo $value; ?></li>
    <?php endforeach; ?>
</ul>
Georg Leber
  • 3,470
  • 5
  • 40
  • 63
1

When can I omit the curly braces and in which structure/loop/function? I know that I can definitely do so in if and else. But what about while, for and foreach?

For If/else it is possible to have single and multiple statements without curly braces by using the following construct:

<?php
  if ($x):
    echo 'foo';
    echo 'bar';
  else:
    echo 'nofoo';
    echo 'nobar';
  endif;
?>

As described in this answer

For while, for and foreach, only single statements are allowed without curly brackets

<?php
foreach($array as $x => $y)
    $do_something = $x;
?>
Duffmannen
  • 136
  • 1
  • 5
1

For single line statements.

If you tried to do

foreach($array as $x => $y)
    $do_something = $x;
    $do_something_else = $y;

Unless I am mistaken the php interpreter will take the second line under the foreach statement as being outside of the implied braces

Due to the indentation if you came back to this code at a later date, or another developer looked at your work it would be confusing.

As such it is generally wise to always use braces with these statements. It will save later headache/confusion

Pete Mitchell
  • 2,879
  • 1
  • 16
  • 22
0

The answer is easy. This is the same in C/C++.

if, if/else, if/else if/ else and loops => If the next statement is one single line, you can omit the curly braces.

Ex:

for($i= 0; $i<=100; $i++)
{
    if($i % 7 == 0)
    {   
        echo $i . "<br>";
    }

}

It can also be written in this way:

for($i= 0; $i<=100; $i++) if($i % 7 == 0) echo $i . "<br>";
AlexPac
  • 620
  • 1
  • 5
  • 8
0

It's possible when you have only one expression after your clause/

For example,

foreach($var as $value)
    if(1 + 1 == 2) {
        $arr[] = $value;
    };

is correct, but

foreach($var as $value)
    $somevar = $var;
    if(1 + 1 == 2) {
        $arr[] = $value;
    };

is not, and php interpreter will think that if statement is outside foreach

nikans
  • 2,468
  • 1
  • 28
  • 35
-1

PHP shorthand expression was available since PHP 5.3

$condition ? $value_if_true : $value_if_false

$a ? $b : ( $c ? $d : ( $e ? $f : $g ) )
Midhun
  • 1,107
  • 10
  • 24
-1

enter image description here

At one point in my life, I also ommitted the curly braces if the next statement only have one line.

Back then I thought that my code looks cool and sleek and that I should save line of codes as much as possible.

But I realized that being explicit is more helpful in the long run, especially in regards to maintainability of the project.

Also, we should never sacrifice significant things over microperformance.

kapitan
  • 2,008
  • 3
  • 20
  • 26
-1

It's perfectly fine to omit the {} curly braces when you perform single action inside the code block, but if you will execute two or more actions on that block, then you will need to use the {} curly braces for them, or else you will get an error.

// Single action
    if (true)
        return 'true';

// Compound
    if (true) {
        $value = true;
        return $value;
    }

In single action, you can omit the {} braces because you will return the value directly.

In compound action, you have to put the braces because you will perform two things:

  1. assign the boolean 'true' to the $value
  2. return that $value

I hope this does make sense.