亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > PHP > 正文

PHP容器Pimple運行流程的分析

2020-03-22 18:56:27
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了關于PHP容器Pimple運行流程的分析,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

需要具備的知識點閉包

閉包和匿名函數在PHP5.3.0中引入的。

閉包是指:創建時封裝周圍狀態的函數。即使閉包所處的環境不存在了,閉包中封裝的狀態依然存在。

理論上,閉包和匿名函數是不同的概念。但是PHP將其視作相同概念。
實際上,閉包和匿名函數是偽裝成函數的對象。他們是Closure類的實例。

閉包和字符串、整數一樣,是一等值類型。

創建閉包:

<?php$closure = function ($name) {    return 'Hello ' . $name;};echo $closure('nesfo');//Hello nesfovar_dump(method_exists($closure, '__invoke'));//true
我們之所以能調用$closure變量,是因為這個變量的值是一個閉包,而且閉包對象實現了__invoke()魔術方法。只要變量名后有(),PHP就會查找并調用__invoke()方法。

通常會把PHP閉包當作函數的回調使用。

array_map(), preg_replace_callback()方法都會用到回調函數,這是使用閉包的最佳時機!

舉個例子:

<?php$numbersPlusOne = array_map(function ($number) {    return $number + 1;}, [1, 2, 3]);print_r($numbersPlusOne);

得到結果:

[2, 3, 4]

在閉包出現之前,只能單獨創建具名函數,然后使用名稱引用那個函數。這么做,代碼執行會稍微慢點,而且把回調的實現和使用場景隔離了。

<?phpfunction incrementNum ($number) {    return $number + 1;}$numbersPlusOne = array_map('incrementNum', [1, 2, 3]);print_r($numbersPlusOne);
SPLArrayAccess

實現ArrayAccess接口,可以使得object像array那樣操作。ArrayAccess接口包含四個必須實現的方法:

