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

Patrick
  • 383
  • 1
  • 2
  • 19
  • 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. – deceze Jul 22 '14 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. – Patrick Jul 22 '14 at 12:42
  • See here: http://stackoverflow.com/questions/12868066/dynamically-create-php-class-functions Specifically, they mention NOT using the create_function (which he goes on to say he doesn't think works with methods and classes). – Mark Jul 22 '14 at 12:44
  • 1
    See here: http://stackoverflow.com/questions/10985926/php-create-class-method-at-runtime – fluminis Jul 22 '14 at 13:19

1 Answers1

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

Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291
  • 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? – Patrick Jul 22 '14 at 13:07
  • @user2022678 I've edited code. You can now use `$this` – Marcin Nabiałek Jul 22 '14 at 13:13
  • 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! – Patrick Jul 22 '14 at 13:19
  • @user2022678 I don't really know but probably it's not possible – Marcin Nabiałek Jul 22 '14 at 13:22