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
Related
I can use ?? operator in PHP to handle an index of array which is not defined.
I am confused if null safe operator offers me same or extends ?? operator's functionality?
Edit:
I can do in existing PHP versions to check if there is a specific property is defined in the array:
$user_actions = ['work' => 'SEO','play' => 'Chess', 'drink' => 'coffee'];
$fourth_tag = $user_tags['eat'] ?? "n/a";
I am trying to understand whether null safe operator is offering me something better to do so?
Null coalescing operator (??) work as an if statement it takes two values if first is null then it is replaced by second.
$a = null;
$b = $a ?? 'B';
Here $b will get the value B as $a is null;
In PHP8, NullSafe Operator (?->) was introduced will gives option of chaining the call from one function to other. As per documentation here: (https://www.php.net/releases/8.0/en.php#nullsafe-operator)
Instead of null check conditions, you can now use a chain of calls with the new nullsafe operator. When the evaluation of one element in the chain fails, the execution of the entire chain aborts and the entire chain evaluates to null.
Here is the example from documentation:
$country = null;
if ($session !== null) {
$user = $session->user;
if ($user !== null) {
$address = $user->getAddress();
if ($address !== null) {
$country = $address->country;
}
}
}
But in PHP8 you can simply do this:
$country = $session?->user?->getAddress()?->country;
So the working of both operators is significantly different.
is there a possiblity to use the null coalescing operator AND echo in one expression like this:
echo htmlspecialchars($_POST['email']) ?? '';
As a short form of
if (isset($_POST['email'])) {
echo htmlspechars($_POST['email']);
}
Any ideas?
The null coalescing operator won't emit a E_NOTICE when a parameter isn't defined.
So you could do $email = htmlspecialchars($_POST['email'] ?? '');
Note that the null coalescing operator is applied to the variable ($_POST['email']) and not to the result of htmlspecialchars().
If you wanted to use conditional ternary operator (?:), then you should have to check if the variable is set before operating on it.
if ( isset($_POST['email']) ) {
$email = htmlspecialchars($_POST['email'] ?: '');
}
Note that isset() will be TRUE if the variable is set (or, in other words, it is defined and has a value different than NULL).
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
I want to get a value from the session, but use a default if it is not defined. And ofcourse I want to circumvent the PHP notice.
You can write a function that does this
function get(&$var, $default){
if(isset($var)) return $var;
return $default;
}
echo get($foo, "bar\n");
$foobar = "foobar";
echo get($foobar, "ERROR");
Example in action
Is there a way to do this without defining this function in every file?
You can define it in one script and then require_once that script in your other scripts
You could also just use the ternary operator:
$myVar = isset($var)?$var:$default;
From PHP 7, you can now use the null coalescing operator :
$var ?? $default
that does exactly like your function
Use this concise alternative:
isset($myVar) || $myvar=$default;
The || operator is short circuit, it will not evaluate second operant if the first one be evaluated true.
The Null coalescing operator has been added to PHP version 7.0, what it does is replaces
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
with a shorter version:
$username = $_GET['user'] ?? 'nobody';
What the line above does, is check if $_GET['user'] is set, and not null, then it will assign that to the $username variable, if $_GET['user'] is not set (and thus null) it will default to the 'nobody' string so $username is nobody.
Your code should look like:
echo $foo ?? "bar\n";
$foobar = "foobar";
echo $foobar ?? "ERROR";
Use less code to do what you need.
You don't need to specify the variable again using the _?_:_ format.
echo $var?:"default";
Is the same as
echo $var?$var:"default";
Now as far as an empty check, you could use # to mute notices, I'm not sure of the technical ramifications, but you're already doing your own checking while using this format:
echo #$non_existing_var?:"default";
Some examples:
<?php
$nope = null;
$yup = "hello";
echo ($nope?:$yup) . "\n" ;
echo ($yup?:$nope) . "\n" ;
$items = [ 'one', 'two', false, 'three', 'four', null ];
foreach($items as $item):
echo($item?:"default shown (".var_export($item,true).")")."\n";
endforeach;
echo(#$non_existing?:"default for non-existant variable!");
?>
Output:
$ php variabledefault.php
hello
hello
one
two
default shown (false)
three
four
default shown (NULL)
default for non-existant variable!%
You could use my tiny library ValueResolver in this case, for example:
$myVar = ValueResolver::resolve($var, $default);
and don't forget to use namespace use LapaLabs\ValueResolver\Resolver\ValueResolver;
There are also ability to typecasting, for example if your variable's value should be integer, so use this:
$id = ValueResolver::toInteger('6 apples', 1); // returns 6
$id = ValueResolver::toInteger('There are no apples', 1); // returns 1 (used default value)
Check the docs for more examples
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')));