2009-06-04 2 views
1

В настоящее время я делаю это так, но, кажется, не может быть надлежащим образом:Как назначить функцию члена в массив и назовем его

class Name 
{ 
    protected $jobs2do; 

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

     public function do() { 
     ... 
    } 
} 

Поскольку непосредственно назначить функцию вызовет предупреждение, должен сделать что-то вроде:

function func() 
{ 
... 
} 

$func_array[] = 'func'; 

сказать, положил его в строку, но я не знаю, как это сделать, когда это функция член.

Является ли следующая версия OK ?:

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); 
} 
+0

последнее редактирование должно работать ... – Jet

ответ

0

Написать класс для задания и использовать factory шаблон для их создания. Затем напишите класс JobManager, который должен поддерживать список 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(); 
     } 
    } 
} 
0

Посмотрите на тип 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"); 



Edit: Кажется, вы пытаетесь реализовать command pattern. В этом случае вы могли бы попробовать что-то вдоль этих линий:

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

Но я не буду называть функции пользователя, а функция член :( – omg

+0

не имеет значения.Посмотрите на мой маленький пример. – n3rd

+0

Спасибо, я обновил свой пост, не могли бы вы сказать мне, правильно ли это в конструкторе? – omg

0

Возможна несколько возможных решений этой проблемы. У вас есть командные и заводские шаблоны, представленные в других ответах. Это иллюстрирует, как использовать Visitor + Command шаблон сотрудничества.

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 из-за отсутствия встроенной поддержки для переопределения явного метода.

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

Вы также можете заменить «бар» на строковую переменную.

0

Не знаете, правильно ли это. но это то, как я делаю свое.

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