7

PHP を使い始めたばかりで、匿名関数をクラス インスタンスに追加する方法があるかどうか疑問に思っています。

たとえば、言ってみましょう...

class A{
    public B;
}

$c = new A();

//This is where I am getting a little confused...
//The following wont work

$c->B = function(){echo('HelloWorld');};
$c->B();

私が望んでいるのは、同じコードの一部を多数の異なるアプリケーションで再利用し、特定のインスタンスで関数を「スワップアウト」して置き換えることができるようにすることです。

私はphp5.3を使用しています(匿名関数は機能するはずですが、私が使用している方法ではありません)。

お時間をいただき、誠にありがとうございました!!

-GK

4

7 に答える 7

10

このジョブには__callマジック関数を使用できます。美しさではありませんが、機能します..

このような:

class A {
    public $B;

    public function __call($closure, $args)
    {
        call_user_func_array($this->$closure, $args);
    }
}

$c = new A();

$c->B = function () { echo('HelloWorld'); };
$c->B();
于 2010-06-13T22:17:08.743 に答える
5

FWIW:

PHP 5.3 の無名関数の扱いは面白いものです。これはうまくいきません:

$c->B = function() { echo func_get_arg(0); };
$c->B("This fails :(");

これはうまくいきます:

$c->B = function() { echo func_get_arg(0); };
$hilarious = $c->B;
$hilarious("This works!");

これを回避するには、 Oden が提供する__callようなハックを使用する必要があります。

この動作将来変更される可能性があります。RFC を逆参照する配列は最近PHP のトランクにコミットされ、パッチは関数呼び出しの連鎖に関する議論を開始しました。その構文により、__call ハックなしで実行しようとしていることが可能になる可能性があります。残念ながら、関数呼び出しチェーンを機能させることは過去に困難であることが証明されています。

于 2010-06-14T00:24:12.947 に答える
4
# real ugly, but PoC...

class a {
  function __call($f, $x) {
    call_user_func_array($this->$f, $x);
  }
}

$a = new a;
$a->b = function() { echo "Hello world"; };
$a->b();
于 2010-06-13T22:16:32.430 に答える
2

ストラテジー パターンまたはデコレータ パターンについて説明しているように聞こえます。コードを読む他の開発者とより簡単にやり取りできる方法でこれを達成する方法他にもあります。

于 2010-06-13T22:11:15.990 に答える
1

これは、PHP 7 ではもはや問題ではありません。

// no error
$result = ($this->anonFunc)();
$result = ($this->anonFunc)($arg1, $arg2, ...);

ASTの詳細を参照してください。

于 2016-03-09T00:22:53.873 に答える
1

これらの行に沿って何かを行うことができます (クロージャーではないコールバックでも機能します)。

<?php
class A {
    private $fun;
    function setFun($fun) {
        if (!is_callable($fun))
            throw new InvalidArgumentException();
         $this->fun = $fun;
    }
    public function fun() {
        call_user_func_array($this->fun, func_get_args());
    }
}

$c = new A();

$c->setFun(function($a) { echo('HelloWorld ' . $a);});
$c->fun("here");

を与えHelloWorld hereます。

とはいえ、継承またはデコレータ パターンも考慮する必要があります。

于 2010-06-13T22:10:02.883 に答える