最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

Pimple运行流程浅析(PHP容器)

来源:懂视网 责编:小采 时间:2020-11-03 18:21:02
文档

Pimple运行流程浅析(PHP容器)

Pimple运行流程浅析(PHP容器):需要具备的知识点闭包闭包和匿名函数在PHP5.3.0中引入的。闭包是指:创建时封装周围状态的函数。即使闭包所处的环境不存在了,闭包中封装的状态依然存在。理论上,闭包和匿名函数是不同的概念。但是PHP将其视作相同概念。实际上,闭包和匿名函数是伪装成函数
推荐度:
导读Pimple运行流程浅析(PHP容器):需要具备的知识点闭包闭包和匿名函数在PHP5.3.0中引入的。闭包是指:创建时封装周围状态的函数。即使闭包所处的环境不存在了,闭包中封装的状态依然存在。理论上,闭包和匿名函数是不同的概念。但是PHP将其视作相同概念。实际上,闭包和匿名函数是伪装成函数

我们的应用可以基于Pimple开发:

namespace EasyWeChatFoundation;
use PimpleContainer;
class Application extends Container
{
 /**
 * Service Providers.
 *
 * @var array
 */
 protected $providers = [
 ServiceProvidersServerServiceProvider::class,
 ServiceProvidersUserServiceProvider::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 = [
 ServiceProvidersServerServiceProvider::class,
 ServiceProvidersUserServiceProvider::class
];

UserServiceProvider为例,我们看其代码实现:

namespace EasyWeChatFoundationServiceProviders;
use EasyWeChatUserUser;
use PimpleContainer;
use PimpleServiceProviderInterface;
/**
 * 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;

到这里,我们还没有实例化真正提供实际功能的类EasyWeChatUserUsr。但已经完成了服务提供者的注册工作。

当我们运行到这里:

$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知识,请访问php教程!

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文档

Pimple运行流程浅析(PHP容器)

Pimple运行流程浅析(PHP容器):需要具备的知识点闭包闭包和匿名函数在PHP5.3.0中引入的。闭包是指:创建时封装周围状态的函数。即使闭包所处的环境不存在了,闭包中封装的状态依然存在。理论上,闭包和匿名函数是不同的概念。但是PHP将其视作相同概念。实际上,闭包和匿名函数是伪装成函数
推荐度:
标签: 流程 php 执行
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top