Ternary operator when casting a variable - php

While writing is_numeric($var) ? (Int)$var : (String)$var;, I was wondering if it could be possible to move the ternary operator to the part where I cast the variable:
echo (is_numeric($var) ? Int : String)$var;
Not to my surprise, it didn't work:
PHP Parse error: syntax error, unexpected '$var' (T_VARIABLE)
Is this at all possible? Or maybe something close to what I'm trying to do? It's more of a curiosity thing than a need to use it.

Yes it's possible. This should work for you:
var_dump((is_numeric($var)?(int)$var :(string)$var));
As an example to test it you can easy do this:
$var = 5;
var_dump((true?(int)$var :(string)$var)); //Or var_dump((false?(int)$var :(string)$var));
Output:
int(5) //string(1) "5"
EDIT:
They only way i could think of to do something similar to what you want would be this:
settype($var, (is_numeric($var)?"int":"string"));
var_dump($var);

No; this is not possible. The ternary operator expects an expression which the casting operator is not.
It would however be possible to use first-class functions, which are expressions, with the ternary operator like so:
$toInt = function($var) {
return (int) $var;
};
$toString = function($var) {
return (string) $var;
};
$foo = "10";
var_dump(call_user_func(is_numeric($foo) ? $toInt : $toString, $foo));

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

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

In PHP can you use || (or) in the same way as javascript?

Can I use the OR argument in this way in PHP? Meaning if $x is null assign $y to $var.
$var = $x || $y
Simple question, cheers!
No. PHP's boolean operators evaluate to true or false, not the value of the operands as in Javascript. So you'll have to write something like this:
$var = $x ? $x : $y;
Since 5.3, you can write this though, which basically has the same effect as Javascript's ||:
$var = $x ?: $y;
That requires that $x exists though, otherwise you should check with isset first.
No, in this way you assign a boolean to $var
$var = $x or $y;
means: $var is true, if $x or $y. You are looking for the ternary operator
$var = isset($x) ? $x : $y;
// or
$var = empty($x) ? $y : $x;
The ternary operator always works like
$var = $expressionToTest
? $valueIfExpressionTrue
: $valueIfExpressionFalse
With PHP5.3 or later you can omit $valueIfExpressionTrue
$var = $expressionToTest ?: $valueIfExpressionFalse;
$x=0;
$y=9;
$var = ($x)?$x:$y;
echo $var;
if variable x is null then var will be 9,or else it will be value of x.
This question is already answered, but I juist wanted to point your attention to the other usage of OR and AND operators in PHP
defined('SOMETHING') OR define('SOMETHING', 1);
if this case if SOMETHING is not defined (defined('SOMETHONG') evaluates to false) expression after OR will be evaluated
$admin AND show_admin_controls();
if $admin is evaluated to boolean true, show_admin_controls() function will be called
I usually use it to check if some constant is defined, but I've seen a lot of examples of good-looking and really well-readable code using this constructions for other purposes.

Can you pass by reference while using the ternary operator?

Simple question, simple code. This works:
$x = &$_SESSION['foo'];
This does not:
$x = (isset($_SESSION['foo']))?&$_SESSION['foo']:false;
It throws PHP Parse error: syntax error, unexpected '&'. Is it just not possible to pass by reference while using the conditional operator, and why not? Also happens if there's a space between the ? and &.
In the very simply case, this expression, which is illegal;
$c = condition ? &$a : &$b; // Syntax error
can be written like this:
$c = &${ condition ? 'a' : 'b' };
In your specific case, since you're not assigning by reference if the condition is false, a better option seems to be:
$x = isset($_SESSION['foo']) ? $x = &$_SESSION['foo'] : false;
Simple answer: no. You'll have to take the long way around with if/else. It would also be rare and possibly confusing to have a reference one time, and a value the next. I would find this more intuitive, but then again I don't know your code of course:
if(!isset($_SESSION['foo'])) $_SESSION['foo'] = false;
$x = &$_SESSION['foo'];
As to why: no idea, probably it has to with at which point the parser considers something to be an copy of value or creation of a reference, which in this way cannot be determined at the point of parsing.
Let's try:
$x =& true?$y:$x;
Parse error: syntax error, unexpected '?', expecting T_PAAMAYIM_NEKUDOTAYIM in...
$x = true?&$y:&$x;
Parse error: syntax error, unexpected '&' in...
So, you see, it doesn't even parse. Wikken is probably right as to why it's not allowed.
You can get around this with a function:
function &ternaryRef($cond, &$iftrue, &$iffalse=NULL) {
if ($cond)
return $iftrue;
else
return $iffalse;
}
$x = 4;
$a = &ternaryRef(true, $x);
xdebug_debug_zval('a');
$b = &ternaryRef(false, $x);
xdebug_debug_zval('b');
gives:
a: (refcount=2, is_ref=1),int 4
b: (refcount=1, is_ref=0),null
Unfortunately, you can't.
$x=false;
if (isset($_SESSION['foo']))
$x=&$_SESSION['foo'];
The commentary on this bug report might shed some light on the issue:
http://bugs.php.net/bug.php?id=53117.
In essence, the two problems with trying to assign a reference from the result of a ternary operator are:
Expressions can't yield references, and
$x = (expression) is not a reference assignment, even if (expression) is a reference (which it isn't; see point 1).

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