$var = $input || 'default' in PHP - php

Sorry if the title isn't clear enough, but in Javascript you can do this :
var input = null;
var fruit = input || 'default';
Just wondering if PHP supports that kind of checking, currently I'm using :
$fruit = !empty($input)?$input : 'default' ;
Which is quite good, but of course the Javascript method is more elegant.
Thanks

|| returns a boolean in PHP, so this operator cannot be used for it. Same for or.
However, you can use the binary ?: operator if you are using PHP5.3+:
$fruit = $input ?: 'default';
However, it has one great disadvantage destroying its usefulness in the single case where it would be most useful (when importing request variables):
$fruit = $_REQUEST['fruit'] ?: 'strawberry';
This would throw an E_NOTICE in your face if $_REQUEST['fruit'] didn't exist. So in this case you still need the ternary version of it with an isset or !empty check.

PHP doesn't because it returns a Boolean, not the last evaluated expression like in JavaScript or Ruby.
You can use a ternary or the new binary form that ThiefMaster mentions.

In PHP, the || operator returns a boolean, thus you will always get either true or false from it. The reason it's possible in JS is because it will return a value.
So, no, not possible.

Related

Is it really bad practice to assign a variable multiple times, as per a NetBeans warning?

I have a function that is basically like this:
//Init variable
$ready = FALSE;
//if submit
filter_input(INPUT_POST, "submit") ? $ready = TRUE : $ready = FALSE ;
//return the result
return $ready;
NetBeans is warning me against multiple assignments. In other languages this is pretty normal to do. It is the only NetBeans warning that I get. Is this code okay to use?
Think of the ternary operator ?: as a function call:
$var = decideOnValue($condition, $valueIfConditionTrue, $valueIfConditionFalse);
and you'll understand why Netbeans is generating those warnings.
The common usages of the ?: operator are:
decide on what value to assign to a variable based on a condition, without resorting to the longer if/else construct
call a function or another, based on a condition, again to shorten the code
Doing more than this is dangerous as it can lead to bugs. For your particular example, if you have a typo and you mistakenly write $redy = FALSE then you introduce a subtle bug, even if the code is syntactically correct, and the PHP static analyser that comes with Netbeans tries to avoid this.
You can simplify your code to a single assignment so you don't even need the ternary operator:
$ready = filter_input(INPUT_POST, "submit");
You can rewrite you code to be a little less, and Netbeans won't paranoid you:
$ready = filter_input(INPUT_POST, "submit") ? TRUE : FALSE;
return $ready;
Slight misuse of the syntax. Try:
$ready = filter_input(INPUT_POST, "submit") ? true : false;
$ready must be either true or false at this point so there is no need to initialize to false beforehand.

PHP, Why doesn't anyone use the ?: operator?

I cant seem to find any discussion about this.
In JavaScript to check if something exists, and use a default if it doesn't is like this:
var myvariable = mysetting || 3
In PHP from what I understand, the same thing can be done like this:
$myvariable = $mysetting ?: 3;
Am i completely off on this? I understand the implications of not using isset() and not_empty() and all that, but if I just want to know if the variable exists and is truthy otherwise use a default - this should work I think. Does this syntax have any hidden bad things about it?
Because it doesn't work. That code will still throw a notice Notice: Undefined variable: mysetting in C:\wamp\www\x.php on line, which might be visible to the user, depending on the PHP settings. Apart from that, it will work. If notices are suppressed, then the end result is correct.
So, to get around that, you can either use isset, which isn't really a function, but a language construct, and is specifically designed to do this check:
$myvariable = isset($mysetting)? $mysetting: 3;
Or you can suppress the notice using the # operator:
$myvariable = #$mysetting ?: 3;
For this specific case, maybe it's acceptable, but in general the use of # is frowned upon by many. Personally, I would rather use a couple more characters and make it feel less 'dirty', but it's a matter of opinion.
Another reason why people may not use it, is that it's relatively new (PHP 5.3). Not everyone might know of this new syntax or be comfortable with it. They have been used to isset for years, and old habits die hard.
Those statements are not equivalent. From what I have found the javascript is equivalent to:
if (!mysetting) {
myvariable = 3;
} else {
myvariable = mysetting;
}
Whereas the equivalent PHP statement using the ternary operator would be:
$mysetting = isset($myvariable) ? $myvariable : 3;
aka:
if( isset($myvariable) ) {
$mysetting = $myvariable;
} else {
$mysetting = 3;
}
The ternary operator is essentially a shorthand for and if/else statement, and the first operand is interpreted as a logical expression.

PHP Shorthand If Else

Is there a way to do the following, but in short if/then syntax:
if($method->isAbstract()) {
$details['abstract'] = true;
}
If I do:
$details['abstract'] = $method->isAbstract() ? true : null;
It is not quite the same, because the array key abstract is always set. I only way the array key set if isAbstract() is true. To clarify, if isAbstract() is false, don't set the key in the array.
Thanks.
I don't have a PHP interpreter at hand, but I guess this will work:
$method->isAbstract() && $details['abstract'] = true;
Update: yes, it works → http://codepad.org/lW23FR0j
I wouldn't worry too much about trying to shorten three lines of code, which in all honesty could be written in one line anyway:
if ( $obj->method() ) $data['key'] = 'value' ;
However, as #Mischa's answer demonstrated, there are shorter ways. You could use the logical operator && to perform assignment as well:
$obj->method() && $data['key'] = 'value' ;
In this method, the expression on the right is evaluated if the expression on the left is "true".
Another method is the new shorter ternary operator which excludes the second expression. While you presented the long-form ternary as an alternative in your original question, you could also consider the new format provided since PHP 5.3
!$obj->method() ?: $data['key'] = 'value' ;
Since we're not using the second expression, we invert our test in the first expression. No longer checking for a positive, we are now looking for a negative. When the negative is found, our assignment takes place.
I don't provide this answer to encourage you to avoid 3-line solutions, but only to encourage you to feel free to explore shorter solutions from time to time as they often times lead to parts of the language you may not have otherwise discovered.

