魔术方法 __call() 参数为“真实”论点
我正在寻找有关如何使用参数列表动态实例化类的解决方案。
例如:
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
as ($args[0]
), $required as ($args[1]
) 等。另外,强制执行“正确”的参数。
我为什么要找这个?
PHP 的 __autoload
功能是有限的。好吧,也许不是,但我还没有找到区分类自动加载的简单方法。
借助此功能,我可以使用 __call()
、__get()
、__callStatic()
进行三种不同的自动加载。例如:
__call()
在/includes/libraries
中查找库__get()
查找插件 在/application/plugins
__callStatic()
中查找,嗯,cats 在/application/cats
中>
如果有更好的办法自动加载,请分享。但如果可能的话,我仍在寻找这样的解决方案。也许使用 Reflection
类?
ReflectionClass 的一些工作示例:
$instance = new ReflectionClass($name);
$instance->newInstanceArgs($arguments);
return $instance;
但这里很明显,它将在这里调用 ReflectionClass->__toString() 。另外,忽略返回的转储,它实际上没有使用 newInstanceArgs() 这里。
注意:
我对 PHP 5.3 之前的示例感兴趣。
I'm looking for a solution on how to use argument list for instantiating class' dynamically.
For example:
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;
As comment states, that results in error, but I'm looking to be able to access $object
as ($args[0]
), $required as ($args[1]
) etc. Plus, enforce "correct" arguments.
Why am I looking for this?
The __autoload
functionality of PHP is limited. Well, maybe it's not, but I have not found an easy way to differentiate class autoloads.
With this functionality, I can use __call()
, __get()
, __callStatic()
for three different autoloads. Like:
__call()
looks for libraries in/includes/libraries
__get()
looks for plugins in/application/plugins
__callStatic()
looks for, umm, cats in/application/cats
If there is a better way through autoloading, please share. But I'm still looking for such a solution, if it's possible. Maybe with Reflection
classes?
Somewhat working example with ReflectionClass:
$instance = new ReflectionClass($name);
$instance->newInstanceArgs($arguments);
return $instance;
But it's obvious here, that it will call ReflectionClass->__toString() here. Plus, overlooking the returned dump, it actually does not use the newInstanceArgs() here.
Notes:
I'm interested in example working prior to PHP 5.3.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用反射:
它需要一个数组,就像
call_user_func_array
编辑:一个工作示例:http://codepad. org/ZZpBwRij
Use reflection:
it takes an array just like
call_user_func_array
Edit: a working example: http://codepad.org/ZZpBwRij
有一个更好的方法通过自动加载。
为您的代码命名空间,即在相关目录中创建“Library”、“Plugin”和“Cats”命名空间。例如
使用类似 Symfony 的通用类加载器
There is a better way through autoloading.
Namespace your code, ie create "Library", "Plugin" and "Cats" namespaces in the relevant directories. For example
Use something like Symfony's universal class loader
所以,这是一个工作示例,源自@Dani 的答案。
工作起来就像一个魅力,除了,我还不知道性能。
So, a working example, derived from @Dani's answer.
Works like a charm, except, I have no idea about performance yet.