Class calling member function through Eval() - php

Yes, I am quite aware of how horrible Eval() is, I have no choice, it is for an assignment and the professor has instructed us to use it.
I am having trouble figuring out why PHP won't let me call a class's member function from within the class when using Eval(). For example:
$code="class evalTest{
function f1(){
echo 'f1';
f2();
}
function f2(){
echo 'f2';
}
}
$x=new evalTest();
$x->f2();
$x->f1();";
eval($code);
echo 'test';
The above code will print out:
f2f1
and the rest of the page will be blank. It seems like the entire PHP script stops as soon as I call a function from within a function through Eval(). Even the final "echo 'test';" is not printed.
Is there some trick to getting this to work, or is this a limitation of Eval()? Again, I would avoid using Eval() if I could, but we were specifically instructed to use it.

Because you need to call $this->f2(); instead of f2().
You also need to escape $ if you are using double quotes, because any $blah in double-quote strings are interpreted as variable references.
<?php
$code="class evalTest{
function f1(){
echo 'f1';
\$this->f2();
}
function f2(){
echo 'f2';
}
}
\$x=new evalTest();
\$x->f2();
\$x->f1();";
eval($code);
echo 'test';
Demo

use single quotes or protect \$, also you had error where you called f2(), use $this->f2
http://codepad.org/DkQ3PiTQ
$code='class evalTest{
function f1(){
echo "f1";
$this->f2();
}
function f2(){
echo "f2";
}
}
$x=new evalTest();
$x->f2();
$x->f1();;';
eval($code);
echo 'test';

Related

Passing a function by reference

Is it possible to pass a function by reference? So everytime the reference variable is called the function will be called aswell. Take a look at my code.
<?php
class Documents {
private static $docs = array(
'She went to the toilet and on her way back, opened the wrong door',
'She had found something that would mean she\'d never be poor again - but there was a catch',
'It was just for one night',
'He watched, helpless, as the door closed behind her'
);
public static function get() {
return self::$docs[array_rand(self::$docs)];
}
}
class Printer {
public static $content;
}
Printer::$content = &Documents::get();
echo Printer::$content;
echo "\n" . Printer::$content;
echo "\n" . Printer::$content;
Right now it'll print 3 similar lines but i would like it to call Documents::get() everytime Printer::$content is printed because Printer::$content = **&**Documents::get(); it is by reference.
No, you cannot have a variable which you treat as a variable which nonetheless runs code behind the scenes. If you write $foo, that's using the value of a variable. Only of you write $foo() are you explicitly executing a function.
Having said that, there are some situations in which object methods will be called implicitly. For instance, if $foo is an object and you use it in a string context:
echo $foo;
This will (try to) implicitly call $foo->__toString().
Please do not get the idea to somehow abuse this implied method call to do anything fancy. If you want to call functions, call functions. You can even return functions from other functions, so there's no lack of possibility to pass around functions. You will have to call them explicitly with () however.
There are variable functions:
php > function foo($bar) { echo $bar; }
php > $baz = 'foo';
php > $baz('qux');
qux
But you cannot have PHP automatically execute that "referenced" function when the variable is simply accessed, e.g:
php > $baz;
php >
As you can see, the foo function was not called, and no output was performed. Without the () to signify a function call, that variable is like any other - it's just a string whose contents happen to be the same as a particular functions. It's the () that makes the string "executable".
Note that variable functions, while useful in some limited circumstances, should be avoided as they can lead to spaghetti code and difficult-to-debug bugs.
You can use the magic method __get().
class Printer {
public function __get($name)
{
switch($name) {
case "content":
return Documents::get();
break;
default:
return $this->$name;
break;
}
}
}
But this cannot be done in static context. So you would have to have an instance of Printer. (Perhaps use a singleton?)

php concatenation operator use when operand is a function

<?php
function dosomething(){
echo "do\n";
}
$temp="test".dosomething();
echo $temp;
?>
expected result:testdo
but actual result is:
do
test%
I know how to change the code to get the expected result.
But what i doubt is why the code prints result like this.
Can someone explain it?Thanks!
dosomething is echoing to the screen. Since this runs first "do\n" is printed.
dosomething also doesn't return anything so the second echo is equivalent to echo "test";
In order to use the result of the call you should return it:
function dosomething(){
return "do\n";
}
Which will behave as you expect.
To clarify. In order to work out what $temp is the function must be run first which prints out "do\n" first.
Use return.
function dosomething(){
return "do\n"; }
Use a return statement instead of echo
function dosomething(){
return "do\n";
}
I'm not sure why people are getting down voted. Their answers are right.
http://codepad.org/nagGXY99
Try this:
Use return in the calling function. Doing that you will get the string where the function is being called. So function is being replaced by string and 2 strings will then con cat.
-
Thanks

