0

I have a class that executes eval statements within a (very large) loop. The eval statements are database stored code (mixed html & php) that needs to be processed. There is however is a serious performance issue because of this.

Instead of parsing the eval-statement every time in the loop, I would like to create a dynamic methods from the available eval-codes coming from the database within my class.

I thought of the following pseudocode so that the eval code is converted to a method:

class foo
{
    private $test=3;
    public function doloop()
    {   
        for($i=0;$i<5;$i++)
        {
            $string="echo 50 * \$this->test.'<br>';";
            $func="evalcode_001";
            if(!isset(${$func}))
            {
                ${$func}=create_function('',$string);
            }

            ${$func}();
        }
    }
}
$obj_foo = new foo();
$obj_foo->doloop();//must output '150<br>150<br>150<br> .....'

However when running it I get the error message "Using $this when not in object context in ...". So obviously I didn't really create methods within the class.

So my question is: How do I create a method for a class dynamically and assign code for the given method. Basically I want to be able to do:

$obj_foo->evalcode_001(); 

in the above example.

Help appreciated

PS I am using PHP5.4

4
  • 1
    FWIW: storing code in a database is a pretty darn bad idea to begin with. Apart from the problems you're obviously encountering with it, you're nailing your PHP code down and can hardly change it, because you have tons of database "data" which depends on some specifics in your code. Commented Jul 22, 2014 at 12:27
  • Hi; I agree, but it's where templating data is stored, for letters and CMS. Most if it is plain html, but over the years customizing has been done which included PHP code I'm afraid. Commented Jul 22, 2014 at 12:42
  • See here: stackoverflow.com/questions/12868066/… Specifically, they mention NOT using the create_function (which he goes on to say he doesn't think works with methods and classes). Commented Jul 22, 2014 at 12:44
  • 1
    See here: stackoverflow.com/questions/10985926/… Commented Jul 22, 2014 at 13:19

1 Answer 1

1

If you can change $this->test inside string (or write extra preg_match) you can use:

<?php

class foo
{
    public $test=3;

    public $functions = array();
    public function doloop()
    {   
        for($i=0;$i<5;$i++)
        {
            $string="echo 50 * \$this->test.'<br>';";
            $func="evalcode_001";
            if(!isset($this->functions[$func]))
            {
                $string = str_replace('$this','$object', $string );
                $this->functions[$func]= create_function('$object',$string);                
            }

            $this->functions[$func]($this);
        }
    }

    public function __call($name, $arguments) {
      if (isset($this->functions[$name])) {
          return $this->functions[$name]($this);          
      }
    }

    public function otherMethod() {
        echo "test";

    }     

}


$obj_foo = new foo();
$obj_foo->doloop();//must output '150<br>150<br>150<br> .....
$obj_foo->evalcode_001();
$obj_foo->otherMethod();

However as other said I wouldn't like to use anything like that in my real script

Sign up to request clarification or add additional context in comments.

4 Comments

Hi, thanks for the example code! However the eval codes need to be able to access various class properties/methods, so $this must be accessable. Is there perhaps a better way than using create_function?
@user2022678 I've edited code. You can now use $this
Great! seems to work now :-) ..small add-on question, is there also a way to access private properties, as now is only for public properties? Thanks again!
@user2022678 I don't really know but probably it's not possible

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.