PHP中的变量类扩展 - 是否可能?

时间:2008-11-20 06:44:55

标签: php class object variable-variables

在PHP中是否可以使用以下内容?

$blah = 'foo1';

class foo2 extends $blah {
    //...
}

class foo1 {
    //...
}

这会出错。

我想动态设置$ blah所以我可以扩展我想要的任何类。

编辑:想要这样做的原因是因为我想在相关类中使用另一个类的函数。最后它会是这样的:

Final extends foo1 extends foo2 extends foo3 extends foo4 extends parent { ... }

最后我决定在类中实例化另一个类并使用它。不是最好的选择,因为它们都是你们2个相同的类,但是这种情况不会经常使用,因此它现在可以使用。

8 个答案:

答案 0 :(得分:15)

你在这里假设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技巧)

答案 1 :(得分:2)

我不知道这会特别有用,但是要回答你的问题......不。没有办法动态地执行此操作,因为生成的类必须在计算变量之前进行实例化(如果这是有意义的)。

简单地说:在正确执行代码之前,类必须存在。

答案 2 :(得分:2)

我认为这是为了便于维护,对吧?在运行时扩展一个类真的很疯狂。

class SuperClassOne { /* code */ }
class SuperClassTwo { /* code */ }

class IntermediateClass extends SuperClassOne { /* empty! */ }

class DescendantClassFoo extends IntermediateClass{ }
class DescendantClassBar extends IntermediateClass{ }
class DescendantClassBaz extends IntermediateClass{ }

然后,当您想要更改所有DescendantClass*类时,您只需要更改IntermediateClass所扩展的内容:

class IntermediateClass extends SuperClassTwo { }

答案 3 :(得分:2)

如果你没有太多的$ blah值,你可以将每个值扩展到另一个文件,然后require_once "classes/foo_$blah.php"

否则,你会遇到eval()解决方案......祝你好运......:)

答案 4 :(得分:2)

我知道很久以前就问了这个问题,但答案相对简单。

假设你想要在类foo存在时扩展类foo,或者如果不存在则扩展类bar,你可以使用:

if(!class_exists('foo')) {
    class foo extends bar {
        function __construct() {
            parent::__construct();
        }
    }
}

class myclass extends foo{
    //YOUR CLASS HERE
}

答案 5 :(得分:1)

我测试了定义和吠叫的东西:

<?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

所以答案“可变类扩展可能吗?”是:否。

答案 6 :(得分:1)

使用PHP overloading,您可以在一定程度上完成此任务。

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);
    }
}

我在Drupal module prefetching data from the cache内使用此模式。

答案 7 :(得分:-2)

你应该尝试过$$

$blah = 'foo1';
class foo2 extends $$blah {
    //...
}

class foo1 {
    //...
}