0

重複の可能性:
PHP関数の無制限の引数?
未定義の数の引数を別の関数に転送します

たとえば、次のように、オブジェクトに対するメソッドの実行を「委任」するために、Gearmanサーバーをセットアップしています。

$user->synchronize();

また

$event->publish('english', array('remote1','remote2') );

(remote1とremote2はリモートソーシャルネットワークです)

私のアイデアは、オブジェクト、メソッド名、および引数(言語などの他のパラメーターも含む)を、シリアル化してギアマンワーカーに送信できるオブジェクトにラップすることです。

 class bzkGearmanWrapper {
        public $object;
        public $method;
        public $args; 
        /*
        * @param  $object (object) any object
        * @param  $method (string) the name of the method to execute
        * @param  $args    an argument or an array containing the arguments to pass to the method
        */

    private function __construct($object, $method, $args )  { 
        $this->object = $object;
        $this->method = $method;
        $this->args = $args;
    }

    private function execute() {
        $object = $this->object;
        $method = $this->method;
        $args   = $this->args;
        return $object->{$method}($args);

    }
}

その後、メインスクリプトで実行できるようになります

$client =new GearmanClient();

// instead of :  $user->synchronize();
$params = new bzkGearmanWrapper($user, 'synchronize');
$client->do('execute', $params);

// instead of : $event->publish('english', array('remote1','remote2') );
$targets = array('remote1', 'remote2');
$params = new bzkGearmanWrapper($event, 'publish', array('english', $targets); 
$client->do('execute', $params);

そして私のギアマンワーカーでは、私は単に「実行」タスクを次のように呼び出すことができます

function execute($job) {
    $wrapper = unserialize( $job->workload() ); 
    return $wrapper->execute(); 
}

上記のexecuteメソッドは、引数を1つだけ指定すると機能しますが、引数の数を特定できない場合はどうすればよいですか。最大2つの引数を使用する私のメソッドのほとんどは、次のように書くことができます

return $object->{$method}($arg1, $arg2);

1つの解決策はeval()を使用することですが、私はそれを避けたいと思います。

関数に引数を渡す方法を知っていますか?

編集

このトピックは、2つの古いトピックの複製としてクローズされました。1つ目は、オブジェクトに対してではなく、ユーザー関数に対してジョブを実行するcall_user_func_array()関数に関するものでした。2番目のトピック「未定義の数の引数を別の関数に転送する」では、ReflectionClassの使用について説明しています。私はいくつかの宿題をしました、そしてこれはReflectionMethod::invokeArgsを使った結果です。

class bzkObjectWrapperException extends Exception { }

class bzkObjectWrapper {

    public $object;
    public $method;
    public $args; 

    public function __construct($object, $method, $args = array() )  { 
        $this->object = $object;
        $this->method = $method;
        $this->args = $args;
    }

    public function execute() {

        $object = $this->object;
        $method = $this->method;
        $args   = is_array($this->args) ? $this->args : array($this->args);
        $classname = get_class($object);

        $reflectionMethod = new ReflectionMethod($classname, $method);
        return $reflectionMethod->invokeArgs($object, $args);   
    }
}

それがお役に立てば幸いです。そして、2番目のトピックへのリンクに感謝します。

4

1 に答える 1