Question

Est-ce que quelque chose comme ce qui suit est possible en PHP?

$blah = 'foo1';

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

class foo1 {
    //...
}

Cela donne une erreur.

Je souhaite définir dynamiquement $ bla pour pouvoir étendre la classe de mon choix.

Modifier: raison de vouloir le faire parce que je souhaitais utiliser une fonction d'une autre classe dans une classe liée. En fin de compte, cela aurait été quelque chose comme:

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

Finalement, j'ai décidé d'instancier l'autre classe dans la classe et de l'utiliser. Ce ne sont pas les meilleures options parce que vous avez deux des mêmes classes, mais cela ne sera pas utilisé aussi souvent, donc cela fonctionnera pour le moment.

Était-ce utile?

La solution

Vous supposez ici que php s'exécute de haut en bas, mais cela ne fonctionne pas vraiment comme ça:

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

Maintenant, vous pouvez créer conditionnellement des classes:

<?php

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

Vous ne pouvez pas en instancier un à l'exécution à partir d'une variable:

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

Il existe un moyen de le faire avec Eval, mais vous ne voulez vraiment pas y aller:

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

Cependant, il y a une question plus importante ici:

Pourquoi voudriez-vous étendre une classe différente au moment de l'exécution

Toute personne utilisant votre code voudra vous maintenir et vous fouetter pour cela.

(Sinon, si vous aimez fouetter, faites cette astuce d'évaluation)

Autres conseils

Je ne vois pas en quoi cela serait particulièrement utile, mais pour répondre à votre question ... non. Il n’ya aucun moyen de le faire de manière dynamique car la classe générée doit être instanciée avant que la variable ne soit évaluée (si cela a du sens).

Pour le dire simplement: la classe doit exister avant que le code puisse être exécuté correctement.

Si vous n'avez pas trop de valeurs pour $ blah, vous pouvez les étendre dans un fichier différent, puis require_once "quot / foo_ $ blah.php"

Sinon, vous êtes coincé avec la solution eval () ... bonne chance avec ça ...:)

Je sais que cette question a été posée il y a longtemps, mais la réponse est relativement simple.

En supposant que vous souhaitiez étendre la classe foo si la classe foo existe, ou la barre de classe si ce n'est pas le cas, vous utiliseriez:

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

class myclass extends foo{
    //YOUR CLASS HERE
}

Je suppose que c'est pour la facilité de maintenance, non? L'extension d'une classe au moment de l'exécution est vraiment assez folle.

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

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

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

Ensuite, lorsque vous souhaitez modifier toutes vos classes DescendantClass * , il vous suffit de modifier la portée de la classe IntermediateClass:

class IntermediateClass extends SuperClassTwo { }

J'ai testé quelque chose avec les définitions et les aboiements:

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

la sortie est:

  

Erreur fatale: la classe 'INHERIT' est introuvable.   dans D: \ sites \ inherit.php à la ligne 15

donc, la réponse à "Des extensions de classe variables sont-elles possibles?" est: non.

En utilisant la surcharge de PHP , vous pouvez accomplir cela dans une certaine mesure.

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

J'utilise ce modèle dans un module Drupal pour pré-extraire des données du cache .

vous devriez avoir essayé $$

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

class foo1 {
    //...
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top