سؤال

أنا أفعل ذلك حاليا بهذه الطريقة، ولكن يبدو أنه لا يكون بالطريقة الصحيحة:

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);
}
هل كانت مفيدة؟

المحلول

اكتب فئة للعمل والاستخدام مصنع نمط لخلقها. ثم اكتب فئة يجب أن يحتفظ jobmanager wihich بمثيلات مهمة قائمة OB.

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 () أو call_user_func_array ()

نلقي نظرة على callable. نوع الزائفة. يمكنك بعد ذلك الاتصال بهذه الوظيفة 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");
}

يمكن أن يكون هناك العديد من الحلول الممكنة لهذه المشكلة. لديك أنماط الأوامر والمصنع المقدمة في ردود أخرى. هذا واحد يوضح كيفية استخدام الزائر + أمر التعاون النمط.

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 بسبب عدم وجود دعم الأصلي للطريقة الصريحة.

لا أعرف إذا كانت هذه هي الطريقة الصحيحة. ولكن هذه هي الطريقة التي أقوم بها.

$this->api['google']['+1Button']=function($str)
    {
        echo $str;
    };
    $this->api['google']['+1Button']("hello world");
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top