In PHP I often write lines like
isset($foo)? NULL : $foo = 'bar'
In ruby there is a brilliant shortcut for that, called or equals
foo ||= 'bar'
Does PHP have such an operator, shortcut or method call? I cannot find one, but I might have missed it.
As of PHP7, you can use the Null Coalesce Operator:
The coalesce, or ??, operator is added, which returns the result of its first operand if it exists and is not NULL, or else its second operand.
So you can write:
$foo = $foo ?? 'bar';
and it will use $foo if it is set and not null or assign "bar" to $foo.
On a sidenote, the example you give with the ternary operator should really read:
$foo = isset($foo) ? $foo : 'bar';
A ternary operation is not a shorthand if/else control structure, but it should be used to select between two expressions depending on a third one, rather than to select two sentences or paths of execution
I really like the ?: operator. Unfortunately, it is not yet implemented on my production environment. So, if I were to make this look ruby-ish, I would go for something like:
isset($foo) || $foo = 'bar';
Or, if you want it even shorter (slower, and may yield unexpected results):
#$foo || $foo = 'bar';
You could create your own function:
function setIfNotSet(&$var, $value) {
if(!isset($var)) {
$var = $value;
}
}
I find it readable, concise and performant to just do:
isset($foo) or $foo = 'bar';
As of PHP 5.3 it's possible to use $foo ?: 'bar'
Unless you expect $foo to be false
[edit]
Forget it. It still raises E_NOTICE if $foo is no set.
From the manual:
Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.
It's not exactly the same though. Hope it helps anyway.
No. According to w3schools, that operator doesn't exist.
Also, the PHP code you posted is rather cryptic. I prefer something like this:
if (!isset($foo)) $foo = 'bar';
The most similar with ruby is this:
$foo or $foo = 'bar';
$foo is false if
$foo = 0;
$foo = '0';
$foo = NULL;
$foo = '';
$foo = array();
$foo = FALSE;
Related
What are the shortest equivalents to the two following statements which do not generate a notice (when error_reporting is E_ALL):
$foo = empty($row['foo']) ? 42 : $row['foo'];
$foo = empty($row['foo']) ? null : $row['foo'];
The variable in empty() could be non existent or an empty string.
This has been bugging me for so long. I have been searching for alternatives across the Internet, including SO.
The null coalescing operator does not seem to work:
$foo = $bar ?? 42;
var_dump($foo);
returns '', not 42.
Are my examples really the shortest form to write it?
The null-coalescing operator (??) will only check for either null or undefined variables.
The shorthand ternary operator (?:) will check for falsy values but can't handle undefined variables by itself.
Therefore, the only shorter way to write these two lines would be to use a combination of both:
$foo = ($row['foo'] ?? null) ?: 42;
and:
$foo = ($row['foo'] ?? null) ?: null;
Whether this is easily readable is debatable, but that should work.
In using the shorter ternary operator:
$foo = isset($_GET['bar']) ?: 'hello';
If $_GET['bar'] is set, is it possible for $foo to return the value of $_GET['bar'] instead of true?
Edit: I understand the old school ternary works e.g.,
$foo = isset($_GET['bar']) ? $_GET['bar'] : 'hello';
but I want to use the newschool ternary which is the even shorter version
It sounds like you are asking about the new (as of PHP 7) null coalesce operator. You can do something like:
$foo = $_GET['bar'] ?? 'hello';
echo $foo;
Which if $_GET['bar'] is null will set $foo to hello.
The first operand from left to right that exists and is not NULL. NULL if no values are defined and not NULL. Available as of PHP 7.
Functional demo: https://3v4l.org/0CfbE
$foo = $_GET['bar'] ?? 'hello';
echo $foo . "\n";
$_GET['bar'] = 'good bye';
$foo = $_GET['bar'] ?? 'hello';
echo $foo;
Output:
hello
good bye
Additional reading on it: http://www.lornajane.net/posts/2015/new-in-php-7-null-coalesce-operator
yes you would do it like this
$foo = isset($_GET['bar']) ? $_GET['bar'] : 'hello';
something like this:
$foo = isset($_GET['bar']) ? $_GET['bar'] : 'hello';
I'm not sure I understand your question, but is it something like:
$foo = isset($_GET['bar']) ? true : 'hello';
This will give you one(true) if that variable is set or just hello if it's not.
The answer is no (in PHP5 at least, see chris's answer for PHP7 only). For this reason I tend to use a helper function e.g.
function isset_or(&$variable, $default = NULL)
{
return isset($variable) ? $variable : $default;
}
$foo = isset_or($_GET['bar'], 'hello');
I know you can assign a variable in a condition like this:
if ($var = $foo)
However I don't need to do anything in the condition itself, so I'm often left with empty brackets. Can I simply assign $var if $foo is true in some other way without needing to do something else later?
Also can I assign $var to $foo if $foo is true but if $foo is false do something else? Like:
if ($var = !$foo) {
if ($var = !$bar) {
//Etc...
}
}
Basically I want to have more fallbacks/defaults.
#chandresh_cool's suggestion is right but to allow multiple possiblities / fallbacks you would have to nest the ternary expressions:
$var = ($foo == true) ? $foo:
($bar == true) ? $bar:
($fuzz == true) ? $fuzz:
$default;
Note: the first 3 lines end in colons not semi-colons.
However a simpler solution is to do the following:
$var = ($foo||$bar||$fuzz...);
Although this is a very old post. Fallback logic on falsify values can be coded like this.
$var = $foo ?: $bar ?: "default";
In this case when $foo is a falsified value (like false, empty string, etc.) it will fall back to $bar otherwise it uses $foo.
If bar is a falsified value, it will fallback to the string default.
Keep in mind, that this works with falsified values, and not only true.
example:
$foo = "";
$bar = null;
$var = $foo ?: $bar ?: "default";
$var will contain the text default because empty strings and null are considered "false" values.
[update]
In php 7 you can use the new null coalescing operator: ??, which also checks if the variable exists with isset(). This is usefull for when you are using a key in an array.
Example:
$array = [];
$bar = null;
$var = $array['foo'] ?? $bar ?? "default";
Before php 7 this would have given an Undefined index: foo notice. But with the null coalescing operator, that notice won't come up.
Instead you can Use ternary operator like this
$var = ($foo == true)?$foo:"put here what you want";
You can assign values like this:
$var = $foo;
Setting them within an if statement is also possible, PHP will evaluate the resulting $var which you just assigned.
I dont really get your question, but you could do something like this:
if(!($var = $foo)){
//something else.
}
In PHP I find myself writing code like this frequently:
$a = isset($the->very->long->variable[$index])
? $the->very->long->variable[$index]
: null;
Is there a simpler way to do this? Preferably one that doesn't require me to write $the->very->long->variable[$index] twice.
An update, because PHP 7 is now out and is a game-changer on this point ; the previous answers are about PHP 5.
PHP 7 solves this issue. Because you are true at saying that it is frequent to write this in PHP, and that's absolutely not elegant.
In PHP 7 comes the Null Coalesce Operator (RFC), which is a perfect shorthand for the isset ternary condition.
Its goal is to replace this type of condition:
$var = isset($dict['optional']) ? $dict['optional'] : 'fallback';
By that:
$var = $dict['optional'] ?? 'fallback';
Even better, the null coalesce operators are chainable:
$x = null;
# $y = null; (undefined)
$z = 'fallback';
# PHP 7
echo $x ?? $y ?? $z #=> "fallback"
# PHP 5
echo isset($x) ? $x : (isset($y) ? $y : $z)
The null coalesce operator acts exactly like isset() : the subject variable's value is taken if:
The variable is defined (it exists)
The variable is not null
Just a note for PHP beginners: if you use the ternary condition but you know that the subject variable is necessarily defined (but you want a fallback for falsy values), there's the Elvis operator:
$var = $dict['optional'] ?: 'fallback';
With the Elvis operator, if $dict['optional'] is an invalid offset or $dict is undefined, you'll get a E_NOTICE warning (PHP 5 & 7). That's why, in PHP 5, people are using the hideous isset a ? a : b form when they're not sure about the input.
Sadly no, because the RFC has been declined. And because isset is not a function but a language construct you cannot write your own function for this case.
Note: Because this is a language construct and not a function, it cannot be called using variable functions.
If you only assign null instead of the non set variable, you can use:
$a = #$the->very->long->variable[$index];
# makes that instruction throw no errors
Assuming you know that $the->very->long->variable is set, and you're just worried about the array index....
$x = $the->very->long->variable;
$a = isset($x[$index]) ? $x[$index] : null;
Or for a more generic variant that you can use around you code:
function array_valifset($arr,$k, $default=null) {
return isset($arr[$k]) ? $arr[$k] : $default;
}
then call it like this for any array value:
$a = array_valifset($the->very->long->variable,$index);
I stumbled across the same problem and discovered that referencing an array element does not issue a notice or warning but returns null (at least PHP 5.6).
$foo = ['bar' => 1];
var_dump($bar = &$foo['bar']); // int 1
var_dump($baz = &$foo['baz']); // null
Inside an if statement:
if($bar = &$foo['bar']) {
echo $bar;
}
if($baz = &$foo['baz']) {
echo $baz;
}
I love doing this sort of thing in Perl: $foo = $bar || $baz to assign $baz to $foo if $bar is empty or undefined. You also have $foo ||= $bletch which will only assign $bletch to $foo if $foo is not defined or empty.
The ternary operator in this situation is tedious and tiresome. Surely there's a simple, elegant method available in PHP?
Or is the only answer a custom function that uses isset()?
PHP 5.3 has a shorthand ?: operator:
$foo = $bar ?: $baz;
Which assigns $bar if it's not an empty value (I don't know how this would be different in PHP from Perl), otherwise $baz, and is the same as this in Perl and older versions of PHP:
$foo = $bar ? $bar : $baz;
But PHP does not have a compound assignment operator for this (that is, no equivalent of Perl's ||=).
Also, PHP will make noise if $bar isn't set unless you turn notices off. There is also a semantic difference between isset() and empty(). The former returns false if the variable doesn't exist, or is set to NULL. The latter returns true if it doesn't exist, or is set to 0, '', false or NULL.
In PHP 7 we finally have a way to do this elegantly. It is called the Null coalescing operator. You can use it like this:
$name = $_GET['name'] ?? 'john doe';
This is equivalent to
$name = isset($_GET['name']) ? $_GET['name']:'john doe';
Thanks for all the great answers!
For anyone else coming here for a possible alternative, here are some functions that help take the tedium out of this sort of thing.
function set_if_defined(&$var, $test){
if (isset($test)){
$var = $test;
return true;
} else {
return false;
}
}
function set_unless_defined(&$var, $default_var){
if (! isset($var)){
$var = $default_var;
return true;
} else {
return false;
}
}
function select_defined(){
$l = func_num_args();
$a = func_get_args();
for ($i=0; $i<$l; $i++){
if ($a[$i]) return $a[$i];
}
}
Examples:
// $foo ||= $bar;
set_unless_defined($foo, $bar);
//$foo = $baz || $bletch
$foo = select_defined($baz, $bletch);
I'm sure these can be improved upon.
A common idiom to stay compatible with older PHP versions is:
$var = $bool or $var = "default";
// If I use it, then only with excessive spaces for clarity.
This works for values that can be evaluated in boolean context. The advantage here is that it also gives you said debug e_notice should the variable be undefined.
In PHP earlier than 7.*, one may use ?: for an undefined variable having errors locally suppressed with an #:
$foo = #$bar ?: $baz;
this is another good format for the isset case
isset($foo) || $foo= $bar;
another simple way and will give you more control as you can add more conditions and assign to another variable in the same time
$foo = (isset($oData['foo']))?$bar['foo']:'default value';
A possible solution: defaultFor( )
Unless we have a factory solution (which is indeed very annoying), I'd recommend the following little helper. It does the job in most cases:
function defaultFor(&$x,$default=null) {
if(!isset($x)) $x = $default;
}
//-------------------- Now you can do this: --------------
defaultFor($a,"Jack"); // if $a is not set, it will be "Jack"
defaultFor($x); // no more notices for $x but keep it !isset
I hope this is close to what you wanted to achieve. It will not give you any notices if you use it with a nonexistent variable, and it's quite convenient. Surely it has a drawback: the default value always gets calculated beforehand so don't use it with anything heavy as a second parameter, like a file_get_contents or something. In those cases, you're better off with isseting.
I think in general doing something like this:
$foo = $bar || $baz;
is a bad idea, unless $bar and $baz are both booleans. If they aren't:
$bar = 10;
$baz = 11;
then the question becomes: what determines if something is true or false? Most people would probably expect zero to be false, and everything else to be true. But with some languages (for example Ruby), only false and nil are false, which means both 0 and 1 would be true. Because of this cross language ambiguity, I think it best to be explicit in these cases:
if ($bar !== 0) {
$foo = $bar;
} else {
$foo = $baz;
}
or:
$foo = $bar !== 0 ? $bar : $baz;