2017-02-18 2 views
1

Lets sagen, ich habe einen Verschluss:Passing Variable Schließung

$object->group(function() { 
    $object->add('example'); 
    $object->add('example'); 
}); 

Es wird nicht funktionieren, weil $ Objekt nicht in der Schließung definiert ist.

Notice: Undefined variable: Manager

Also ich use ($object) haben würde:

$object->group(function() use ($object) { 
    $object->add('example'); 
    $object->add('example'); 
}); 

Jetzt will ich es halten so einfach wie das erste so irgendwie $ Objekt injiziert werden in die Schließung.

Der Laravel Rahmen tut dies mit Routen zum Beispiel:

Route::group(['middleware' => 'auth'], function() { 
    Route::get('/', function() { 
     // Uses Auth Middleware 
    }); 

    Route::get('user/profile', function() { 
     // Uses Auth Middleware 
    }); 
}); 

Ich glaube Laravel tut dies mit der Reflection Klasse.

Wie konnte ich das erreichen?

+0

Ich sehe absolut nichts falsch mit 'function() use ($ object)'. Es gibt nichts saubereres mit dem anderen Ansatz. Absolut zilch. –

+0

Ich will nur wissen, wie Laravel das macht. –

+0

Laravel verwendet 'statisch'. Du benutzt Objekte. –

Antwort

0

Ihr Ziel ist es, zu wissen, wie man einem Verschluss einen Parameter liefert. Es ist mit call_user_func_array erreicht.

Definieren wir eine Methode in einer Klasse, die eine Schließung akzeptiert.

class MyTestClass 
{ 
    public function doWork(callable $callback) 
    { 
     return call_user_func_array($callback, [$this]); 
    } 
} 

$obj = new MyTestClass(); 

$obj->doWork(function(MyTestClass $obj) { 
    // 
}); 

Hinweis: nicht getestet, aber ich nehme es das ist, was Sie nach waren?

+0

In diesem Fall müssen Sie noch den Parameter einstellen, richtig? Ich möchte es genauso machen wie Laravel. Also irgendwie wird die Abhängigkeit in die Schließung injiziert. Vielleicht wird der Inhalt geklont und angehängt? Ich habe keine Ahnung. –

+0

Ich habe eine sehr hässliche Art gefunden, dies zu tun, also habe ich mich einfach dazu entschieden, bei den Parametern zu bleiben. Was Sie tun könnten, ist, den Inhalt der Methode wie folgt zu erhalten: http://stackoverflow.com/questions/7026690/reconstruct-get-code-of-php-function. Verwenden Sie dann create_function, um eine Funktion zu erstellen, die einen Parameter akzeptiert und dann die Abhängigkeit eingibt. –

+1

Sie können variable Anzahl von Parametern in Ihrem Verschluss haben. Sie können NULL-Werte haben. Wenn Sie eine variable Anzahl von Parametern eingeben möchten, müssen Sie wahrscheinlich mit 'Reflection' spielen und das wird hässlich (um zu sehen, was es als Parameter erwartet). Ich glaube nicht, dass du es wirklich übertreiben musst :) –

0

Sie müssen sich keine Gedanken über Reflexion machen. Der Deputy-Injection-Container des berüchtigten Laravel wird es für Sie erledigen. Alles, was Sie brauchen, ist ihm zu sagen, was zu injizieren ist, wenn class oder interface Typ angedeutet ist.

// xXxServiceProvider.php 
function register(){ 
    ... 
    this->app->bind('ObjNamespace\ObjClass', function ($app) { 
     return new ObjNamepsace\ObjClass(); 
    }); 
} 

Nehmen wir jetzt an, Sie möchten ein ObjNamepsace\ObjClass in Ihrer Route behandeln.

Route::get('user/profile', function (ObjNamepsace\ObjClass $object) { 
    // $object is resolved via type hinting 
}); 

Darüber hinaus gibt es drei Bindungsmethoden, können Sie wählen, welche passt zu Ihrem Anwendungsfall:

  • bind: spritzt eine neue Instanz bei jedem Aufruf wird Laravel ein neues $ Objekt erstellen jedes Mal.

  • singleton: injiziert dieselbe Instanz, Laravel erstellt die Instanz beim ersten Aufruf und injiziert sie bei jedem Aufruf benötigt. Verwenden Sie es, wenn Sie einmal $object erstellen möchten.

  • instance: Sie binden die class oder interface an eine Objektinstanz.

+0

Die Laravel-Routen waren ein Beispiel für das, was ich erreichen möchte. Dieses Projekt wird nicht in Laravel gemacht –

+0

Warum ist Laravels Service Container "berüchtigt" –

+0

Soweit ich weiß, unterscheidet sich die Verwendung von Abhängigkeitsinjektionen nicht sehr stark über Frameworks hinweg. Die gleichen Prinzipien gelten überall. – motia