Is there in PHP a shorthand for:
function a() {...}
function b() {...}
$c = a();
$c = ($c) ? $c : b();
In javascript you can simply do:
$c = a() || b();
but in PHP, if you do this, $c will be a boolean (which is normal, but I want to know if there exists another shorthand which does what I want).
UPDATE
Thank you guys for all the answers.
The shortest way to do it seems to be:
$c = a() ?: b();
I personally also like:
$c = a() or $c = b();
for the good readability.
This may work:
$c = ($c) ? : b();
It is not possible to do it like in Javascript, but you can use the short version of the ternary construct:
$c = a() ?: b();
Another way is to use or's lesser precedence. It is not as pretty, but it actually comes closer to how you can do it in Javascript:
$c = a() or $c = b();
Another way of representing the above, so that it is easier to understand, is to wrap it in parentheses:
($c = a()) or ($c = b());
The assignment operator, =, has greater precedence than the "or" operator (do not confuse it with the || operator, though), which means that the part after or will not be executed if the first part evaluates to true. It is essentially the same as this:
if ($c = a()) {
// Do nothing
} elseif ($c = b()) {
// Do nothing
}
Both expressions are assignments that evaluate to either true or false. If the first expression is true then $c will be a(). Otherwise the second expression will be be tried, and because it is the last expression, and because nothing is done after that, $c will just be equal to b().
In any case, this is not really an important problem. If you use time on worrying about the aesthetics of variable assignment then you are not worrying about the right things.
I like it this way, but its a question of preference
if( !$c=a() ){
$c=b();
}
as in
if(!$User=$db->getUserFromID($user_id)){
$User=$db->getUserFromUsername($username);
}
There is possibility to use black magic like this. I’d prefer to write it in longer form though.
function a() {
return false;
}
function b() {
return true;
}
($c = a()) || ($c = b());
echo $c;
You can do this:
$c = a() OR $c = b();
You can use the assignment operator to your benefit.
($c = a()) || ($c = b());
echo $c;
Here's a demo : http://codepad.org/kqnKv2y4
I'm assuming that you are looking for this.
http://www.php.net/manual/en/language.operators.comparison.php#language.operators.comparison.ternary
$c = a() ? $c : b();
I'm not sure what you're going for though.
Related
I want to initialise a variable with the contents of another variable, or a predefined value, if said other variable is not set.
I know I could use
if(isset($var1)){
$var2 = $var1;
} else{
$var2 = "predefined value";
}
I thought doing it like this would be more elegant:
$var2 = $var1 || "predefined value";
Last time I checked, this did work (or my memory is fooling me). But here, when I print $var2, it is always 1. It seems PHP checks if the statement $var1 || "predefined value" is true and assigns 1 to $var2.
I want "predefined value" to be assigned to $var2, in case $var1 doesn't exist.
Any peculiarity of PHP I'm missing here to make this work?
Thanks in advance
I generally create a helper function like this:
function issetor(&$var, $def = false) {
return isset($var) ? $var : $def;
}
and call it with the reference of the variable :
$var2 = issetor($var1, "predefined");
I just read that in PHP 7, there will be a new abbreviation for
$c = ($a === NULL) ? $b : $a;
It will look like this:
$c = $a ?? $b;
And can be extended like this:
$c = $a ?? $b ?? $c ?? $d;
explanation: $c will be assigned the first value from the left, which is not NULL.
how could I get the following code to print out aaa.bbb.ccc ??
Currently all I get is a parse error for each eval() line.
This is a abstract code version. Finally I want the users to be able to select fields of a database table to be searched through. Something like a combination of
if (strpos("$field1.$field2.$field3",$search) !== false) ...
$filter = "\$x=\$a.\$b.\$c";
$a = "a";
$b = "a";
$c = "a";
eval($filter);
echo $x.",";
$a = "b";
$b = "b";
$c = "b";
eval($filter);
echo $x.",";
$a = "c";
$b = "c";
$c = "c";
eval($filter);
echo $x;
To fix your current code, change the following:
$filter = "\$x=\$a.\$b.\$c";
To
$filter = '$x=$a.$b.$c;';
But to use eval() on user input is a big security hole in your code. Try some different approach, like checking if the input is present in $search by use of a regular expression and the preg_match_all() function.
I am trying to modularise a lengthy if..else function.
$condition = "$a < $b";
if($condition)
{
$c++;
}
Is there any way of translating the literal string into a logical expression?
I am trying to modularise a lengthy if..else function.
You don't need to put the condition in a string for that, just store the boolean true or false:
$condition = ($a < $b);
if($condition)
{
$c++;
}
the values of $a and $b may change between definition of $condition and its usage
One solution would be a Closure (assuming that definition and usage are happening in the same scope):
$condition = function() use (&$a, &$b) {
return $a < $b;
}
$a = 1;
$b = 2;
if ($condition()) {
echo 'a is less than b';
}
But I don't know if this makes sense for you without remotely knowing what you are trying to accomplish.
Use lambda if you know variables that are enough to determine result
$f = function ($a, $b) { return $a < $b; }
if ($f($x, $y)){}
you could do this using eval. not sure why you wouldn't just evaluate the condition immediately, though.
<?php
$a=0;
$b=1;
function resultofcondition()
{
global $a,$b;
return $a<$b;
}
if(resultofcondition()){
echo " You are dumb,";
}else{
echo " I am dumb,";
}
$a=1;
$b=0;
if(resultofcondition()){
echo " You were correct.";
}else{
echo " in your face.";
}
?>
Indeed thanks for commenting that out, was missing the GLOBAL parameter, for those who voted down, what would that code output? ¬_¬ w/e have fun xD
Why do I get a parse error with this code:
$func = "do_{$something}" = $func();
?
It should be correct because
$func = "do_{$something}";
$func = $func();
works...
Because the assignment works from right to left.
Look at this code as an example:
$a = $b = 3;
If assignment would work from the left, this'll be parsed as:
$a = $b;
$b = 3;
which would give you an undefined variable error.
Instead, it's parsed as:
$b = 3;
$a = $b;
What you're trying to do is equivalent to the following:
"do_{$something}" = $func();
$func = "do_{$something}";
Which obviously has syntax errors. Your second block of code doesn't read well, as you're overwriting the function name variable with the result of the function call. A cleaner way to do this would be:
$result = call_user_func('do_' . $something);
It is invalid because the = operator is right-associative. This means that the right-most = is executed first, so your code is actually equivalent to this:
"do_{$something}" = $func();
$func = "do_{$something}";
I'd like to be able to inquire my program as to what variable a variable is a reference of. Is there a way to do this? I looked in all the usual sources and couldn't find anything, perhaps my search terms were goofy. Thanks.
you can just compare references with === operator
Note: this only compares object references.
$obj1 = new DateTime();
$obj2 = $obj1;
if($obj2 === $obj1){
echo "Equal";
}else {
echo "Not Equal";
}
// Outputs Equal
$obj2 = new DateTime();
if($obj2 === $obj1){
echo "Equal";
}else {
echo "Not Equal";
}
// Outputs Not Equal
The only code I personally know is to directly query what a class is of, not to retrieve it:
if($var instanceof Your_Class) { }
If you know the variable is strictly a class, you can use:
get_class();
If you use the function on a non-object, it appears to return an E_WARNING. I'd suggest code such as this:
$class_known = false;
if(is_object($class))
{
$class_name = get_class($class);
$class_known = false;
}
if($class_known)
{
echo $class_name;
}
If you're dealing with objects, I believe === performs the test you want.
$obj1 = new Object;
$obj2 = $obj1;
echo ($obj1 === $obj2) ? 'same' : 'not same'; // same
$obj2 = new Object;
echo ($obj1 === $obj2) ? 'same' : 'not same'; // not same
As far as I know, there's no direct way to test if two variables point to the same thing. Something like this might work:
function is_reference_of(&$a, &$b)
{
// if an object, use strict comparison
if (is_object($a)) return $a === $b;
// definitely not a reference to each other if they aren't the same value
if ($a !== $b) return false;
$tmp = $a;
if (is_array($a))
{
$a = 0;
// if $b is no longer an array, then it must be a reference to $a
$is_ref = !is_array($b);
}
else
{
$a = !$a;
// if $b is no longer equal to $tmp, then it must be a reference to $a
$is_ref = ($b !== $tmp);
}
// make sure to reset $a back to what it was
$a = $tmp;
return $is_ref;
}
$a = 0;
$b = 0;
is_reference_of($a, $b); // false
$b = &$a;
is_reference_of($a, $b); // true
Huge disclaimer: I haven't really thought this through carefully. There could be all sorts of side effects to doing something like the above. Consider this just a proof of concept to get you started
If you are always working with arrays or classes, you could try setting a temporary field or property in one and seeing if it exists in the other, etc. That would be less prone to errors than the above code that changes the entire variable.
Note that the order of the parameters in the above function does not matter.
Update: With objects, you can use === and skip the function altogether. I've updated the function slightly to detect what type of variable is being tested and react accordingly. The disclaimer still applies.