2

私はいくつかの混乱を持っています!以下に示すような単純なクラスがあります

class MyClass {
    public $bar;
}

次に、インスタンスを作成しました

$cls = new MyClass;

$bar次に、クラスの外部からパブリック プロパティに値を割り当てました。

$cls->bar='Bar';

次に、新しいパブリック プロパティを追加$bazし、クラスの外部から値を割り当てました。

$cls->baz='Baz';

次に、新しいパブリック プロパティを追加し$showBar、クラスの外部から値を割り当てました。今回は、値は無名関数です。

$cls->showBar = function(){
    return $this->bar;
};

$cls次に、使用中のvar_dump($cls);インスタンスをダンプしました。出力は次のとおりです

object(MyClass)[10]
  public 'bar' => string 'Bar' (length=3)
  public 'baz' => string 'Baz' (length=3)
  public 'showBar' => 
    object(Closure)[11]

anonymous関数を含めて追加したすべてのパブリックプロパティが利用可能であるようです。

echo $cls->bar; // Bar
echo $cls->baz; // Baz
echo $cls->showBar(); // error

public プロパティshowbarはクラスで使用できます (var_dump に表示されます) が、関数を呼び出すと、次のように表示されます

致命的なエラー: 234 行目の D:\xampp\htdocs\phpTutorialInfo\bind\bindtoCls.php の未定義メソッド MyClass::showBar() の呼び出し

問題は次のとおりです。初期化後に新しいプロパティを追加することは可能です(スカラー値で正常に動作します)。また、利用可能なようにshowbar見えますが、なぜそれを認識できないPhpのでしょうか。値が匿名関数であるため、var_dump出力で利用できるのはなぜですか関数自体を含め、なぜ値を割り当てさせて(無名関数)、プロパティPhpの値を割り当てようとしたときにエラーがスローされたはずですか?showbarそれはまったく可能ですか?

4

3 に答える 3

4

この方法で関数を呼び出すことはできません。これは、PHP がクラス内で同じ名前の関数を変数に持つことを許可しているためです。関数演算子を使用すると、()PHP は関数のリストのみを調べ、クロージャーである変数は調べません。

PHP5.4 の時点で、ソリューションは次のようになります。

class MyClass {

    public function __call($fname, $args) {
        // bind the `this` scope to use
        $cl = $this->{$fname}->bindTo($this);
        // call the function and pass args to it
        return call_user_func_array($cl, $args);
    }

}

例:

$obj = new MyClass();
$obj->func = function() {
    echo 'We are in ' . get_class($this);
};

$obj->func(); // We are in MyClass

ここでこれをテストできます

于 2013-07-01T19:38:42.117 に答える
3

PHP でメソッドを動的に追加することはできません。あなたが行ったことは、関数であるカスタム プロパティを追加することです。しかし、これはメソッドにはなりません。違いを説明するために、同じ名前のプロパティとメソッドを持つクラスを作成できます。

class A {
    public $test = 42;
    public test() { return 43; }
}

$a = new A;
$a->test === 42;
$a->test() === 43;
于 2013-07-01T19:44:22.317 に答える
2

使用できますcall_user_func。例:

<?php
class MyClass {
    public $bar;
}
$cls = new MyClass;
$cls->bar='Bar';
$cls->baz='Baz';
$cls->showBar = function() use ($cls) {
    return $cls->bar;
};

echo call_user_func($cls->showBar); // Bar
?>

クロージャーを渡す代わりに__callマジックメソッドを定義したい場合があります。return $this->bar$cls

于 2013-07-01T19:41:49.630 に答える