Jump to content

Instantiating class from a string


sennetta

Recommended Posts

This might not be strictly OOP related, but I wasn't sure and I didn't want to clutter the main board with something that might be inappropriate.

 

I would like to create a function which takes a carefully formatted string as a parameter and creates an instance of an object with arguments taken from the string.  The protocol is as follows:

 

"ClassName_arg1_arg2"

 

On being called the function splits the string (using http://uk3.php.net/split ?) and attempts to create an instance of the class ClassName with arguments Arg1 and Arg2, so, upon receiving such a string, the function essentially needs to carry out the following:

 

<?php
$obj = new ClassName("arg1","arg2");
?>

 

Note that more parameters may be added to the initial string, so it may be

 

"ClassName_arg1_arg2_arg3_arg4_arg5"
resulting in
<?php
$obj = new ClassName("arg1","arg2","arg3","arg4","arg5");
?>

 

or even simply

 

"ClassName"
resulting in
<?php
$obj = new ClassName();
?>

.

 

I've had a think and a way I have come up with is getting the function to build the string

 

"$obj = new ClassName(\"arg1\",\"arg2\");"

 

and then get PHP to parse it, and essentially run the code it has just built.

 

Is this even possible in PHP, and if so am I on the right track?

 

Many thanks,

 

Anthony

Link to comment
Share on other sites

well if you have the strng "ClassName_arg_arg2" and your run it through split or explode, you know that the zero index is the class name and the rest are the arguments. So your code should could build variable variables and pass them to the constructor of that zero index. Does that make sense?

Link to comment
Share on other sites

I've had a think and a way I have come up with is getting the function to build the string

 

"$obj = new ClassName(\"arg1\",\"arg2\");"

 

and then get PHP to parse it, and essentially run the code it has just built.

 

Is this even possible in PHP, and if so am I on the right track?

It is possible to get PHP to parse your string using eval(), but emehrkay's solution is much cleaner, faster, more secure, etc, meaning there's no reason to use this in this circumstance.

Link to comment
Share on other sites

You can also use func_get_args(); and just pass whatever to the constructor

 

class test{
    public function __construct(){
        echo func_num_args();
    }
}

$class = 'test';
$vars = 'argument';

$instance = new $class($vars);

 

Ok so I have the class name stored as a string, and the arguments stored in a separate array, and I have successfully created an instance of the class like so:

private function createClass(){
require_once($this->className.".php");
$this->classInst = new $this->className;
}

How can I pass a varying number of arguments to the constructor of that class?  I think I can do it by creating a method in the class to pass arguments, and then call a "begin" method which will set the class doing its stuff:

 

private function createClass(){
require_once($this->className.".php");
$this->classInst = new $this->className;

foreach ($this->args as $arg){
	$this->classInst->addArg($arg);
}
$this->classInst->begin();
}

but I'd rather not do that: passing them to the constructor would be a lot neater, and means I wouldn't have to subclass anything - I could just use an interface.  What would you do?

 

Many thanks once again.

Link to comment
Share on other sites

 

... but I'd rather not do that: passing them to the constructor would be a lot neater, and means I wouldn't have to subclass anything later on - I could just use an interface.  What would you do?

 

Many thanks once again.

 

Sorry wouldn't let me edit it.

Link to comment
Share on other sites

Blimey they don't like edits here do they!

 

 

... but I'd rather not do that: passing them to the constructor would be a lot neater, and means I wouldn't have to subclass anything later on - I could just use an interface.  What would you do?

 

Many thanks once again.

 

Sorry wouldn't let me edit it.  I meant:

 

 

... but I'd rather not do that: passing them to the constructor would be a lot neater, and means I wouldn't have to subclass anything later on - I could just use an interface and avoid calling parent constructors and having "criteria" (urgh) for writing a new module.  What would you do?

 

Many thanks once again.

Link to comment
Share on other sites

<?php
class Foo {

private $bar;
private $meh;

public static function factory($bar, $meh){
	return new self($bar, $meh);
}
public function __construct($bar, $meh){
	$this->bar = $bar;
	$this->meh = $meh;
}
}
$arr = explode('_', 'Foo_bar_meh');
$foo = call_user_func_array(array($arr[0], 'factory'), array($arr[1], $arr[2]));
var_dump($foo);
?>

Link to comment
Share on other sites

<?php
class Foo {

private $bar;
private $meh;

public static function factory($bar, $meh){
	return new self($bar, $meh);
}
public function __construct($bar, $meh){
	$this->bar = $bar;
	$this->meh = $meh;
}
}
$arr = explode('_', 'Foo_bar_meh');
$foo = call_user_func_array(array($arr[0], 'factory'), array($arr[1], $arr[2]));
var_dump($foo);
?>

Thanks very much.  That was exactly what I needed.  Here is the code I wrote.

<?php
private function createClass(){
require_once($this->className.".php");
// create class instance using factory method in class
$this->classInst = call_user_func_array(
		array(
			$this->className,
			'factory'),
		$this->argsArr); // $argsArr is array of arguments created 
				      // when the input string is exploded

}

?>

and it works, by crikey.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.