Multiple assignments to the same variable - php

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

Related

PHP - How to change reference of a function's pointer parameter from the definition

I'm using PHP 7.4. From the function call, I need to change the reference of a variable passed to it by reference. This is the simplified version of my code to make it clear and more focus on the problem.
function f(&$p){
$p['x'] = [];
$p = &$p['x'];
//$p represents $a['x'] here
}
$a = [];
$p = &$a;
f($p);
//$p revert to $a here
$p['y'] = 3;
echo json_encode($a);
I expected the function to change the reference of variable $p from pointing to $a to $a['x']. Within the definition scope, it did. But the reference reverted back to $a after the call.
So from the above code, instead of this {"x" : {"y" : 3}}, I get this {"x" : {}, "y" : 3} as the result.
I assume that a function's pointer parameter can only be used to change the value not the reference. But is there any way to do the same for a reference considering that reference is also a type of value?.
I realized what you needed, your solution is this.
function &f(&$p){
$p['x'] = [];
$p = &$p['x'];
return $p;
}
$a = [];
$p = &$a;
$p = &f($p);
$p['y'] = 3;
echo json_encode($a);

Can I use the eval function in this case?

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.

Functions and the OR operator

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.

PHP - How can I use curly bracket with variable correctly?

I read php document and I saw this:
class foo{
var $bar = 'I am a bar';
}
$foo = new foo();
$identity = 'bar';
echo "{$foo->$identity}";
And I saw somebody wrote like this:
if (!isset($ns->job_{$this->id})){
//do something
}
But when I tried with this code, It didn't work:
$id1 = 10;
$no = 1;
echo ${id.$no};
Can you guys tell me why it didn't work and when I can use braces with variable correctly?
Live example
Brackets can be used on object types, for instance, to simulate a array index. Supposing that $arr is an array type and $obj an object, we have:
$arr['index'] ===
$obj->{'index'}
You can make it more fun, for instance:
$arr["index{$id}"] ===
$obj->{"index{$id}"}
Even more:
$arr[count($list)] ===
$obj->{count($list)}
Edit: Your problem --
variable of variable
// Your problem
$id1 = 10;
$no = 1;
$full = "id{$no}";
var_dump($$full); // yeap! $$ instead of $
What are you expecting?
$id = 10;
$no = 1;
echo "${id}.${no}"; // prints "10.1"

Is there a way to bind variables? PHP 5

Using PHP 5 I would like to know if it is possible for a variable to dynamically reference the value
of multiple variables?
For example
<?php
$var = "hello";
$var2 = " earth";
$var3 = $var.$var2 ;
echo $var3; // hello earth
Now if I change either $var or $var2 I would like $var3 to be updated too.
$var2 =" world";
echo $var3;
This still prints hello earth, but I would like to print "hello world" now :(
Is there any way to achieve this?
No, there is no way to do this in PHP with simple variables. If you wanted to do something like this in PHP, what you'd probably do would be to create a class with member variables for var1 and var2, and then have a method that would give you a calculated value for var3.
This should do the trick. I tested it on PHP 5.3 and it worked. Should also work on any 5.2.x version.
You could easily extend this with an "add"-Method to allow an arbitrary number of strings to be placed in the object.
<?php
class MagicString {
private $references = array();
public function __construct(&$var1, &$var2)
{
$this->references[] = &$var1;
$this->references[] = &$var2;
}
public function __toString()
{
$str = '';
foreach ($this->references as $ref) {
$str .= $ref;
}
return $str;
}
}
$var1 = 'Hello ';
$var2 = 'Earth';
$magic = new MagicString($var1, $var2);
echo "$magic\n"; //puts out 'Hello Earth'
$var2 = 'World';
echo "$magic\n"; //puts out 'Hello World'
No. Cannot be done without utilizing some sort of custom String class.
Check the PHP manual for types and variables, especially this passage:
By default, variables are always
assigned by value. That is to say,
when you assign an expression to a
variable, the entire value of the
original expression is copied into the
destination variable. This means, for
instance, that after assigning one
variable's value to another, changing
one of those variables will have no
effect on the other. For more
information on this kind of
assignment, see the chapter on
Expressions.
it's a bit late, but it's interesting question.
You could do it this way:
$var = "hello";
$var2 = " earth";
$var3 = &$var;
$var4 = &$var2;
echo $var3.$var4; // hello earth
From my point of view the following code is a little closer to the required:
$a = 'a';
$b = 'b';
$c = function() use (&$a, &$b) { return $a.$b; };
echo $c(); // ab
$b = 'c';
echo $c(); // ac
Create a function.
function foobar($1, $2){
$3 = "$1 $2";
return $3;
}
echo foobar("hello", "earth");
echo foobar("goodbye", "jupiter");

Categories