5

在 PHP 中是否可能出现以下情况?

$blah = 'foo1';

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

class foo1 {
    //...
}

这给出了一个错误。

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

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

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

最后我决定在类中实例化另一个类并使用它。不是最好的选择,因为他们都是同一类的两个,但这不会经常使用,所以它现在可以工作。

4

8 回答 8

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!

然而,这里还有一个更重要的问题:

为什么你在运行时扩展一个不同的类

任何使用您的代码的人都会想要压制您并为此鞭打您。

(或者,如果你喜欢鞭打,做那个评估技巧)

于 2008-11-20T07:55:57.567 回答
2

我看不出这会特别有用,但是要回答您的问题……不。没有办法动态地做到这一点,因为必须在评估变量之前实例化生成的类(如果这有意义的话)。

简单来说:类必须存在,代码才能正确执行。

于 2008-11-20T07:20:09.057 回答
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 { }
于 2008-11-20T08:04:04.850 回答
2

如果你没有太多的 $blah 值,你可以在不同的文件中扩展每个值require_once "classes/foo_$blah.php"

否则,您将无法解决eval()问题...祝您好运... :)

于 2008-11-20T08:56:46.790 回答
2

我知道这个问题很久以前就被问过了,但答案比较简单。

假设你想扩展类 foo 如果类 foo 存在,或者类 bar 如果它不存在,你会使用:

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

class myclass extends foo{
    //YOUR CLASS HERE
}
于 2012-10-01T14:29:08.160 回答
2

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

I'm using this pattern inside a Drupal module for prefetching data from the cache.

于 2015-01-27T22:38:45.637 回答
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();
?>

输出是:

致命错误:在第 15 行的 D:\sites\inherit.php 中找不到类 'INHERIT'

那么“变量类扩展是否可能?”的答案是什么?没有。

于 2011-05-27T15:04:10.537 回答
-2

你应该尝试过 $$

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

class foo1 {
    //...
}
于 2009-11-02T14:33:51.010 回答