Analysis of PHP container pimple running process

Source: Internet
Author: User
This article mainly introduces the PHP container pimple running flow analysis, has a certain reference value, now share to everyone, the need for friends can refer to

Need to have the knowledge point

Closed Package

Closures and anonymous functions are introduced in the PHP5.3.0.

Closures are functions that encapsulate the surrounding state when created. Even if the environment in which the closure is located does not exist, the state of encapsulation in the closure still exists.

In
theory, closures and anonymous functions are different concepts. But PHP sees it as the same concept.
In fact, closures and anonymous functions are objects disguised as functions. They are instances of the closure class.

Closures, like strings and integers, are equivalent types.

To create a closure:

<?php$closure = function ($name) {    return ' Hello '. $name;}; echo $closure (' NESFO ');//hello nesfovar_dump (Method_exists ($closure, ' __invoke '));//true
The
reason we can invoke a $closure variable is because the value of the variable is a closure, and the closure object implements the __invoke() magic method. As long as the variable name is followed () , PHP will find and invoke the __invoke() method.

PHP closures are often used as callbacks to functions.

array_map(), the preg_replace_callback() method will use the callback function, which is the best time to use closures!

As an example:

<?php$numbersplusone = Array_map (function ($number) {    return $number + 1;}, [1, 2, 3]);p Rint_r ($numbersPlusOne);

Get results:

[2, 3, 4]

Before a closure occurs, you can only create a named function by itself, and then use the name to refer to that function. In doing so, the code executes slightly more slowly and isolates the implementation of the callback from the usage scenario.

<?phpfunction Incrementnum ($number) {    return $number + 1;} $numbersPlusOne = Array_map (' Incrementnum ', [1, 2, 3]);p Rint_r ($numbersPlusOne);

Spl

Arrayaccess

Implementing the Arrayaccess interface allows an object to operate like an array. The Arrayaccess interface contains four methods that must be implemented:

Interface Arrayaccess {    //check if an offset location exists public     mixed offsetexists (mixed $offset  );        Gets the value of an offset position public     mixed offsetget (mixed $offset  );        Sets the value of an offset position public     mixed Offsetset (mixed $offset  );        Resets the value of an offset position public     mixed Offsetunset  (mixed $offset  );}

Splobjectstorage

The Splobjectstorage class implements such a data structure as the object-key mapping (map) or the collection of objects (if the data corresponding to the object being the key is omitted). An instance of this class is much like an array, but the objects it holds are unique. Another feature of this class is that you can delete the specified object directly from it, without having to traverse or search the entire collection.

::classGrammar

Because ::class the representation is a string. ::classThe advantage is that the IDE can rename a class directly, and then the IDE automatically handles the relevant reference.
Also, when PHP executes the relevant code, it does not load the relevant class first.

Similarly, code automation check inspect can also correctly identify class.

Brief analysis of pimple container flow

Pimpl is a relatively popular container in the PHP community. Code is not many, see Https://github.com/silexphp/P ....

Our applications can be developed on the basis of pimple:

Namespace Easywechat\foundation;use pimple\container;class Application extends container{/** * Service Providers. * * @var Array */protected $providers = [Serviceproviders\serverserviceprovider::class, Ser    Viceproviders\userserviceprovider::class];     /** * Application constructor.        * * @param array $config */Public function __construct ($config) {parent::__construct ();        $this [' config '] = function () use ($config) {return new config ($config);        };        if ($this [' config '] [' Debug ']) {error_reporting (E_all);    } $this->registerproviders ();     }/** * Add a provider.        * * @param string $provider * * @return Application */Public Function AddProvider ($provider) {        Array_push ($this->providers, $provider);    return $this;     }/** * Set providers. * * @param array $providers */Public function SetprovideRS (array $providers) {$this->providers = [];        foreach ($providers as $provider) {$this->addprovider ($provider);     }}/** * Return all providers.    * * @return Array */Public function getproviders () {return $this->providers;     }/** * Magic get access. * * @param string $id * * @return Mixed */Public Function __get ($id) {return $this->offs    Etget ($id);     }/** * Magic set access. * * @param string $id * @param mixed $value */Public Function __set ($id, $value) {$this->of    Fsetset ($id, $value); }}

How to use our app:

$app = new Application ([]); $user = $app->user;

Then we can use $user the method of the object. We found that this attribute is not actually available $this->user , but can be used directly. This is mainly the effect of these two methods:

Public Function Offsetset ($id, $value) {}public function offsetget ($id) {}

Below we will explain what pimple did in executing these two lines of code. But before explaining this, let's look at some of the core concepts of the container.

Service Provider

A service provider is a bridge between a connection container and a specific function implementation class. The service provider needs to implement the interface ServiceProviderInterface :

Namespace pimple;/** * Pimple Service Provider interface. * * @author  Fabien potencier * @author  Dominik zogg */interface serviceproviderinterface{    /**     * Registers services on the given container.     *     * This method is should only being used to configure services and parameters.     * It should not get services.     *     * @param Container $pimple A Container Instance     * * Public    function Register (Container $pimple);}

All service providers must implement an interface register method.

There are 2 service providers in our app by default:

protected $providers = [    serviceproviders\serverserviceprovider::class,    serviceproviders\ Userserviceprovider::class];

Take Userserviceprovider as an example, we look at its code implementation:

namespace Easywechat\foundation\serviceproviders;use easywechat\user\user;use Pimple\container;use Pimple\ serviceproviderinterface;/** * Class Userserviceprovider. */class Userserviceprovider implements serviceproviderinterface{    /**     * Registers services on the given Container.     *     * This method is should only being used to configure services and parameters.     * It should not get services.     *     * @param Container $pimple A Container Instance     * * Public    function Register (Container $pimple)    {        $pimple [' user '] = function ($pimple) {            return new user ($pimple [' Access_token ']);        }}    

We see that the registration method of the service provider adds properties to the container user , but returns a closure instead of an object. I'll explain this later.

Service Registration

We used $this->registerProviders(); to register all service providers in the application constructor:

Private Function Registerproviders () {    foreach ($this->providers as $provider) {        $this->register (new $ Provider ());}    }

Looking closely, we found that the service provider was instantiated here and called the container pimple register method:

Public Function Register (serviceproviderinterface $provider, array $values = Array ()) {    $provider->register ($ this);    foreach ($values as $key = + $value) {        $this [$key] = $value;    }    return $this;}

And here is the method of invoking the service provider register , which we mentioned in the previous section: the registration method adds a property to the container, user but returns a closure instead of an object.

When we add properties to the container pimple user , we call the offsetSet($id, $value) method: give the container the Pimple property values , assign the keys value separately:

$this->values[$id] = $value; $this->keys[$id] = true;

Here, we haven't instantiated a class that really provides real-world functionality EasyWeChat\User\Usr . However, the registration of the service provider has been completed.

When we run to here:

$user = $app->user;

offsetGet($id)the real class is called and instantiated:

$raw = $this->values[$id]; $val = $this->values[$id] = $raw ($this); $this->raw[$id] = $raw; $this->frozen[$id ] = True;return $val;

$rawGet a closure:

$pimple [' user '] = function ($pimple) {    return new user ($pimple [' Access_token ']);};

$raw($this)Returns the instantiated object user. This means that only the actual invocation will instantiate the specific class. Later, we can pass $this['user'] or $this->user invoke the method in the user class.

Of course, there are a lot of features in pimple that we should go into in-depth study, here do not do too much explanation.

The above is the whole content of this article, I hope that everyone's learning has helped, more relevant content please pay attention to topic.alibabacloud.com!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.