Note that there are some explanatory texts on larger screens.

plurals
  1. POLaravel 4 Container Internal Workings
    primarykey
    data
    text
    <p>I've been studying the laravel 4 container to get more knowledge of the internals of laravel and to upgrade my own skills in writing better code.</p> <p>However i'm failing to understand 3 similar pieces of code. I'll use the smallest snippet to keep this question clean.</p> <p>Similar questions can be found in links below. Although people have replied with correct answers, I'm not satisfied with simply 'Knowing how to use it, but not knowing how it all works inside'. So i really hope someone can give an explanation to all this.</p> <p><a href="https://stackoverflow.com/questions/17296224/laravel-4-container-class-share-function-closure-logic">Question 1</a> <a href="https://stackoverflow.com/questions/15758936/laravel-core-method-confusion/17295616#17295616">Question 2</a></p> <pre><code>&lt;?php namespace Illuminate\Container; use Closure, ArrayAccess, ReflectionParameter; class BindingResolutionException extends \Exception {} class Container implements ArrayAccess { /** * Wrap a Closure such that it is shared. * * @param Closure $closure * @return Closure */ public function share(Closure $closure) { return function($container) use ($closure) { // We'll simply declare a static variable within the Closures and if // it has not been set we'll execute the given Closure to resolve // the value and return it back to the consumers of the method. static $object; if (is_null($object)) { $object = $closure($container); } return $object; }; } } </code></pre> <p>How does the share method know that the $container variable in that function is in fact an instance of Illuminate\Container? It isn't defined within the scope of that function. Neither is it defined in the following example usecase (which wouldn't help anyway)</p> <pre><code>class AuthServiceProvider extends ServiceProvider{ /** * Register the service provider. * * @return void */ public function register() { $this-&gt;app['auth'] = $this-&gt;app-&gt;share(function($app) { // Once the authentication service has actually been requested by the developer // we will set a variable in the application indicating such. This helps us // know that we need to set any queued cookies in the after event later. $app['auth.loaded'] = true; return new AuthManager($app); }); } } </code></pre> <p>I'd expect a different implementation, so here comes</p> <pre><code>class MyContainer{ public function share(Closure $closure) { $container = $this; return function() use ($closure, $container) { static $object; if(is_null($object)) { $object = $closure($container); } return $object; }; } } $closure = function($container) { var_dump($container); }; $container = new MyContainer(); call_user_func($container-&gt;share($closure)); //dumps an instance of MyContainer -&gt; which is the wanted behaviour $container = new Illuminate\Container\Container(); call_user_func($container-&gt;share($closure)); //Throws a warning AND a notice //Warning: Missing argument 1 for Illuminate\Container\Container::Illuminate\Container\{closure}() in /Users/thomas/Sites/Troll/vendor/illuminate/container/Illuminate/Container/Container.php on line 128 //NOTICE: Notice: Undefined variable: container in /Users/thomas/Sites/Troll/vendor/illuminate/container/Illuminate/Container/Container.php on line 137 //and even worse the output of the var_dump is NULL </code></pre> <p>I have the same problem in understanding the extend and the bind method, which both have the same implementation of passing a none-existing parameter as a closure argument, but i cannot grasp how it is resolved to the container instance itself?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload