How does this operator '??' work in php code.? [duplicate] - php

This question already has answers here:
Reference Guide: What does this symbol mean in PHP? (PHP Syntax)
(24 answers)
Closed 6 years ago.
$array = ['name'=>'Jonh', 'lastname' => 'Doe', 'nickname' => 'JD'] ;
$person = $array['name'] ?? null ; //try to change null to true or false<br>
echo $person;
$person = $array['age'] ?? null; //no Undefined index: age<br>
echo $person;
I can't find any documentation about it.

It's new PHP7 "null coalescing operator":
// 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';
While
short form of Ternary Operator ?: does nearly the same for years (as of at least PHP 5.3)

You can find doc about it in php.net here.
EDIT:
It works like combination of isset() and ?
So code like:
return isset($a)?$a:$b
could be something like:
return $a??$b

This is a null coalescing operator- Please refer to this link

Related

PHP Null coalescing operator usage [duplicate]

This question already has answers here:
Is there a "nullsafe operator" in PHP?
(3 answers)
Closed 3 months ago.
Having this example code using the tertiary operator in PHP, I get the 'default value'.
$myObject = null; // I'm doing this for the example
$result = $myObject ? $myObject->path() : 'default value';
However, when I try to use the null coalescing operator to do this, I get the error
Call to a member function path() on null
$result = $myObject->path() ?? 'default value';
What am I doing wrong with the ?? operator?
?? will work if the left hand side is null or not set, however in your case the left hand cannot be evaluated if $myObject is null.
What you should consider in your case is the new nullsafe operator available with PHP 8 (so need to wait on that)
$result = $myObject?->path() ?? 'default value';
This should make the left hand side null if $myObject is null
Until then you can just do:
$result = ($myObject ? $myObject->path() : null) ?? 'default value';
This differs from your first use case in that you get default value if either $myObject or $myObject->path() are null
These snippets do not work in the same way:
$result = $myObject ? $myObject->path() : 'default value'; says: use 'default value' if $myObject is NULL
$result = $myObject->path() ?? 'default value'; says: use the default if $myObject->path() returns NULL - but that call can only return something if the object itself is not NULL

using PHP's null coalescing operator on an array

I am using PHP's null coalescing operator described by http://php.net/manual/en/migration70.new-features.php.
Null coalescing operator ΒΆ
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.
<?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';
?>
I noticed the following doesn't produce my expected results which was to add a new phone index to $params whose value is "default".
$params=['address'=>'123 main street'];
$params['phone']??'default';
Why not?
You don't add anything to params. Your given code simply generates an unused return value:
$params['phone'] ?? 'default'; // returns phone number or "default", but is unused
Thus, you will still have to set it:
$params['phone'] = $params['phone'] ?? 'default';
The correct answer above from #mrks can be shortened to:
$params['phone'] ??= 'default';
RFC: Null coalesce equal operator

Faster way to select either SESSION or COOKIE value if exists? [duplicate]

I want to do this for 5 sets of parameters is this the best way to do it or is there some simpler syntax?
if(isset($_GET['credentials'])) $credentials = $_GET['credentials'];
if(isset($_POST['credentials'])) $credentials = $_POST['credentials'];
if(isset($_POST['c'])) $credentials = $_POST['c'];
if(isset($_GET['c'])) $credentials = $_GET['c'];
Also with this same hierarchy.
PHP 7 introduced the The null coalescing operator (??), which you can use like this:
$result = $var ?? 'default';
This will assign default to result if:
$var is undefined.
$var is NULL
You can also use multiple ?? operators:
$result = $null_var ?? $undefined_var ?? 'hello' ?? 'world'; // Result: hello
To answer your question, you should be doing something like:
$credentials = $_GET['c'] ?? $_POST['c'] ?? $_POST['credentials'] ?? $_GET['credentials'];
More details here and here

Make condition in one line? [duplicate]

This question already has answers here:
PHP conditionals, brackets needed?
(7 answers)
Closed 6 years ago.
Usually I made the if/else condition like this:
if(empty($data['key']))
{
$err = "empty . $key ";
}
but I saw that there is the ternary operator.
I really don't understand how this works.. Someone could show me an example? How can I convert this condition in the ternary logic?
I'm not sure what you're trying to do with your code.
You check if its empty, and then try to set $err to a value by concentrating an empty value.
Perhaps this is more likely what you want.
// Ternary operator
$err = empty($data['key']) ? "empty key" : '';
# -----------IF-----------------THEN ---- ELSE
// Ternary operator (nesting) (not recommended)
// Changing empty() to isset() you must rewrite the entire logic structure.
$err = empty($data) ? 'empty' : is_numeric($data) ? $data : 'not numeric';
# ---------IF--------- THEN -------ELSEIF-----------THEN-----ELSE
// Null Coalescing operator ?? available in PHP 7.
$err = $data['key'] ?? 'empty value';
# ---- IF ISSET USE --- ELSE value
// Nesting
$err = $data['key'] ?? $_SESSION['key'] ?? $_COOKIE['key'] ?? 'no key';
# IF ISSET USE -- IF ISSET USE ------ IF ISSET USE ------ELSE

Using short circuiting to get first non-null variable

What's the equivalent of the following (based in JS style) in PHP:
echo $post['story'] || $post['message'] || $post['name'];
So if story exists then post that; or if message exist post that, etc...
It would be (PHP 5.3+):
echo $post['story'] ?: $post['message'] ?: $post['name'];
And for PHP 7:
echo $post['story'] ?? $post['message'] ?? $post['name'];
There is a one-liner for that, but it's not exactly shorter:
echo current(array_filter(array($post['story'], $post['message'], $post['name'])));
array_filter would return you all non-null entries from the list of alternatives. And current just gets the first entry from the filtered list.
Since both or and || do not return one of their operands that's not possible.
You could write a simple function for it though:
function firstset() {
$args = func_get_args();
foreach($args as $arg) {
if($arg) return $arg;
}
return $args[-1];
}
As of PHP 7, you can use the null coalescing operator:
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.
// 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';
Building on Adam's answer, you could use the error control operator to help suppress the errors generated when the variables aren't set.
echo #$post['story'] ?: #$post['message'] ?: #$post['name'];
http://php.net/manual/en/language.operators.errorcontrol.php
You can try it
<?php
echo array_shift(array_values(array_filter($post)));
?>
That syntax would echo 1 if any of these are set and not false, and 0 if not.
Here's a one line way of doing this which works and which can be extended for any number of options:
echo isset($post['story']) ? $post['story'] : isset($post['message']) ? $post['message'] : $post['name'];
... pretty ugly though. Edit: Mario's is better than mine since it respects your chosen arbitrary order like this does, but unlike this, it doesn't keep getting uglier with each new option you add.
Because variety is the spice of life:
echo key(array_intersect(array_flip($post), array('story', 'message', 'name')));

Categories