Page 1 of 1

Passing off arguments

Posted: Wed Dec 27, 2006 6:34 pm
by aliasxneo
Hey all,

I'm not really sure if this is possible but I need a method for passing off arguments from one function to another. Basically what I have is a function that loads a class and returns a new instance of it. Well, some of the classes that get loaded need arguments in class initialization and therefor are failing because my function that returns the class doesn't give any parameters. So basically the function looks like this right now:

Code: Select all

function new_ob($object) // Required function //
    {
        if (empty($object))
        {
            throw new Exception("Cannot initiate empty object");
        }

        $path = $this->system->paths['modules'] . $this->name . "/objects/" . $object . ".object.php";
        $this->load($path);

        if (!class_exists($object))
        {
            throw new Exception("Cannot initiate non-existent object");
        }

        return new $object();
    }
And as you can see when I initiate the object I don't give any parameters. Well I have no idea how to get around this and the only thing I can think of is some kind of method of passing off arguments from one function to another. Basically pass off all the arguments (Except for $object) that get sent to the new_ob() function into the class initialization function. For example if I wanted to load a class and pass off "test" as the first argument I should be able to go:

Code: Select all

new_ob("object1", "test");
And have the "test" parameter passed as the first parameter for the class initialization. Is this possible with PHP? If not does anyone see any clear methods around this? Thanks.

Cheers,
- Josh

Posted: Wed Dec 27, 2006 7:02 pm
by timvw
the problem is that php does not support overloading...

here are a couple of approaches:
- require that all the objects have a constructor without arguments (and then use setters to inject the values).
- require that all the objects have a constructor that takes an array of values

Posted: Wed Dec 27, 2006 7:13 pm
by Begby
Are you trying to auto include files when you reference a class? If so use __autoload(). That will take care of your problem.

However, what you are looking for is doable using reflection. You first check if your class exists, create a new ReflectionObject, then using that object look at __construct() and see how many arguments it requires. Then you can create an instance of the object.

You can also just do a count of the number of parameters passed to new_obj() then use eval() to instantiate the object.

IMO though you are better explaining what it is you are trying to do, I assume that there is probably a better approach as what you are doing seems like it might be unneccessary.

Posted: Wed Dec 27, 2006 7:21 pm
by volka
If your php version is recent enough

Code: Select all

<?php
class Fac {
	function new_ob()
	{
		$args=func_get_args();
		if ( empty($args) ) {
			/*
			InvalidArgumentException is part of the SPL,
			see http://www.php.net/~helly/php/ext/spl/c ... ption.html
			*/
			throw new InvalidArgumentException('first parameter must be a classname');
		}
		$classname = array_shift($args);
		
		/*
		$path = $this->system->paths['modules'] . $this->name . "/objects/" . $classname . ".object.php";
		$this->load($path);
		*/
		$rc = new ReflectionClass($classname);
		/*
		newInstanceArgs was added in php 5.1.3
		*/
		return $rc->newInstanceArgs($args);
	}
}

class Foo {
	public function __construct() {
		echo "construction Foo\n";
	}
}

class Bar {
	public function __construct($a,$b,$c) {
		echo "construction Bar($a,$b,$c)\n";
	}
}

$f = new Fac;
$a = $f->new_ob('Foo');
$a = $f->new_ob('Bar', 'x', 'y', 'z');
$a = $f->new_ob('FooBar');
might do the trick.
You might also be interested in http://de2.php.net/manual/en/language.oop5.autoload.php

Posted: Wed Dec 27, 2006 7:38 pm
by aliasxneo
volka wrote:If your php version is recent enough

Code: Select all

<?php
class Fac {
	function new_ob()
	{
		$args=func_get_args();
		if ( empty($args) ) {
			/*
			InvalidArgumentException is part of the SPL,
			see http://www.php.net/~helly/php/ext/spl/c ... ption.html
			*/
			throw new InvalidArgumentException('first parameter must be a classname');
		}
		$classname = array_shift($args);
		
		/*
		$path = $this->system->paths['modules'] . $this->name . "/objects/" . $classname . ".object.php";
		$this->load($path);
		*/
		$rc = new ReflectionClass($classname);
		/*
		newInstanceArgs was added in php 5.1.3
		*/
		return $rc->newInstanceArgs($args);
	}
}

class Foo {
	public function __construct() {
		echo "construction Foo\n";
	}
}

class Bar {
	public function __construct($a,$b,$c) {
		echo "construction Bar($a,$b,$c)\n";
	}
}

$f = new Fac;
$a = $f->new_ob('Foo');
$a = $f->new_ob('Bar', 'x', 'y', 'z');
$a = $f->new_ob('FooBar');
might do the trick.
You might also be interested in http://de2.php.net/manual/en/language.oop5.autoload.php
Worked perfectly. Thanks for the help :)

Posted: Wed Dec 27, 2006 11:38 pm
by daedalus__
Read about this:

Service Locator