Use contents of string variable to call function

I have the following piece of code
copy($source, $target);
I also use
move_uploaded_file($source, $target);
To prevent code reuse, I want to pass copy and move_uploaded_file in via a variable.
If my variable is $var = "copy";, simply putting $var($source, $target);, doesn't seem to work.
Are there any special characters that must surround $var?
Thanks.
The correct syntax is $var (variable functions), so your code should work.
But please don't do that, just write the code in a straightforward and readable manner. There are legitimate use cases for this technique, but this is not one of them.
You want to look at Variable Functions which goes on to explain how to do that.
function foo() {
echo "In foo()<br />\n";
}
$bar = 'foo';
$bar(); //this calls foo()
This can also be done on both object methods and static methods.
Object Methods
class Foo
{
function MyFunction()
{
//code here
}
}
$foo = new Foo();
$funcName = "MyFunction";
$foo->$funcName();
Static Methods
class Bar
{
static function MyStaticFunction()
{
//code here
}
}
$funcName = "MyStaticFunction";
Bar::$funcName();
While maybe not the case in your situation, when dealing with functions dynamically like this, it is important to check whether the function actually exists and/or is callable.
Alternatively to using Variable Functions, you can use call_user_func which will call the function based on the string name and with provided parameters.
You can use the PHP function call_user_func().
More info here.
You can use call_user_func to do this.
$result = call_user_func($functionToCall, $source, $target)
Documentation: PHP: call_user_func
as far as i know your code should work
here is the link for your refrence

PHP Basics: Can't deal with scope within classes

i got some trouble to understand scope in OOP. What i want is that $foo->test_item() prints "teststring"...Now it just fails with:
Warning: Missing argument 1 for testing::test_item()
Thanks a lot!
<?php
class testing {
public $vari = "teststring";
function test_item($vari){ //$this->vari doesn't work either
print $vari;
}
}
$foo = new testing();
$foo->test_item();
?>
test_item() should be:
function test_item() {
print $this->vari;
}
There is no need to pass $vari as a parameter.
Well, you've declared a method which expects an argument, which is missing. You should do:
$foo->test_item("Something");
As for the $this->, that goes inside of the class methods.
function test_item(){
print $this->vari;
}
function parameters can not be as "$this->var",
change your class like
class testing {
public $vari = "teststring";
function test_item(){ //$this->vari doesn't work either
print $this->vari;
}
}
$foo = new testing();
$foo->test_item();
And read this Object-Oriented PHP for Beginners
What's happening there is that $foo->test_item() is expecting something passed as an argument, so for example
$foo->test_item("Hello");
Would be correct in this case. This would print Hello
But, you may be wondering why it doesn't print teststring. This is because by calling
print $vari;
you are only printing the variable that has been passed to $foo->test_item()
However, if instead you do
function test_item(){ //notice I've removed the argument passed to test_item here...
print $this->vari;
}
You will instead be printing the value of the class property $vari. Use $this->... to call functions or variables within the scope of the class. If you try it without $this-> then PHP will look for that variable within the function's local scope

Tell How Function was called

I've looked at debug_backtrace but so far it doesn't do what I need it to do.
I need to know whether the function I'm calling was 'called' or 'echo-ed'. Like this:
function hello() {
//blah blah
}
echo hello(); //echo-ed
hello(); //'called'
But the function would do different things if it was 'called' over 'echo-ed'.
How would I do that?
I am pretty sure that this is impossible. The reason this cannot work is that "echo" or any other operator, function or variable assignment uses the return value of the function you've called. So if you've got the following:
echo function1();
What happens is that function1 gets executed, and the return value is passed to echo. Therefor, function1 cannot possibly know that its return value is going to be "echo-ed", because by the time that happens, function1() has already been called and finished executing.
There is no efficient way to deal it
Update:
There is no way to deal it :)
two examples to help you understand.
function hello(){
return "Hello!";
}
echo hello(); // prints Hello!
function hello(){
echo "Hello!";
}
hello(); // prints Hello!

Categories