質問
私は現在この方法でそれを行っていますが、適切な方法ではないようです:
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);
}
解決
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();
}
}
}
他のヒント
これを行うには(少なくとも)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);
あなたも、文字列変数に「バー」を置き換えることができます。
call_user_func()のか<のhref = "HTTPをご確認ください。ネット/ call_user_func_array」のrel = "nofollowをnoreferrer"> call_user_func_array()の
呼び出し可能なを見てみましょう>擬似型。あなたは、その後でその関数を呼び出すことができます 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");
}
この問題にはいくつかの可能な解決策が存在する場合があります。あなたは他の回答で提示コマンドや工場のパターンを持っています。この1はビジターの+ <のhref = "http://dofactory.comを使用する方法を示しています/Patterns/PatternCommand.aspx」のrel = "nofollowをnoreferrer">コマンドは、パターンの協力をを。
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
オブジェクトこうしてジョブオブジェクトは、呼び出し元にアクセスしている)Visitorパターンの典型的です。しかし、真のVisitorパターンが原因明示的なオーバーライドのネイティブサポートの不足のためにPHPで可能ではありません。
これは正しい方法であれば知りません。しかし、これは私が鉱山を行う方法です。
$this->api['google']['+1Button']=function($str)
{
echo $str;
};
$this->api['google']['+1Button']("hello world");