interface ArrayAccess {    //檢查一個偏移位置是否存在     html' target='_blank'>public mixed offsetExists ( mixed $offset  );        //獲取一個偏移位置的值     public mixed offsetGet( mixed $offset  );        //設置一個偏移位置的值     public mixed offsetSet ( mixed $offset  );        //復位一個偏移位置的值     public mixed offsetUnset  ( mixed $offset  );}
SplObjectStorage

SplObjectStorage類實現了以對象為鍵的映射(map)或對象的集合(如果忽略作為鍵的對象所對應的數據)這種數據結構。這個類的實例很像一個數組,但是它所存放的對象都是唯一。該類的另一個特點是,可以直接從中刪除指定的對象,而不需要遍歷或搜索整個集合。

::class語法

因為 ::class 表示是字符串。用 ::class 的好處在于 IDE 里面可以直接改名一個 class,然后 IDE 自動處理相關引用。
同時,PHP 執行相關代碼時,是不會先加載相關 class 的。

同理,代碼自動化檢查 inspect 也可以正確識別 class。

Pimple容器流程淺析

Pimpl是php社區中比較流行的容器。代碼不是很多,詳見https://github.com/silexphp/P... 。

我們的應用可以基于Pimple開發:

namespace EasyWeChat/Foundation;use Pimple/Container;class Application extends Container{    /**     * Service Providers.     *     * @var array     */    protected $providers = [        ServiceProviders/ServerServiceProvider::class,        ServiceProviders/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->offsetGet($id);    }    /**     * Magic set access.     *     * @param string $id     * @param mixed  $value     */    public function __set($id, $value)    {        $this->offsetSet($id, $value);    }}

如何使用我們的應用:

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

之后我們就可以使用$user對象的方法了。我們發現其實并沒有$this->user這個屬性,但是可以直接使用。主要是這兩個方法起的作用:

public function offsetSet($id, $value){}public function offsetGet($id){}

下面我們將解釋在執行這兩句代碼,Pimple做了什么。但在解釋這個之前,我們先看看容器的一些核心概念。

服務提供者

服務提供者是連接容器與具體功能實現類的橋梁。服務提供者需要實現接口ServiceProviderInterface:

namespace Pimple;/** * Pimple service provider interface. * * @author  Fabien Potencier * @author  Dominik Zogg */interface ServiceProviderInterface{    /**     * Registers services on the given container.     *     * This method should only be used to configure services and parameters.     * It should not get services.     *     * @param Container $pimple A container instance     */    public function register(Container $pimple);}

所有服務提供者必須實現接口register方法。

我們的應用里默認有2個服務提供者:

protected $providers = [    ServiceProviders/ServerServiceProvider::class,    ServiceProviders/UserServiceProvider::class];

以UserServiceProvider為例,我們看其代碼實現:

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 should only be 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']);        };    }}

我們看到,該服務提供者的注冊方法會給容器增加屬性user,但是返回的不是對象,而是一個閉包。這個后面我再做講解。

服務注冊

我們在Application里構造函數里使用$this->registerProviders();對所有服務提供者進行了注冊:

private function registerProviders(){    foreach ($this->providers as $provider) {        $this->register(new $provider());    }}

仔細看,我們發現這里實例化了服務提供者,并調用了容器Pimple的register方法:

public function register(ServiceProviderInterface $provider, array $values = array()){    $provider->register($this);    foreach ($values as $key => $value) {        $this[$key] = $value;    }    return $this;}

而這里調用了服務提供者的register方法,也就是我們在上一節中提到的:注冊方法給容器增加了屬性user,但返回的不是對象,而是一個閉包。

當我們給容器Pimple添加屬性user的同時,會調用offsetSet($id, $value)方法:給容器Pimple的屬性values、keys分別賦值:

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

到這里,我們還沒有實例化真正提供實際功能的類EasyWeChat/User/Usr。但已經完成了服務提供者的注冊工作。

當我們運行到這里:

$user = $app->user;

會調用offsetGet($id)并進行實例化真正的類:

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

$raw獲取的是閉包:

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

$raw($this)返回的是實例化的對象User。也就是說只有實際調用才會去實例化具體的類。后面我們就可以通過$this['user']或者$this->user調用User類里的方法了。

當然,Pimple里還有很多特性值得我們去深入研究,這里不做過多講解。

以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP !

相關推薦:

wordpress使用wp_head()函數的方法

PHP變量之作用域、global、static等關鍵字

以上就是PHP容器Pimple運行流程的分析的詳細內容,更多請關注 其它相關文章!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91在线视频成人| 不卡在线观看电视剧完整版| 黑人巨大精品欧美一区二区免费| 成人国产亚洲精品a区天堂华泰| 欧美极品少妇xxxxⅹ免费视频| 亚洲视频axxx| 最近2019免费中文字幕视频三| 日韩毛片在线观看| 欧美大尺度激情区在线播放| 国产精品视频26uuu| 欧美日韩综合视频| 亚洲欧美另类在线观看| 亚洲福利在线看| 日韩国产欧美精品一区二区三区| 精品国产91乱高清在线观看| 成人激情免费在线| 57pao精品| 欧美日韩激情视频8区| 久久精品视频va| 日韩小视频在线观看| 国产91精品在线播放| 日韩美女视频免费在线观看| 青草青草久热精品视频在线观看| 精品国产福利视频| 成人在线视频福利| 国产精品亚发布| 亚洲欧美一区二区三区久久| 国产精品成人v| 欧美xxxx综合视频| 欧美激情一级欧美精品| 欧美午夜片欧美片在线观看| 国产福利视频一区二区| 欧美精品日韩www.p站| 精品毛片三在线观看| 久久久久这里只有精品| 亚洲bt欧美bt日本bt| 欧美中文字幕在线观看| 久久视频国产精品免费视频在线| 中文字幕国产精品久久| 久久韩国免费视频| 91免费精品视频| 久久久久久久国产精品视频| 日韩网站在线观看| 亚洲新声在线观看| 国产精品久久久久久亚洲影视| 日本精品性网站在线观看| 欧美成人激情视频免费观看| 97视频在线观看亚洲| 91久久精品久久国产性色也91| 日韩美女视频免费在线观看| 日韩精品在线免费播放| 久久精品中文字幕一区| 69视频在线播放| 欧美黑人xxxx| 国产精品丝袜久久久久久不卡| 亚洲欧美国产日韩中文字幕| 国产亚洲欧美一区| 精品久久久久久久久中文字幕| 国产精品视频永久免费播放| 久久久在线视频| 国产一区二区激情| 国产91在线播放九色快色| 国产mv久久久| 成人网欧美在线视频| 国产+人+亚洲| 欧美黑人一区二区三区| 久久亚洲国产精品成人av秋霞| 91欧美日韩一区| 欧美视频免费在线| 欧美性xxxxxxxxx| 欧美性高潮床叫视频| 国产成人精彩在线视频九色| 欧美激情在线播放| 91国产美女在线观看| 亚洲精品视频在线播放| 国产精品久久久久久久久久久久久久| 久久久精品视频成人| 国内外成人免费激情在线视频| 国产精品91免费在线| 久久久综合免费视频| 成人午夜在线视频一区| 亚洲97在线观看| 日韩电影大全免费观看2023年上| 日韩av在线导航| 欧美电影免费看| 日本在线精品视频| 欧美第一黄网免费网站| 日韩有码在线播放| 成人啪啪免费看| 91av在线影院| 日日狠狠久久偷偷四色综合免费| 琪琪亚洲精品午夜在线| 亚洲综合色av| 超碰97人人做人人爱少妇| 亚洲男女自偷自拍图片另类| 综合国产在线视频| 91成人在线观看国产| 精品一区二区三区三区| 欧美自拍大量在线观看| 亚洲美女av网站| 亚洲成人av在线| 国产精品美女视频网站| 亚洲人av在线影院| 亚洲精品99久久久久| 国产成人精品一区二区在线| 国产欧美一区二区| 亚洲精品日韩激情在线电影| 国产亚洲精品久久| 亚洲精品99久久久久| 97在线日本国产| 成人在线小视频| 欧美另类暴力丝袜| 91免费视频国产| 日韩最新在线视频| 日韩免费高清在线观看| 欧美一区在线直播| 国产99视频精品免视看7| 国产成人精品最新| 国产主播欧美精品| 狠狠做深爱婷婷久久综合一区| 日韩毛片在线看| 91网站免费观看| 久久手机免费视频| 欧美在线观看www| 亚洲午夜av久久乱码| 这里只有精品在线观看| 久久久av网站| 日韩视频在线一区| 91高清在线免费观看| 欧美性69xxxx肥| 色综合色综合久久综合频道88| 亚洲黄色成人网| 亚洲第一页在线| 欧美黑人国产人伦爽爽爽| 中文字幕欧美在线| 久久久久久久久久久av| 亚洲国产中文字幕久久网| 国产精品久久久久久影视| 日韩在线观看视频免费| 一区二区三欧美| 亚洲免费电影在线观看| 欲色天天网综合久久| 欧美成人自拍视频| 黑人巨大精品欧美一区免费视频| 国产精品免费久久久久久| 亚洲精品第一国产综合精品| 51色欧美片视频在线观看| 欧美视频中文字幕在线| 亚洲精品福利资源站| 成人国产精品av| 国产成+人+综合+亚洲欧洲| 国产又爽又黄的激情精品视频| 欧美中文字幕在线| 欧美最近摘花xxxx摘花| 欧美高清视频在线| 国产美女主播一区| 亚洲va男人天堂| 国产精品久久91| 国产精品一区二区久久久| 日韩在线视频线视频免费网站| 亚洲成人xxx| 成人免费在线视频网址| 国产精品久久久精品| 久久国产精品久久精品|