PHP ternary operator vs null coalescing operator

后端 未结 13 1688
南笙
南笙 2020-11-22 15:58

Can someone explain the differences between ternary operator shorthand (?:) and null coalescing operator (??) in PHP?

When do they behave d

相关标签:
13条回答
  • 2020-11-22 16:22

    Ran the below on php interactive mode (php -a on terminal). The comment on each line shows the result.

    var_export (false ?? 'value2');   // false
    var_export (true  ?? 'value2');   // true
    var_export (null  ?? 'value2');   // value2
    var_export (''    ?? 'value2');   // ""
    var_export (0     ?? 'value2');   // 0
    
    var_export (false ?: 'value2');   // value2
    var_export (true  ?: 'value2');   // true
    var_export (null  ?: 'value2');   // value2
    var_export (''    ?: 'value2');   // value2
    var_export (0     ?: 'value2');   // value2
    

    The Null Coalescing Operator ??

    • ?? is like a "gate" that only lets NULL through.
    • So, it always returns first parameter, unless first parameter happens to be NULL.
    • This means ?? is same as ( !isset() || is_null() )

    Use of ??

    • shorten !isset() || is_null() check
    • e.g $object = $object ?? new objClassName();

    Stacking Null Coalese Operator

            $v = $x ?? $y ?? $z; 
    
            // This is a sequence of "SET && NOT NULL"s:
    
            if( $x  &&  !is_null($x) ){ 
                return $x; 
            } else if( $y && !is_null($y) ){ 
                return $y; 
            } else { 
                return $z; 
            }
    

    The Ternary Operator ?:

    • ?: is like a gate that lets anything falsy through - including NULL
    • Anything falsy: 0, empty string, NULL, false, !isset(), empty()
    • Same like old ternary operator: X ? Y : Z
    • Note: ?: will throw PHP NOTICE on undefined (unset or !isset()) variables

    Use of ?:

    • checking empty(), !isset(), is_null() etc
    • shorten ternary operation like !empty($x) ? $x : $y to $x ?: $y
    • shorten if(!$x) { echo $x; } else { echo $y; } to echo $x ?: $y

    Stacking Ternary Operator

            echo 0 ?: 1 ?: 2 ?: 3; //1
            echo 1 ?: 0 ?: 3 ?: 2; //1
            echo 2 ?: 1 ?: 0 ?: 3; //2
            echo 3 ?: 2 ?: 1 ?: 0; //3
        
            echo 0 ?: 1 ?: 2 ?: 3; //1
            echo 0 ?: 0 ?: 2 ?: 3; //2
            echo 0 ?: 0 ?: 0 ?: 3; //3
    
        
            // Source & Credit: http://php.net/manual/en/language.operators.comparison.php#95997
       
            // This is basically a sequence of:
    
     
            if( truthy ) {}
            else if(truthy ) {}
            else if(truthy ) {}
            ..
            else {}
    

    Stacking both, we can shorten this:

            if( isset($_GET['name']) && !is_null($_GET['name'])) {
                $name = $_GET['name'];
            } else if( !empty($user_name) ) {
                 $name = $user_name; 
            } else {
                $name = 'anonymous';
            }
    
    

    To this:

            $name = $_GET['name'] ?? $user_name ?: 'anonymous';
    

    Cool, right? :-)

    0 讨论(0)
  • 2020-11-22 16:22

    Scroll down on this link and view the section, it gives you a comparative example as seen below:

    <?php
    /** Fetches the value of $_GET['user'] and returns 'nobody' if it does not exist. **/
    $username = $_GET['user'] ?? 'nobody';
    /** This is equivalent to: **/
    $username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
    
    /** Coalescing can be chained: this will return the first defined value out of $_GET['user'], $_POST['user'], and 'nobody'. **/
    $username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
    ?>
    

    However, it is not advised to chain the operators as it makes it harder to understand the code when reading it later on.

    The null coalescing operator (??) has been added as syntactic sugar for the common case of needing to use a ternary in conjunction with isset(). It returns its first operand if it exists and is not NULL; otherwise it returns its second operand.

    Essentially, using the coalescing operator will make it auto check for null unlike the ternary operator.

    0 讨论(0)
  • 2020-11-22 16:23

    For the beginners:

    Null coalescing operator (??)

    Everything is true except null values and undefined (variable/array index/object attributes)

    ex:

    $array = [];
    $object = new stdClass();
    
    var_export (false ?? 'second');                           # false
    var_export (true  ?? 'second');                           # true
    var_export (null  ?? 'second');                           # 'second'
    var_export (''    ?? 'second');                           # ""
    var_export ('some text'    ?? 'second');                  # "some text"
    var_export (0     ?? 'second');                           # 0
    var_export ($undefinedVarible ?? 'second');               # "second"
    var_export ($array['undefined_index'] ?? 'second');       # "second"
    var_export ($object->undefinedAttribute ?? 'second');     # "second"
    

    this is basically check the variable(array index, object attribute.. etc) is exist and not null. similar to isset function

    Ternary operator shorthand (?:)

    every false things (false,null,0,empty string) are come as false, but if it's a undefined it also come as false but Notice will throw

    ex

    $array = [];
    $object = new stdClass();
    
    var_export (false ?: 'second');                           # "second"
    var_export (true  ?: 'second');                           # true
    var_export (null  ?: 'second');                           # "second"
    var_export (''    ?: 'second');                           # "second"
    var_export ('some text'    ?? 'second');                  # "some text"
    var_export (0     ?: 'second');                           # "second"
    var_export ($undefinedVarible ?: 'second');               # "second" Notice: Undefined variable: ..
    var_export ($array['undefined_index'] ?: 'second');       # "second" Notice: Undefined index: ..
    var_export ($object->undefinedAttribute ?: 'second');     # "Notice: Undefined index: ..
    

    Hope this helps

    0 讨论(0)
  • 2020-11-22 16:25

    Null Coalescing operator performs just two tasks: it checks whether the variable is set and whether it is null. Have a look at the following example:

    <?php
    # case 1:
    $greeting = 'Hola';
    echo $greeting ?? 'Hi There'; # outputs: 'Hola'
    
    # case 2:
    $greeting = null;
    echo $greeting ?? 'Hi There'; # outputs: 'Hi There'
    
    # case 3:
    unset($greeting);
    echo $greeting ?? 'Hi There'; # outputs: 'Hi There'
    

    The above code example states that Null Coalescing operator treats a non-existing variable and a variable which is set to NULL in the same way.

    Null Coalescing operator is an improvement over the ternary operator. Have a look at the following code snippet comparing the two:

    <?php /* example: checking for the $_POST field that goes by the name of 'fullname'*/
    # in ternary operator
    echo "Welcome ", (isset($_POST['fullname']) && !is_null($_POST['fullname']) ? $_POST['fullname'] : 'Mr. Whosoever.'); # outputs: Welcome Mr. Whosoever.
    # in null coalecing operator
    echo "Welcome ", ($_POST['fullname'] ?? 'Mr. Whosoever.'); # outputs: Welcome Mr. Whosoever.
    

    So, the difference between the two is that Null Coalescing operator operator is designed to handle undefined variables better than the ternary operator. Whereas, the ternary operator is a shorthand for if-else.

    Null Coalescing operator is not meant to replace ternary operator, but in some use cases like in the above example, it allows you to write clean code with less hassle.

    Credits: http://dwellupper.io/post/6/php7-null-coalescing-operator-usage-and-examples

    0 讨论(0)
  • 2020-11-22 16:27

    The major difference is that

    1. Ternary Operator expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE but on the other hand Null Coalescing Operator expression (expr1) ?? (expr2) evaluates to expr1 if expr1 is not NULL

    2. Ternary Operator expr1 ?: expr3 emit a notice if the left-hand side value (expr1) does not exist but on the other hand Null Coalescing Operator (expr1) ?? (expr2) In particular, does not emit a notice if the left-hand side value (expr1) does not exist, just like isset().

    3. TernaryOperator is left associative

      ((true ? 'true' : false) ? 't' : 'f');
      

      Null Coalescing Operator is right associative

      ($a ?? ($b ?? $c));
      

    Now lets explain the difference between by example :

    Ternary Operator (?:)

    $x='';
    $value=($x)?:'default';
    var_dump($value);
    
    // The above is identical to this if/else statement
    if($x){
      $value=$x;
    }
    else{
      $value='default';
    }
    var_dump($value);
    

    Null Coalescing Operator (??)

    $value=($x)??'default';
    var_dump($value);
    
    // The above is identical to this if/else statement
    if(isset($x)){
      $value=$x;
    }
    else{
      $value='default';
    }
    var_dump($value);
    

    Here is the table that explain the difference and similarity between '??' and ?:

    Special Note : null coalescing operator and ternary operator is an expression, and that it doesn't evaluate to a variable, but to the result of an expression. This is important to know if you want to return a variable by reference. The statement return $foo ?? $bar; and return $var == 42 ? $a : $b; in a return-by-reference function will therefore not work and a warning is issued.

    0 讨论(0)
  • 2020-11-22 16:30

    Both of them behave differently when it comes to dynamic data handling.

    If the variable is empty ( '' ) the null coalescing will treat the variable as true but the shorthand ternary operator won't. And that's something to have in mind.

    $a = NULL;
    $c = '';
    
    print $a ?? '1b';
    print "\n";
    
    print $a ?: '2b';
    print "\n";
    
    print $c ?? '1d';
    print "\n";
    
    print $c ?: '2d';
    print "\n";
    
    print $e ?? '1f';
    print "\n";
    
    print $e ?: '2f';
    

    And the output:

    1b
    2b
    
    2d
    1f
    
    Notice: Undefined variable: e in /in/ZBAa1 on line 21
    2f
    

    Link: https://3v4l.org/ZBAa1

    0 讨论(0)
提交回复
热议问题