Bir dizi için bir üye işlev atamak ve onu aramak için nasıl

6 Cevap php

Ben şu anda bunu bu şekilde yapıyor, ama doğru yolu olmayabilir görünüyor değilim:

class Name
{
    protected $jobs2do;

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

        public function do() {
        ...
    }
}

Doğrudan uyarıyı neden olacak bir işlev atamak için, gibi bir şey yapmak gerekir:

function func()
{
...
}

$func_array[] = 'func';

diyelim ki, bir dizeye koydu, ama bir üye işlev olduğunda bunu nasıl bilmiyorum.

Aşağıdaki sürüm tamam mı?:

class Name
{
    public $jobs2do;

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

        public function do() {
        ...
    }
}

çağırdığınızda, sadece:

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

6 Cevap

İş için bir sınıf yazmak ve bunları oluşturmak için factory desen kullanın. Sonra bir liste ob İş örneklerini muhafaza etmeli wihich sınıf JobManager yazın.

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();
    	}
    }
}

Bunu yapmak için 4 yolu (en az) vardır. Orada başka yolları vardır ama bu en saf vardır. Yöntem, versiyonları, en az PHP5 gerektirir.

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);

Sen de, bir dize değişkeni olan 'bar' değiştirebilirsiniz.

callable sözde türü bir göz atın. Bunu daha sonra o işlevi çağırabilirsiniz 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");



Edit: It seems you're trying to implement the command pattern. In that case you could try something along these lines:

// 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");
}

Bu sorunun birkaç olası çözüm olabilir. Diğer cevaplarda sunulan Komutanlığı ve Fabrika desenler var. Bu bir Visitor + Command desen işbirliğini nasıl kullanılacağını göstermektedir.

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();

Çıktı:

Name washes dishes
Name does shopping

Uygulanması A sınıfı IJob arayüzü geçti ve daha sonra çalıştırılmak üzere saklanabilir bir komut. Yol Name nesne ($this referans geçen) koleksiyonunda işleri çağırır (- Name nesnesi bu iş yolu nesne arayan erişmek vardır) Ziyaretçi deseni için tipiktir. Ancak, gerçek Ziyaretçi desen nedeniyle açık yöntem geçersiz kılma için doğal destek eksikliği PHP mümkün değildir.

Bu doğru yolu ise dont know. ama bu ben benim bunu nasıl.

$this->api['google']['+1Button']=function($str)
    {
        echo $str;
    };
    $this->api['google']['+1Button']("hello world");