5

PHPで次のようなことは可能ですか?

$blah = 'foo1';

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

class foo1 {
    //...
}

これによりエラーが発生します。

$blah を動的に設定して、必要なクラスを拡張できるようにします。

編集:関連するクラスの別のクラスの関数を使用したかったため、これを実行したい理由。最終的には次のようになります。

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

結局、クラス内で他のクラスをインスタンス化して使用することにしました。どちらも同じクラスの 2 人であるため、最適なオプションではありませんが、これはそれほど頻繁には使用されないため、今のところ機能します。

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!

ただし、ここでさらに重要な問題があります。

なぜ実行時に別のクラスを拡張したいのですか

あなたのコードを使用している人は誰でも、あなたを押さえつけたいと思うでしょう。

(または、鞭打ちに興味がある場合は、その eval トリックを実行してください)

于 2008-11-20T07:55:57.567 に答える
2

これが特に役立つかどうかはわかりませんが、あなたの質問に答えるために...いいえ。変数が評価される前に生成されたクラスをインスタンス化する必要があるため、これを動的に行う方法はありません(それが理にかなっている場合)。

簡単に言うと、コードを適切に実行するには、クラスが存在している必要があります。

于 2008-11-20T07:20:09.057 に答える
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);
    }
}

Drupal モジュール内でこのパターンを使用して、キャッシュからデータをプリフェッチしています。

于 2015-01-27T22:38:45.637 に答える
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 に答える
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 に答える