Page 3 of 3

Posted: Tue May 09, 2006 4:31 pm
by timvw
With runkit_method_add it becomes possible to add a 'custom' method to a class.. And you could update the properties in that custom method...

Here is an example where i add a constructor that accepts an associative array with property, value pairs.

Code: Select all

<?php
ini_set('error_reporting', E_ALL);
ini_set('display_errors', TRUE);

class Foo {
	public function getName() {
		return $this->name;
	}
}

runkit_method_add(
	'Foo', 
	'__construct', 
	'$args',
	'foreach($args as $key => $val) { $this->$key =$val; }'
);

$foo = new Foo(array('name' => 'john', 'age' => 26));
print $foo->getName();
?>

Posted: Tue May 09, 2006 4:48 pm
by nielsene
Now that's interesting ... Has there been any benchmarking on the efficiency of the runkit? As long as its "minimal" compared to a database connection/overhead this might work.

Hmm but the runkit appears to knock out the old constructor (which makes sense as PHP doesn't have real method overloading), so I'ld need to capture the old signature and body of the constructor and then restore it after the ORM creates the needed class. As its highly likely that after loading the object tree its likely that the application will need to instantiate "normal" instances of the class.

Posted: Tue May 09, 2006 4:58 pm
by timvw
You could first runkit_method_rename __construct to a tmpname...
Add your custom constructor and initialize the objects you need..
Finally runkit_method_rename tmpname to __construct

(Haven't had the time to checkout performance issues etc of the runkit...)

Posted: Tue May 09, 2006 4:59 pm
by nielsene
yeah that's exactly what I was just playing with...

Posted: Tue May 09, 2006 5:45 pm
by Christopher
The problem with runkit is it is not installed by default as I recall..

You might want to have runkit_method_rename __construct to something like __original_construct. Then add your own constructor and have the injected constructor call __original_construct().

Posted: Tue May 09, 2006 5:51 pm
by nielsene
Yeah, seeing how the body of the constructor is not always as simple as direct key/value assignments. A variety of minor processing is often done to convert inputs to canonical forms, etc.

renaming the old constructor and then using the call_user_func_array from within the dynamic generated constructor would work. While for my own use I'm willing to have the reliance on the runkit, if I decide to go that route,. I'd not be willing to make that a requirement should I try to bundle/release the ORM layer, though, so I think I'll have to stick with eval for now, as interesting/nice as the runkit approach is looking.

Posted: Tue May 09, 2006 8:36 pm
by alex.barylski
In which case use eval()

Whats so unsecure about the following code?

Code: Select all

class Contacts{
    function __construct($name, $title, $email)
    {
      $this->name = $name;
      $this->title = $title;
      $this->email = $email;
    }

    private $name;
    private $title;
    private $email;
  }

  $arg = array('"Alex"', '"Coordinator"', '"nuweb1@hotmail.com"');

  $cls = 'Contacts';
  eval('$obj = new '.$cls.'('.(implode(', ', $arg)).');');

  print_r( $obj );
You could call preg_match() on $cls and/or use some convention which only your ORM objects are likely to follow (prevent incorrect object instantiation) and follow the same process for $arg...

All in all relatively easy...fairly straight forward and does what you are asking...I think... :roll:

I'd go with eval() as it's your only option...or at least guaranteed to work on any version of PHP...

Or you can go with arrays as parameter lists and use the dreaded get_func_args() type functions and then inside the function call extract()?

Cheers :)

Posted: Tue May 09, 2006 8:50 pm
by alex.barylski
arborint wrote:From what I can tell, the reason that you still have to do stuff like this is because the PHP core group have what I would consider an old fashioned view of OO. And unfortunately, there are really no plans for much improvement in the PHP object model because of this attitude. There are a number of features that, though they would rarely be used by application programmers, would help library builders create really interesting stuff in PHP.
Just curious, but how do you mean old fashioned?

How is this issue solved in other languages?

Cheers :)