Wie eine Elementfunktion zu einem Array zugeordnet werden und es nennt
-
09-09-2019 - |
Frage
Ich bin derzeit es auf diese Weise zu tun, aber scheint nicht der richtige Weg zu sein:
class Name
{
protected $jobs2do;
public function __construct($string) {
$this->jobs2do[] = $this->do;
}
public function do() {
...
}
}
Da direkt eine Funktion zuweisen Warnung verursachen, sollte so etwas tun:
function func()
{
...
}
$func_array[] = 'func';
sagen, es in einen String setzen, aber ich weiß nicht, wie es zu tun ist, wenn es eine Member-Funktion.
Ist die folgende Version OK:?
class Name
{
public $jobs2do;
public function __construct($string) {
$this->jobs2do[] = array($this,'do');
}
public function do() {
...
}
}
, wenn es nennen, nur:
$instance = new Name();
foreach ($instance->jobs2do as $job)
{
call_user_func($job);
}
Lösung
eine Klasse für Arbeit schreiben und benutzen Fabrik Muster zu schaffen sie. Schreiben Sie dann eine Klasse Jobmanager wihich eine Liste ob Job-Instanzen beibehalten sollte.
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();
}
}
}
Andere Tipps
Es gibt (mindestens) vier Möglichkeiten, dies zu tun. Es gibt auch andere Möglichkeiten, aber diese sind die meisten rein. Die Methode Versionen erfordern PHP5 auf ein Minimum.
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);
Sie können mit einem String-Variable 'bar' ersetzen, auch.
Bitte überprüfen Sie call_user_func () oder call_user_func_array ()
Werfen Sie einen Blick auf die aufrufbar Pseudo-Typ. Anschließend können Sie diese Funktion aufrufen, mit 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: Es scheint, Sie versuchen, die Befehlsmuster zu implementieren . In diesem Fall könnten Sie etwas in diese Richtung versuchen:
// 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");
}
Es kann mehrere mögliche Lösungen für dieses Problem sein. Sie haben Command and Factory-Muster in anderen Antworten präsentiert. Dies zeigt, wie die Verwendung Besucher + Befehl Muster Zusammenarbeit.
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();
Ausgabe:
Name washes dishes
Name does shopping
Eine Klasse Implementierung IJob
Schnittstelle ist ein Befehl, der übergeben werden kann und für die spätere Ausführung gespeichert. Die Art und Weise Name
Objekt ruft Arbeitsplätze in der Sammlung ($this
Referenz vorbei) ist typisch für Besucher-Muster (auf diese Weise Job Objekt hat seine Anrufer zugreifen - Name
Objekt). Allerdings Muster wahre Besucher ist nicht möglich, in PHP wegen des Mangels an native Unterstützung für explizite Methode überwiegend.
weiß nicht, ob dies der richtige Weg ist. aber das ist, wie ich meine tun.
$this->api['google']['+1Button']=function($str)
{
echo $str;
};
$this->api['google']['+1Button']("hello world");