提问人:Darryl Hein 提问时间:11/20/2008 最后编辑:Darryl Hein 更新时间:8/10/2017 访问量:7940
PHP中的变量变量类扩展--可能吗?
Variable variable class extensions in PHP--is it possible?
问:
在PHP中可以做到以下情况吗?
$blah = 'foo1';
class foo2 extends $blah {
//...
}
class foo1 {
//...
}
这给出了一个错误。
我想动态设置$blah以便我可以扩展我想要的任何类。
编辑:之所以想要这样做,是因为我想在相关类中使用另一个类中的函数。最后,它会是这样的:
Final extends foo1 extends foo2 extends foo3 extends foo4 extends parent { ... }
最后,我决定实例化该类中的另一个类并使用它。不是最好的选择,因为它们都是同一个班级的 2 个,但这不会经常使用,所以它现在可以工作。
答:
我看不出这有什么特别有用,但要回答你的问题......不。没有办法动态地做到这一点,因为在计算变量之前必须实例化生成的类(如果这有意义的话)。
简单地说:在代码可以正确执行之前,类必须存在。
你在这里假设 php 从上到下执行,但它并不完全像那样工作:
<?php
foo(); # works
function foo(){
print "bar";
}
<?php
foo(); #dies
if( $i == 1 )
{
function foo(){
print "bar";
}
}
<?php
$i = 1;
if( $i == 1 )
{
function foo(){
print "bar";
}
}
foo(); #works
现在,尽管您可以有条件地创建类:
<?php
class A { }
class B { }
if( false ){
class C extends B {
public static function bar(){
print "baz";
}
}
}
C::bar(); # dies
您不能在运行时从变量实例化一个:
<?php
class A { }
class B { }
$x = 'B';
if( false ){
class C extends $x {
public static function bar(){
print "baz";
}
}
}
C::bar();
---> Parse error: syntax error, unexpected T_VARIABLE, expecting T_STRING in /tmp/eg.php on line 7
有一种方法可以用 Eval 做到这一点,但你真的不想去那里:
<?php
class A { }
class B { }
$x = 'B';
if( true ){
$code =<<<EOF
class C extends $x {
public static function bar(){
print "baz";
}
}
EOF;
eval( $code );
}
C::bar();
$o = new C;
if ( $o instanceof $x )
{
print "WIN!\n";
}
--->barWIN!
但是,这里有一个更重要的问题:
为什么要在运行时扩展不同的类
任何使用你的代码的人都会想压制你并为此鞭打你。
(或者,如果你喜欢鞭打,那就做那个 eval 技巧)
评论
我认为这是为了便于维护,对吧?在运行时扩展一个类真的是相当疯狂的。
class SuperClassOne { /* code */ }
class SuperClassTwo { /* code */ }
class IntermediateClass extends SuperClassOne { /* empty! */ }
class DescendantClassFoo extends IntermediateClass{ }
class DescendantClassBar extends IntermediateClass{ }
class DescendantClassBaz extends IntermediateClass{ }
然后,当您想要更改所有类时,只需更改 IntermediateClass 扩展的内容:DescendantClass*
class IntermediateClass extends SuperClassTwo { }
评论
如果$blah没有太多值,则可以在不同的文件中扩展每个值require_once "classes/foo_$blah.php"
否则,你就会被解决方案困住......祝你好运... :)eval()
评论
你应该试过 $$
$blah = 'foo1';
class foo2 extends $$blah {
//...
}
class foo1 {
//...
}
我用定义和吠叫测试了一些东西:
<?php
define("INHERIT",A);
class A{
public function bark(){
return "I'm A";
}
}
class B{
public function bark(){
return "I'm B";
}
}
class C extends INHERIT{}
//main?
$dog = new C();
echo $dog->bark();
?>
输出为:
致命错误:找不到类“INHERIT” 在第 15 行的 D:\sites\inherit.php 中
因此,“变量类扩展可能吗?”的答案是:不。
评论
我知道这个问题很久以前就被问过了,但答案相对简单。
假设如果类 foo 存在,则要扩展类 foo,如果不存在,则要扩展类栏,则使用:
if(!class_exists('foo')) {
class foo extends bar {
function __construct() {
parent::__construct();
}
}
}
class myclass extends foo{
//YOUR CLASS HERE
}
评论
使用PHP重载可以在一定程度上实现这一点。
class variable_class {
public $orginalBaseClass;
public $orginalArgs;
public function __construct() {
// Get constructor parameters.
$this->orginalArgs = func_get_args();
// Get class name from args or 3rd party source.
$classname = 'stdClass';
// Pass along args to new class.
$this->orginalBaseClass = new $classname($this->orginalArgs);
}
public function __call($name, $arguments) {
// Pass all method calls to the orginalBaseClass.
return call_user_func_array(array($this->orginalBaseClass, $name), $arguments);
}
}
下一个:java 字符串到类
评论