How can I call functions on PHP using eval()? is it possible?
I wanna do something like this
<?php
$function1 = 'echo';
$function2 = 'implode';
$arr = array('arg1', 'arg2');
eval("$function1 ($function2(', ', $arr));");
?>
Or call other functions with multiple params?
Is eval() what I'm looking for?
Many thanks!
You don't need to eval anything:
$function1 = 'print';
$function2 = 'implode';
$arr = array('arg1', 'arg2');
$function1($function2(', ', $arr));
In fact, you can even use variable, variables:
$foo = 'print';
$bar = 'foo';
$$bar('hello');
Related
I have the following a PHP object with the following properties:
Object:
-Advanced
--Data
To access it in PHP I would have to do the following:
$object->Advanced->Data
Now I want to define a string which has a syntax like this:
$string = "Advanced->Data";
How do I proceed from here to be able to use:
$object->$string = "Something";
So that in the end
$object->Advanced->Data = "Something";
I couldn't figure out using eval or $object->{$string}
If I try to use $object->$string
PHP creates a new property called "Advanced->Data", basically not interpreting the -> Operator.
Though it is a hack, try this, it should work for your case
$arr = array();
$arr['Advanced']['Data'] = 'something';
$string = json_decode(json_encode($arr), 0);
echo $string->Advanced->Data;
Though it is a hack, this can also fetch your desire
$string = &$object->Advanced->Data;
$string = "here we go";
var_dump($object->Advanced->Data);
Probably eval() is not best solution, but it can be useful in your case:
class obj2 {
public $Data = 'test string';
}
class obj1 {
public $Advanced;
public function __construct() {
$this->Advanced = new obj2();
}
}
$test = new obj1();
$string1 = "\$test->Advanced->Data = 'new string';";
$string2 = "\$result = \$test->Advanced->Data;";
eval($string1);
eval($string2);
echo $result . PHP_EOL;
Output will be "new string".
Once try this,
$string = "Advanced->Data";
$arr = explode("->",$string);
$temp = $object->{$arr[0]}->$arr[1];
But this is specific condition. Let me know your requirement if this is not the answer.
Is it possible to create a variable variable pointing to an array or to nested objects? The php docs specifically say you cannot point to SuperGlobals but its unclear (to me at least) if this applies to arrays in general.
Here is my try at the array var var.
// Array Example
$arrayTest = array('value0', 'value1');
${arrayVarTest} = 'arrayTest[1]';
// This returns the correct 'value1'
echo $arrayTest[1];
// This returns null
echo ${$arrayVarTest};
Here is some simple code to show what I mean by object var var.
${OBJVarVar} = 'classObj->obj';
// This should return the values of $classObj->obj but it will return null
var_dump(${$OBJVarVar});
Am I missing something obvious here?
Array element approach:
Extract array name from the string and store it in $arrayName.
Extract array index from the string and store it in $arrayIndex.
Parse them correctly instead of as a whole.
The code:
$arrayTest = array('value0', 'value1');
$variableArrayElement = 'arrayTest[1]';
$arrayName = substr($variableArrayElement,0,strpos($variableArrayElement,'['));
$arrayIndex = preg_replace('/[^\d\s]/', '',$variableArrayElement);
// This returns the correct 'value1'
echo ${$arrayName}[$arrayIndex];
Object properties approach:
Explode the string containing the class and property you want to access by its delimiter (->).
Assign those two variables to $class and $property.
Parse them separately instead of as a whole on var_dump()
The code:
$variableObjectProperty = "classObj->obj";
list($class,$property) = explode("->",$variableObjectProperty);
// This now return the values of $classObj->obj
var_dump(${$class}->{$property});
It works!
Use = & to assign by reference:
$arrayTest = array('value0', 'value1');
$arrayVarTest = &$arrayTest[1];
$arrayTest[1] = 'newvalue1'; // to test if it's really passed by reference
print $arrayVarTest;
In echo $arrayTest[1]; the vars name is $arrayTest with an array index of 1, and not $arrayTest[1]. The brackets are PHP "keywords". Same with the method notation and the -> operator. So you'll need to split up.
// bla[1]
$arr = 'bla';
$idx = 1;
echo $arr[$idx];
// foo->bar
$obj = 'foo';
$method = 'bar';
echo $obj->$method;
What you want to do sounds more like evaluating PHP code (eval()). But remember: eval is evil. ;-)
Nope you can't do that. You can only do that with variable, object and function names.
Example:
$objvar = 'classObj';
var_dump(${$OBJVarVar}->var);
Alternatives can be via eval() or by doing pre-processing.
$arrayTest = array('value0', 'value1');
$arrayVarTest = 'arrayTest[1]';
echo eval('return $'.$arrayVarTest.';');
eval('echo $'.$arrayVarTest.';');
That is if you're very sure of what's going to be the input.
By pre-processing:
function varvar($str){
if(strpos($str,'->') !== false){
$parts = explode('->',$str);
global ${$parts[0]};
return $parts[0]->$parts[1];
}elseif(strpos($str,'[') !== false && strpos($str,']') !== false){
$parts = explode('[',$str);
global ${$parts[0]};
$parts[1] = substr($parts[1],0,strlen($parts[1])-1);
return ${$parts[0]}[$parts[1]];
}else{
return false;
}
}
$arrayTest = array('value0', 'value1');
$test = 'arrayTest[1]';
echo varvar($test);
there is a dynamic approach for to many nested levels:
$attrs = ['level1', 'levelt', 'level3',...];
$finalAttr = $myObject;
foreach ($attrs as $attr) {
$finalAttr = $finalAttr->$attr;
}
return $finalAttr;
What a short way to do something like this?
$variable = array($variable);
To avoid repeating $variable
you could make your own function that takes $variable by reference.
function makeArray(&$var){
$var = array($var);
}
$test = "whatever";
makeArray($test);
var_dump($test);
$variable = (array) $variable;
I'm having some issues with the StdClass() object in PHP..
I'm using it to send information (a string and boolean) to a function.
Outside the function, it works great.
$args = new StdClass();
$args->str = "hej";
$args->ic = TRUE;
fun($arg);
This is then the function called:
function fun($args) {
$str = $args->str;
$ignore_case = $args->ic;
echo $str;
echo $ignore_case;
}
which just writes "stric" instead of the variable contents.
Is there a way to use StdClass to transfer this data and read it correctly?
//Martin
function fun($args) {
$str = $args->str;
$ignore_case = $args->ic;
echo $str;
echo $ignore_case;
}
add $ and second echo should be $ignore_case - I believe
$args = new StdClass();
$args->str = "hej";
$args->ic = TRUE;
fun($arg);
Where is $arg defined? Your call should be fun($args).
You forgot the $ before the variable names in your echos.
echo $str;
echo $ignore_case;
Also, fun($arg); should be fun($args);
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");