PHP Değişken değişken sınıf uzantıları - mümkün mü?

7 Cevap php

PHP aşağıdaki olası gibi bir şey mi?

$blah = 'foo1';

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

class foo1 {
    //...
}

Bu bir hata verir.

Ben dinamik $ filan ayarlamak istediğiniz kadar ben istersem sınıf uzatabilirsiniz.

Ben bir ilgili sınıftan başka bir sınıfın dışında bir işlevi kullanmak istedim çünkü bunu yapmak isteyen için Edit: sebebi. Sonunda o gibi bir şey olurdu:

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

Sonunda ben sınıf içindeki diğer sınıf örneğini ve onu kullanmaya karar verdi. Değil iyi seçenek, çünkü her ikisi de aynı sınıfları 2, ama bunun sık kullanılan olmayacak, bu yüzden şimdi için çalışacak.

7 Cevap

Sen php alt üst yürütür, ama oldukça böyle çalışmıyor burada varsayıyoruz:

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


Şimdi, koşullu sınıfları oluşturmak rağmen:

<?php

class A { }
class B { }
if( false ){ 
  class C extends B { 
    public static function bar(){
      print "baz"; 
    }
  }
}
C::bar(); # dies

Sen bir değişken zamanında bir örneğini olamaz:

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

Orada Eval ile bunu yapmak için bir yoldur, ancak really oraya gitmek istemiyorum:

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

Ancak, burada daha önemli bir soru var:

Why the hell would you want zamanı farklı bir sınıfını genişletmek için

Kodunuzu kullanan biri aşağı tutmak istiyorum ve whip Bunun için olacaktır.

(Alternatif olarak, kamçılama içine iseniz, o eval hile yapmak)

Ben hayır ... Bu özellikle yararlı olacağını nasıl görmüyorum, ama soruyu cevaplamak için. Oluşturulan sınıf (mantıklı eğer) değişken değerlendirilmeden önce örneklenmiş olmak zorunda, çünkü dinamik bunu yapmak için hiçbir yolu yoktur.

Basitçe söylemek gerekirse: kodu düzgün idam edilmeden önce sınıfı bulunmalıdır.

Eğer $ vesaire için çok değerler yoksa, o zaman require_once "classes/foo_$blah.php" farklı bir dosyaya her biri genişletmek olabilir

Aksi takdirde, bu ile eval() çözüm ... iyi şans ile sıkışmış konum ... :)

Ben bu kolaylığı-of-bakım için olduğunu varsayalım, değil mi? Zamanında bir sınıf genişletme gerçekten oldukça çılgın.

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

class IntermediateClass extends SuperClassOne { // empty! }

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

Tüm DescendantClass* sınıfları değiştirmek istediğinizde, sonra, sadece IntermediateClass uzanır ne değiştirmek zorunda:

class IntermediateClass extends SuperClassTwo { }

Ben define ve havlaması ile bir şey test:

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

çıktı:

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

öylesine için cevap "olası değişken sınıf uzantıları nelerdir?" olduğunu: Hayır

Bu soru uzun zaman önce soruldu biliyorum, ama cevabı oldukça basit.

Eğer class foo var, ya da eğer bu olmuyorsa sınıf bar, kullanmak istiyorum eğer sınıf foo uzatmak istiyorum varsayarak:

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

class myclass extends foo{
    //YOUR CLASS HERE
}

Eğer $ $ denedim

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

class foo1 {
    //...
}