Best way to give a variable a default value (simulate Perl ||, ||= ) - php

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;

Related

Message: Trying to get property of non-object error in php [duplicate]

Is there in PHP something similar to JavaScript's:
alert(test || 'Hello');
So, when test is undefined or null we'll see Hello, otherwise - we'll see the value of test.
I tried similar syntax in PHP but it doesn't seem to be working right... Also I've got no idea how to google this problem..
thanks
Edit
I should probably add that I wanted to use it inside an array:
$arr = array($one || 'one?', $two || 'two?'); //This is wrong
But indeed, I can use the inline '? :' if statement here as well, thanks.
$arr = array(is_null($one) ? "one?" : $one, is_null($two) ? "two ?" : $two); //OK
you can do echo $test ?: 'hello';
This will echo $test if it is true and 'hello' otherwise.
Note it will throw a notice or strict error if $test is not set but...
This shouldn't be a problem since most servers are set to ignore these errors. Most frameworks have code that triggers these errors.
Edit: This is a classic Ternary Operator, but with the middle part left out. Available since PHP 5.3.
echo $test ? $test : 'hello'; // this is the same
echo $test ?: 'hello'; // as this one
This only checks for the truthiness of the first variable and not if it is undefined, in which case it triggers the E_NOTICE error. For the latter, check the PHP7 answer below (soon hopefully above).
From PHP 7 onwards you can use something called a coalesce operator which does exactly what you want without the E_NOTICE that ?: triggers.
To use it you use ?? which will check if the value on the left is set and not null.
$arr = array($one ?? 'one?', $two ?? 'two?');
See #Yamiko's answer below for a PHP7 solution https://stackoverflow.com/a/29217577/140413
echo (!$test) ? 'hello' : $test;
Or you can be a little more robust and do this
echo isset($test) ? $test : 'hello';
As per the latest version use this for the shorthand
$var = $value ?? "secondvalue";
One-liner. Super readable, works for regular variables, arrays and objects.
// standard variable string
$result = #$var_str ?: "default";
// missing array element
$result = #$var_arr["missing"] ?: "default";
// missing object member
$result = #$var_obj->missing ?: "default";
See it in action: Php Sandbox Demo
I'm very surprised this isn't suggested in the other answers:
echo isset($test) ? $test : 'hello';
From the docs isset($var) will return false if $var doesn't exist or is set to null.
The null coalesce operator from PHP 7 onwards, described by #Yamiko, is a syntax shortcut for the above.
In this case:
echo $test ?? 'hello';
If you want to create an array this way, array_map provides a more concise way to do this (depending on the number of elements in the array):
function defined_map($value, $default) {
return (!isset($value) || is_null($value)) ? $default : $value;
// or return $value ? $default : $value;
}
$values = array($one, $two);
$defaults = array('one', 'two');
$values = array_map('defined_map', $values, $defaults);
Just make sure you know which elements evaluate to false so you can apply the right test.
Since php7.4, you can use the null coalescing assignment, so that you can do
$arr = array($one ??= "one?", $two ??= "two ?");
See the docs here
There may be a better way, but this is the first thing that came to my mind:
echo (!$test) ? "Hello" : $test;
Null is false in PHP, therefore you can use ternary:
alert($test ? $test : 'Hello');
Edit:
This also holds for an empty string, since ternary uses the '===' equality rather than '=='
And empty or null string is false whether using the '===' or '==' operator. I really should test my answers first.
Well, expanding that notation you supplied means you come up with:
if (test) {
alert(test);
} else {
alert('Hello');
}
So it's just a simple if...else construct. In PHP, you can shorten simple if...else constructs as something called a 'ternary expression':
alert($test ? $test : 'Hello');
Obviously there is no equivalent to the JS alert function in PHP, but the construct is the same.
alert((test == null || test == undefined)?'hello':test);
I recently had the very same problem.This is how i solved it:
<?php if (empty($row['test'])) {
echo "Not Provided";}
else {
echo $row['test'];}?></h5></span></span>
</div>
Your value in the database is in variable $test..so if $test row is empty then echo Not Provided

Get value of variable when isset() is used in PHP ternary shorthand operator

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');

Assign variable within condition if true

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.
}

Assign if variable is set

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;
}

PHP equivalent for Ruby's or-equals (foo ||=bar)?

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;

Categories