我正在寻找一个关于如何使用参数列表动态实例化类的解决方案。
例如:
class test {
public function __call($name, $args){
/* blah, blah class exists? require */
return new $name($args);
}
public function __toString(){
return (string) $this->extension(); // to enforce __toString of extension
}
}
class extension extends test {
public function __construct(classTypeHint $object, $required, $random = 25){
// This does not work, results in:
// "Argument 1 passed to extension::__construct must be an instance of classTypeHint, array given...
}
public function __toString(){
return var_export($this, true);
}
}
echo new test;
正如评论所述,这会导致错误,但我希望能够访问$object
为$args[0]
),$必需为($args[1]
)等。另外,强制执行“正确”的论点。
PHP的__autoload
功能有限。好吧,也许不是,但我还没有找到一种简单的方法来区分类自动加载。
借助此功能,我可以将__call()
,__get()
,__callStatic()
用于三种不同的自动加载。像:
__call()
在/includes/libraries
__get()
在/application/plugins
__callStatic()
在[{1}} 如果有更好的自动加载方式,请分享。但如果可能的话,我仍在寻找这样的解决方案。也许是/application/cats
班?
Reflection
但是这里很明显,它会在这里调用ReflectionClass-> __ toString()。另外,忽略返回的转储,它实际上并没有在这里使用newInstanceArgs()。
我对PHP 5.3之前的示例感兴趣。
答案 0 :(得分:4)
使用反射:
public function __call($name, $args)
{
return (new ReflectionClass($name))->newInstanceArgs($args);
}
它需要一个像call_user_func_array
编辑:一个有效的例子:http://codepad.org/ZZpBwRij
<?php
class MyClass
{
public function __construct($a, $b)
{
echo "__construct($a, $b) called";
}
}
function create($name, $args)
{
$class = new ReflectionClass($name);
return $class->newInstanceArgs($args);
}
var_dump(create('MyClass', array(1, 2)));
?>
Output:
__construct(1, 2) called
object(MyClass)#2 (0) {
}
答案 1 :(得分:1)
通过自动加载有更好的方法。
命名空间代码,即在相关目录中创建“Library”,“Plugin”和“Cats”命名空间。例如
// includes/libraries/Library/Foo.php
namespace Library;
class Foo {
// ...
}
// application/plugins/Plugin/Bar.php
namespace Plugin;
class Bar {
// ...
}
使用Symfony's universal class loader
之类的内容require_once 'path/to/Symfony/Component/ClassLoader/UniversalClassLoader.php';
$loader = new \Symfony\Component\ClassLoader\UniversalClassLoader;
$loader->registerNamespaces(array(
'Library' => 'path/to/includes/libraries',
'Plugin' => 'path/to/application/plugins'
));
$loader->register();
$foo = new \Library\Foo;
$bar = new \Plugin\Bar;
答案 2 :(得分:0)
所以,一个工作的例子,源于@ Dani的答案。
public function __call($name, $args){
$reflection = new ReflectionClass($name);
return $reflection->newInstanceArgs($args);
}
像魅力一样,除了,我还不知道表现。