1

私は現在このようにやっていますが、適切な方法ではないようです:

class Name
{
    protected $jobs2do;

    public function __construct($string) {
        $this->jobs2do[] = $this->do;
    }

        public function do() {
        ...
    }
}

関数を直接割り当てると警告が発生するため、次のようにする必要があります。

function func()
{
...
}

$func_array[] = 'func';

たとえば、文字列に入れますが、メンバー関数の場合はどうすればよいかわかりません。

次のバージョンは問題ありませんか?:

class Name
{
    public $jobs2do;

    public function __construct($string) {
        $this->jobs2do[] = array($this,'do');
    }

        public function do() {
        ...
    }
}

呼び出すときは、次のようにします。

$instance = new Name();
foreach ($instance->jobs2do as $job)
{
    call_user_func($job);
}
4

6 に答える 6

1

これを行うには(少なくとも)4つの方法があります。他の方法もありますが、これらは最も純粋です。メソッドバージョンには、少なくともPHP5が必要です。

class foo {
    public function bar($a) { return $a; }
}

$anObject = new foo();
$ret = call_user_func(array($anObject,'bar'), 1);
$ret = call_user_func_array(array($anObject,'bar'), array(1));
$ret = call_user_method('bar', $anObject, array(1));
$ret = call_user_method_array('bar', $anObjectm, 1);

'bar'を文字列変数に置き換えることもできます。

于 2009-06-04T13:53:10.213 に答える
0

Jobのクラスを作成し、ファクトリパターンを使用してそれらを作成します。次に、Jobインスタンスのリストを維持する必要があるクラスJobManagerを記述します。

interface iCallableJob
{
    public function run();
}

class Job implements iCallableJob
{
    // The parameterized factory method
    public static function factory($type)
    {
        $classname = 'Job_' . $type;
        if (class_exists($classname) && in_array('iCallableJob', class_implements('Job')))
        {
            return new $classname();
        }
        return null;
    }
    public function run() { return null; }
}

class Job_type1 extends Job 
{
    public function run() 
    {
        echo 'Job 1';
    }
}

class JobManager
{
    protected $jobs2do = array();

    public function addJob($type)
    {
        if ($job = Job::factory($type))
        {
            $this->jobs2do[] = $job;
            return $job;
        }
        return null;
    }
    public function runAll()
    {
        foreach ($this->jobs2do AS $job)
        {
            $job->run();
        }
    }
}
于 2009-06-04T10:35:42.170 に答える
0

これが正しい方法かどうかはわかりません。しかし、これが私のやり方です。

$this->api['google']['+1Button']=function($str)
    {
        echo $str;
    };
    $this->api['google']['+1Button']("hello world");
于 2013-07-30T20:42:41.750 に答える
0

この問題には、いくつかの解決策が考えられます。Command と Factory のパターンが他の返信に表示されています。これは、ビジター+コマンドパターンの連携を使用する方法を示しています。

class Name {

    protected $jobs = array();

    public function addJob(IJob $j) {
        $this->jobs[] = $j;
    }

    public function do() {
        foreach ($this->jobs as $j) {
            $j->run($this);
        }
    }

}

interface IJob {

    public function run(Name $invoker);

}

class WashDishes implements IJob {

    public function run(Name $invoker) {
        echo get_class($invoker) . ' washes dishes<br/>';
    }

}

class DoShopping implements IJob {

    public function run(Name $invoker) {
        echo get_class($invoker) . ' does shopping<br/>';
    }

}

$n = new Name();
$n->addJob(new WashDishes());
$n->addJob(new DoShopping());
$n->do();

出力:

Name washes dishes
Name does shopping

インターフェイスを実装するクラスIJobは、後で実行するために渡して保存できるコマンドです。オブジェクトがコレクション内のジョブを呼び出す方法Name(参照を渡す$this) は、典型的な訪問者パターンです (この方法では、ジョブ オブジェクトはその呼び出し元 -Nameオブジェクトにアクセスします)。ただし、明示的なメソッドのオーバーライドがネイティブでサポートされていないため、PHP で真の Visitor パターンを使用することはできません。

于 2009-06-04T13:44:00.513 に答える
0

呼び出し可能な疑似型を見てください。その後、その関数をcall_user_func()で呼び出すことができます:

class Foo {
    function bar($str) {
        echo($str);
    }
}

$foo = new Foo();
$func_array = array();
$func_array['foo->bar'] = array($foo, 'bar');  // this is the 'callable' pseudo-type

call_user_func($func_array['foo->bar'], "Hello World");



編集:コマンドパターンを実装しようとしているようです。その場合、次の行に沿って何かを試すことができます。

// define an interface for all actions
interface Executable {
    public function do();
}

// an example action
class DoSomething implements Executable {
    private $name;

    public __construct($name) {
        $this->name = $name;
    }

    public function do($str) {
        echo("Hello $str, my name is $this->name");
    }
}

$objects_to_process = array(new DoSomething("Foo"), new DoSomething("Bar"));
foreach ($objects_to_process as $obj) {
    if ($obj instanceof Executable)
        $obj->do("World");
}
于 2009-06-04T10:14:15.867 に答える
0

call_user_func()またはcall_user_func_array( )を確認してください

于 2009-06-04T10:15:47.110 に答える