3

わかりました、私は以下のコードを持っています

<?php
    class foo{
       public $bar = NULL;

       public function boo(){
          $this->bar();
       }
    }

    $mee = new foo();

    //save a closure function on the property
    $mee->bar = function(){
        echo 'hahaha';
    };

    //invoke the closure function by using a class method
    $mee->boo();
?>

ここで実行されていることがわかりますhttp://codepad.org/s1jhi7cv

ここで必要なのは、クロージャ関数をクラス メソッドに格納することです。

ここでそれに関するドキュメントを読んでいるので、クロージャは可能ですhttp://php.net/manual/en/functions.anonymous.php

これは可能ですか?私は何か間違ったことをしましたか?私を訂正してください

4

6 に答える 6

12

codepad.org は PHP 5.2.5 を使用しており、クロージャのサポートは 5.3 でのみ追加されたため、codepad.org のサンプル コードは機能しません。

ただし、クロージャーをサポートする PHP バージョンでもコードは機能しませんが、別のエラーが発生します: http://codepad.viper-7.com/Ob0bH5

これは現時点での PHP の制限です。$obj->member()という名前のメソッドmemberを検索し、プロパティを調べて呼び出し可能かどうかを確認しません。率直に言って、迷惑です。

call_user_func()/なしでこれを機能させるために私が知っている唯一の方法call_user_func_array()は次のとおりです。

public function boo() {
   $func = $this->bar;
   $func();
}
于 2012-08-30T12:10:15.900 に答える
4

それを利用するには、PHP ( ) のいくつかの魔法の機能を活用する必要があります__callExtendableたとえば、次のように拡張します。

class Extendable {
    static function import($context) {
        $self = new static();
        while (is_callable($context)) $context = $context($self);
        if (is_array($context) || is_object($context) || is_a($context, 'Traversable')) {
            foreach($context as $key => $value)
                $self->$key = &$value; # preserve keys if
        }
        return $self;
    }
    public function __call($name, $args) {
        if (isset($this->$name) && is_callable($this->$name)) {
            return call_user_func_array($this->$name, $args);
        }
        throw new BadFunctionCallException(sprintf('Undefined function %s.', $name));
    }
}

そして、あなたは仕事をすることができます。それはそれほどいいことではありません。背景と例は、私のブログ投稿の 1 つにあります。

もちろん、その魔法の機能を独自に実装することもできます。

于 2012-08-30T12:14:47.690 に答える
2

あなたはそれをすることができません。

たとえば、次のコードを見てください。

class T {
  function foo() {
    echo 'T::foo';
  }
}

$t = new T;
$t->foo = function() {
  echo 'Closure::foo';
};
$t->foo();

PHP 5.4.6 および/または PHP 5.3.16 では問題なく動作しますが、T::foo印刷されてしまいます。

これは、PHP のメソッドが、たとえば JavaScript のように変更可能なクラス プロパティではないために発生します。

でも、

$foo = $t->foo;
$foo();

期待どおりに印刷Closure::fooされます。

于 2012-08-30T12:11:34.870 に答える
2

使用call_user_func()機能:

<?php
    class foo{
       public $bar = NULL;

       public function boo(){
          call_user_func($this->bar);
       }
    }

    $mee = new foo();

    //save a closure function on the property
    $mee->bar = function(){
        echo 'hahaha';
    };

    //invoke the closure function by using a class method
    $mee->boo();

これにより、「ahahah」が表示されます

それが役に立てば幸い。

于 2012-08-30T12:15:04.593 に答える
1

PHP はプロトタイプベースの言語ではないため、関数を再定義することはできません

于 2012-08-30T12:10:37.460 に答える
0

__call定義されていないすべてのメソッドをキャッチし、クロージャーを検索して呼び出すために使用します。このSitePoint スレッドの私の投稿を見てください。

于 2012-08-30T12:13:01.310 に答える