There is already a very good analysis of Purple. It is suggested that we take a look at it first.
Pimple - A simple PHP dependency injection container
Read PHP - Pimple Source Notes (Part 1)
Read PHP - Pimple Source Notes (Part 2)
Here we supplement the description of the core method with examples:
Related types:
-
Services (similar singletons):
$container['session'] = function ($c) { return new Session($c['session_storage']); };
-
Factory services (multiple instances)
$container['session'] = $container->factory(function ($c) { return new Session($c['session_storage']); });
-
Parameters (just save some variables)
$container['cookie_name'] = 'SESSION_ID';
-
Protect parameters (anonymous functions are all considered [1 service], but if you want to be just a parameter, you need to use this method)
$container['random_func'] = $container->protect(function () { return rand(); });
set assignment related source code:
public function offsetSet($id, $value) { //If it is frozen, it cannot be assigned if (isset($this->frozen[$id])) { throw new FrozenServiceException($id); } //Deposit in values $this->values[$id] = $value; //Deposit in keys $this->keys[$id] = true; }
Take [1 service] as an example, after calling the offsetSet method:
$this->values['session'] = function ($c) { return new Session($c['session_storage']); }; $this->keys['session'] = true;
When using $session=$container['session'];, the offsetGet method is called:
public function offsetGet($id) { //$this - > keys ['session'] exists if (!isset($this->keys[$id])) { throw new UnknownIdentifierException($id); } if ( isset($this->raw[$id])//This - > raw ['session'], the first call is not there, so false, repeated calls are ture. || !\is_object($this->values[$id])//All anonymous functions are object s, so they are false. The corresponding case [3 parameters] is true || isset($this->protected[$this->values[$id]])//protected method is not invoked, so it is false, and the corresponding case [4 protection parameters] is true. || !\method_exists($this->values[$id], '__invoke')//All anonymous functions have the u invoke method, so it's false ) { //To sum up, if it's the first call, it won't do that. If it's related to repeated calls, parameters, and protected methods, it will. return $this->values[$id]; } //Determine if there are multiple instances, corresponding to [2 Factory Service], because we did not call the factories method, so this step will not be executed? if (isset($this->factories[$this->values[$id]])) { return $this->values[$id]($this); } //At this point, $ray is the anonymous function ($c) $raw = $this->values[$id]; //Reassigning $this - > values ['session'], passing in $this, which is equivalent to function ($this), passes in $this because the anonymous function may contain other services. //For example, the above $c['session_storage'], $this is equivalent to $container['session_storage'], when passed in, triggers the call to offsetGet. $val = $this->values[$id] = $raw($this); //Save the original anonymous function in $this - > ray, $this - > raw ['session'] has value at this time, and return directly to the upper decision when repeated access, which is equivalent to the singleton mode. $this->raw[$id] = $raw; //Markup is frozen, offsetSet or extension is not allowed after get $this->frozen[$id] = true; //Return $this - > values ['session'] return $val; }