Ternary if statement involving php class

Can someone please explain to me the following line of php?
($myobjectfunction = object::function('letsgo')) ? eval($myobjectfunction) : false;
I understand objects and their functions. Is this php saying if $myobjectfunction is defined then eval $myobjectfunction, otherwise do nothing? Because in the code I am reading, object hasn't yet been defined before this line (sometimes).
This line assigns the returned value from the function object::function('letsgo') to the variable $myobjectfunction. If the return was a "truthy" value (evaluates to boolean TRUE), the contents of that variable are then evaluated as PHP code (eval). If the initial return was FALSE, no further action is taken. The false at the end basically does nothing.
This works because PHP will return the value from an assignment, even though it isn't usually used for anything. In the case of your bit of code, however, the return from the assignment is used to determine which branch of the ternary operator to take since it is enclosed in parentheses.
$x = 3;
// returns 3 even if we don't use it...
This is an unusual idiom, because the parentheses are around the initial assignment.
($myobjectfunction = object::function('letsgo')) ? eval($myobjectfunction) : false;
//^^---------------------------------------------^^^
A more typical usage of the ternary operator would assign the output of either side of the ? to the variable on the left, based on the condition to the right of the = like:
$myobjectfunction = object::function('letsgo') ? $someothervalue : false;
It's difficult to tell exactly what's going on here. I'm assuming you have substituted actual values in order to 'simplify' the example, but the use of keywords actually clouds the matter.
The declaration of the class 'object' doesn't need to be before this statement, so long as the object class is defined at some point during the code execution.
This code is equivalent to:
$myobjectfunction = object::function('letsgo');
if( $myobjectfunction ) {
eval( $myobjectfunction );
}
else {
false;
}
In other words, assign the result of object::function( 'letsgo' ) to a variable. If that variable is "truthy" (i.e. not false, null, or 0, or another value that evaluates like false) then eval its contents; otherwise do nothing.
ya you pretty much got it, well its saying IF $myobjectfunction has successfully been returned a positive result (ie: not false, 0, or null) the eval the new variable object, but i probably wouldnt use "false" in the else bit., id probaby use null.
Now for this to do anything, "object" does need to be defined
this is a strange piece of code though, in my own honest opinion

Conditional operator with only true statement

I want to set a variable to a value, but only if a condition is true.
Instead of doing the following:
if($myarray["foo"]==$bar){
$variablename=$myarray["foo"];
}
This can end up being quite long if the variable names are long, or perhaps it involves arrays, when it's quite simple what I want to do — set a value if a condition is true.
I would like to use the conditional operator, something like this:
$variablename=($myarray["foo"]=="bar")? $myarray["foo"]......
But this fails because I don't want the variable to be set at all if the statement is false.
Basically, what I'm trying to do is make the first example shorter. Perhaps the conditional operator is not the way though...
Does anyone have any suggestions?
It doesn't get much shorter than:
if($condition) $var = $value;
IMO, the best way to make your code sample shorter is:
if($myarray["foo"] == $bar)
$variablename = $myarray["foo"];
FYI, the name of the operator you're asking about isn't "the ternary operator", it's the conditional operator.
Since you ask, a way you could actually use the conditional operator to do what you're asking is:
$myarray['foo'] == $bar ? $variablename = $myarray['foo'] : null;
but that's somewhat horrifically ugly and very unmaintainable.
You could do this, but I wouldn't as it is pretty unreadable and stupid:
$myarray["foo"] == $bar ? $variablename = $myarray["foo"] : 0;
or
$myarray["foo"] == $bar && $variablename = $myarray["foo"];
Your right, ternary is not the way to go. It's there to handle the if and else part of the statement.
Just stick with the regular if statement.
if($myarray["foo"]==$bar) $variablename=$myarray["foo"];
The "problem" you have isn't really a problem. Your example code is very clear and maintainable. I would really say leave it like it is.
You -could- remove the braces, but that will have an impact on maintainability.
Your other alternative is to create a set_if_true(mixed array, string key, boolean conditional) wrapper function. It hides what is really happening but depending on your specific implementation it is a good option. (For instance a configuration type object, or caching backend)
Put != instead of == and ?: instead of just ?..
$variablename = ($myarray["foo"] != "bar") ?: $myarray["foo"];
is the same as
if($myarray["foo"] != "bar"){} else { $variablename = $myarray["foo"]; }
It might not be the smartest solution but it works. I like this one more
if($myarray["foo"] != "bar") {$variablename = $myarray["foo"]};
Set the variable to itself in the false case:
$variablename=($myarray["foo"]=="bar")? $myarray["foo"] : $variablename
You can put the original expression in the else part of the ternary operation, but if you want to guarantee single evaluation of the expression then you'll have to use a temporary variable and an if statement.
Ternary isn't the way, even though it can be written so that ternary works.
The reason is this: you're trying to use it in a way it's not intended, which will make your code awkward for other developers to read.

Categories