2008-11-20 69 views
4

在PHP中可能類似以下內容嗎?PHP中的變量類擴展 - 有可能嗎?

$blah = 'foo1'; 

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

class foo1 { 
    //... 
} 

這給出了一個錯誤。

我想動態設置$等,所以我可以擴展任何我想要的類。

編輯:想要這樣做的原因是因爲我想在相關類中使用另一個類中的函數。最後它會是這樣的:

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

最後我決定實例化類中的其他類並使用它。不是最好的選擇,因爲他們都是同一類的兩個,但這不會經常使用,所以它現在可以工作。

回答

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 

有一種方法與評估和演示做到這一點,但你真的不想去那裏:

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

但是,這裏還有一個更重要的問題:

爲什麼地獄會y歐在運行時擴展不同的類使用你的代碼將要抱你下來

任何人,你這一點。

(或者,如果你到鞭打,這樣做的eval伎倆)

+2

在理想的世界裏,人們不會想要這樣做。但這不是一個理想的世界。我看了這個,因爲我堅持Joomla更改父類,以定義在1.5.x版和更高版本之間的新「元素」。我的子類不需要有所不同,我不需要不同的代碼庫,所以我希望能夠根據Joomla的版本繼承不同的類。這就是爲什麼。 – user185631 2012-07-26 16:35:21

+0

這似乎泛型不可能與PHP,令人失望,我想這樣黑客攻擊! – 2013-05-05 02:10:45

+0

@ user185631出於完全相同的原因來到這裏。 – mavrosxristoforos 2013-10-15 17:32:44

3

我不明白這將如何特別有用,但回答你的問題......不。沒有辦法動態地做到這一點,因爲生成的類必須在變量被評估之前實例化(如果有意義的話)。

簡單來說:該類必須存在才能正確執行代碼。

+0

我的感覺是一樣的。但用PHP,你永遠不會知道...... ;-) – Tomalak 2008-11-20 07:36:32

+0

正如Kent Fredric所說,這是可能的。不漂亮,但可能。 – 2008-11-20 16:49:03

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 { } 
+1

單行註釋使用不當。右括號}被評論! – luiscubal 2009-12-03 22:38:11

2

如果您沒有爲$布拉赫太多值,則可以延長每一個不同的文件,然後require_once "classes/foo_$blah.php"

否則,你堅持的eval()解決方案...祝你好運... :)

-1

你應該嘗試$$

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

class foo1 { 
    //... 
} 
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(); 
?> 

輸出爲:

Fatal error: Class 'INHERIT' not found in D:\sites\inherit.php on line 15

所以「答案是可變類擴展可能?」是:No.

1

我知道這個問題很久以前就問過了,但答案相對簡單。

假設你想,如果類foo是否存在,或者類酒吧,如果不是這樣,你會使用擴展類Foo:

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

class myclass extends foo{ 
    //YOUR CLASS HERE 
} 
0
<?php 
class AAA 
{ 
    function go() 
    { 
     echo 'WORKS!'; 
    } 
} 
$a = 'AAA'; 

use AAA as Eclass; 

class BBB extends EClass 
{ 
} 

BBB::go(); 
?> 
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