What I'd like is for this class
class Car {
public function __construct(Engine $engine, Make $make, Model $model)
{
// stuff
}
}
Get an array that has the types needed to construct this car (Engine, Make, Model
) in the order they are needed for the constructor. I'm using this for a Dependency Injection-esque thing I'm making.
Update: I made these classes to accomplish the task but I feel like there is still a better way:
<?php
class Engine{}
class Make{}
class Model{}
class Car {
public function __construct(Engine $engine, Make $make, Model $model,
$foo,
$cats = 'dogs',
Engine $anotherEngine = NULL)
{
// stuff
}
}
class ServiceParameter extends ReflectionParameter
{
public $type = NULL;
public function __construct()
{
$args = func_get_args();
call_user_func_array(array('parent', '__construct'), $args);
$str = parent::__toString();
$str = explode(" ", $str);
$str = $str[4];
if(substr($str, 0, 1) != '$')
$this->type = $str;
}
}
class ServiceMethod extends ReflectionMethod
{
private $_parameter_cache = NULL;
private function _wrapParameter(&$item, $key)
{
$item = new ServiceParameter(array($item->getDeclaringClass()->name,
$item->getDeclaringFunction()->name),
$item->name);
}
public function getParameters()
{
if(is_array($this->_parameter_cache))
return $this->_parameter_cache;
else
{
$rms = parent::getParameters();
array_walk($rms, array($this, '_wrapParameter'));
$params = $rms;
$this->_parameter_cache = $params;
return $params;
}
}
}
$c = new ServiceMethod("Car", "__construct");
$args = $c->getParameters();
foreach($args as $arg)
{
echo "Parameter Name: {$arg->name}
";
echo "GetName: {$arg->getName()}
";
echo "Type: {$arg->type}
";
echo "
";
}
Which outputs:
Parameter Name: engine
GetName: engine
Type: Engine
Parameter Name: make
GetName: make
Type: Make
Parameter Name: model
GetName: model
Type: Model
Parameter Name: foo
GetName: foo
Type:
Parameter Name: cats
GetName: cats
Type:
Parameter Name: anotherEngine
GetName: anotherEngine
Type: Engine
I know there's some redundant stuff ($params = $rms
) but that's a result of rushing and changing the code around a lot to get it to work. I feel like constructing a whole new ServiceParameter
when we already have the ReflectionParameter
instance is a waste. Is there anyway around this ($item = (ServiceParameter)$item
didn't work)
class Engine { }
class Make { }
class Model { }
class Car {
public function __construct(array $a, $b, Engine $engine, Make $make, Model $model)
{
// stuff
}
}
$rc = new ReflectionClass('Car');
$ctor = $rc->getConstructor();
foreach( $ctor->getParameters() as $rp ) {
$cn = $rp->getClass();
if ( $cn instanceof ReflectionClass ) {
$cn = $cn->getName();
}
echo $cn, ' ', $rp->getName(), "
";
}
prints
a
b
Engine engine
Make make
Model model
How about the method ReflectionMethod::getPrototype? If it is not good enough, you might use ZF : http://docs.gnulife.cn/ZF/ZendFramework-1.0.4/documentation/api/core/Zend_Server/Reflection/Zend_Server_Reflection_Parameter.html (there is a "type" field in this class)