首页 后端开发 php教程 awesome PHP之依赖注入器皿pimple

awesome PHP之依赖注入器皿pimple

Jun 13, 2016 am 11:55 AM
callable object the this

awesome PHP之依赖注入容器pimple
依赖注入(Dependency Injection)又叫控制反转(Inversion of Control)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,它能消除组件间的直接依赖关系,让组件的开发更独立,使用更灵活,在java框架中应用非常广泛。在php中由于语言特性不能完全照搬java的那一套,但简单的功能还是可以实现的。pimple就是php社区中比较流行的一种ioc容器。

可以用composer添加 require  "pimple/pimple": "1.*"

pimple的优势是简单,就一个文件

<?php /* * This file is part of Pimple. * * Copyright (c) 2009 Fabien Potencier * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is furnished * to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. *//** * Pimple main class. * * @package pimple * @author  Fabien Potencier */class Pimple implements \ArrayAccess{    private $values = array();    private $factories;    private $protected;    private $frozen = array();    private $raw = array();    private $keys = array();    /**     * Instantiate the container.     *     * Objects and parameters can be passed as argument to the constructor.     *     * @param array $values The parameters or objects.     */    public function __construct(array $values = array())    {        $this->factories = new \SplObjectStorage();        $this->protected = new \SplObjectStorage();        foreach ($values as $key => $value) {            $this->offsetSet($key, $value);        }    }    /**     * Sets a parameter or an object.     *     * Objects must be defined as Closures.     *     * Allowing any PHP callable leads to difficult to debug problems     * as function names (strings) are callable (creating a function with     * the same name as an existing parameter would break your container).     *     * @param  string           $id    The unique identifier for the parameter or object     * @param  mixed            $value The value of the parameter or a closure to define an object     * @throws RuntimeException Prevent override of a frozen service     */    public function offsetSet($id, $value)    {        if (isset($this->frozen[$id])) {            throw new \RuntimeException(sprintf('Cannot override frozen service "%s".', $id));        }        $this->values[$id] = $value;        $this->keys[$id] = true;    }    /**     * Gets a parameter or an object.     *     * @param string $id The unique identifier for the parameter or object     *     * @return mixed The value of the parameter or an object     *     * @throws InvalidArgumentException if the identifier is not defined     */    public function offsetGet($id)    {        if (!isset($this->keys[$id])) {            throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));        }        if (            isset($this->raw[$id])            || !is_object($this->values[$id])            || isset($this->protected[$this->values[$id]])            || !method_exists($this->values[$id], '__invoke')        ) {            return $this->values[$id];        }        if (isset($this->factories[$this->values[$id]])) {            return $this->values[$id]($this);        }        $this->frozen[$id] = true;        $this->raw[$id] = $this->values[$id];        return $this->values[$id] = $this->values[$id]($this);    }    /**     * Checks if a parameter or an object is set.     *     * @param string $id The unique identifier for the parameter or object     *     * @return Boolean     */    public function offsetExists($id)    {        return isset($this->keys[$id]);    }    /**     * Unsets a parameter or an object.     *     * @param string $id The unique identifier for the parameter or object     */    public function offsetUnset($id)    {        if (isset($this->keys[$id])) {            if (is_object($this->values[$id])) {                unset($this->factories[$this->values[$id]], $this->protected[$this->values[$id]]);            }            unset($this->values[$id], $this->frozen[$id], $this->raw[$id], $this->keys[$id]);        }    }    /**     * Marks a callable as being a factory service.     *     * @param callable $callable A service definition to be used as a factory     *     * @return callable The passed callable     *     * @throws InvalidArgumentException Service definition has to be a closure of an invokable object     */    public function factory($callable)    {        if (!is_object($callable) || !method_exists($callable, '__invoke')) {            throw new \InvalidArgumentException('Service definition is not a Closure or invokable object.');        }        $this->factories->attach($callable);        return $callable;    }    /**     * Protects a callable from being interpreted as a service.     *     * This is useful when you want to store a callable as a parameter.     *     * @param callable $callable A callable to protect from being evaluated     *     * @return callable The passed callable     *     * @throws InvalidArgumentException Service definition has to be a closure of an invokable object     */    public function protect($callable)    {        if (!is_object($callable) || !method_exists($callable, '__invoke')) {            throw new \InvalidArgumentException('Callable is not a Closure or invokable object.');        }        $this->protected->attach($callable);        return $callable;    }    /**     * Gets a parameter or the closure defining an object.     *     * @param string $id The unique identifier for the parameter or object     *     * @return mixed The value of the parameter or the closure defining an object     *     * @throws InvalidArgumentException if the identifier is not defined     */    public function raw($id)    {        if (!isset($this->keys[$id])) {            throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));        }        if (isset($this->raw[$id])) {            return $this->raw[$id];        }        return $this->values[$id];    }    /**     * Extends an object definition.     *     * Useful when you want to extend an existing object definition,     * without necessarily loading that object.     *     * @param string   $id       The unique identifier for the object     * @param callable $callable A service definition to extend the original     *     * @return callable The wrapped callable     *     * @throws InvalidArgumentException if the identifier is not defined or not a service definition     */    public function extend($id, $callable)    {        if (!isset($this->keys[$id])) {            throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));        }        if (!is_object($this->values[$id]) || !method_exists($this->values[$id], '__invoke')) {            throw new \InvalidArgumentException(sprintf('Identifier "%s" does not contain an object definition.', $id));        }        if (!is_object($callable) || !method_exists($callable, '__invoke')) {            throw new \InvalidArgumentException('Extension service definition is not a Closure or invokable object.');        }        $factory = $this->values[$id];        $extended = function ($c) use ($callable, $factory) {            return $callable($factory($c), $c);        };        if (isset($this->factories[$factory])) {            $this->factories->detach($factory);            $this->factories->attach($extended);        }        return $this[$id] = $extended;    }    /**     * Returns all defined value names.     *     * @return array An array of value names     */    public function keys()    {        return array_keys($this->values);    }}
登录后复制

pimple类就继承一个php数组对象接口,在程序整个生命周期中,各种属性、方法、对象、闭包都可以注册其中,得易于php的数组的hashtable实现,容器本身的查询效率不算是太低。类似zf1中的Zend_Register或者Yii的委托代理形式,总体来说还是pimple直观些。

pimple只是实现了一个容器的概念,关于依赖注入自动创建关联对象的功能可以参照Laravel4和z2中的实现。一个例子代码:

require __DIR__ . '/vendor/autoload.php';  // define some services$container['session_storage'] = function ($c) {    return new $c['session_storage_class']($c['cookie_name']);};$container['session'] = function ($c) {    return new Session($c['session_storage']);};// get the session object$session = $container['session'];$container['session'] = $container->factory(function ($c) {    return new Session($c['session_storage']);});
登录后复制


本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

2 个月不见,人形机器人 Walker S 会叠衣服了 2 个月不见,人形机器人 Walker S 会叠衣服了 Apr 03, 2024 am 08:01 AM

机器之能报道编辑:吴昕国内版的人形机器人+大模型组队,首次完成叠衣服这类复杂柔性材料的操作任务。随着融合了OpenAI多模态大模型的Figure01揭开神秘面纱,国内同行的相关进展一直备受关注。就在昨天,国内"人形机器人第一股"优必选发布了人形机器人WalkerS深入融合百度文心大模型后的首个Demo,展示了一些有趣的新功能。现在,得到百度文心大模型能力加持的WalkerS是这个样子的。和Figure01一样,WalkerS没有走动,而是站在桌子后面完成一系列任务。它可以听从人类的命令,折叠衣物

java Object转byte与byte转Object的方法是什么 java Object转byte与byte转Object的方法是什么 Apr 20, 2023 am 11:37 AM

Object转byte与byte转Object今天实现一下如何从Object去转为byte和如何从byte转为Object。首先,定义一个类student:packagecom.byteToObject;importjava.io.Serializable;publicclassstudentimplementsSerializable{privateintsid;privateStringname;publicintgetSid(){returnsid;}publicvoidsetSid(in

Java Object类中的方法怎么用 Java Object类中的方法怎么用 Apr 18, 2023 pm 06:13 PM

1.Object类介绍Object是Java默认提供的一个类。Java里面除了Object类,所有的类都是存在继承关系的。默认会继承Object父类。即所有类的对象都可以使用Object的引用进行接收。范例:使用Object接收所有类的对象classPerson{}classStudent{}publicclassTest{publicstaticvoidmain(String[]args){function(newPerson());function(newStudent());}public

Java中Synchronized的原理和使用场景以及Callable接口的使用方法及区别分析 Java中Synchronized的原理和使用场景以及Callable接口的使用方法及区别分析 Apr 21, 2023 am 08:04 AM

一、基本特点1.开始时是乐观锁,如果锁冲突频繁,就转换为悲观锁.2.开始是轻量级锁实现,如果锁被持有的时间较长,就转换成重量级锁.3.实现轻量级锁的时候大概率用到的自旋锁策略4.是一种不公平锁5.是一种可重入锁6.不是读写锁二、加锁工作过程JVM将synchronized锁分为无锁、偏向锁、轻量级锁、重量级锁状态。会根据情况,进行依次升级。偏向锁假设男主是一个锁,女主是一个线程.如果只有这一个线程来使用这个锁,那么男主女主即使不领证结婚(避免了高成本操作),也可以一直幸福的生活下去.但是女配出现

Java使用Object类的getClass()函数获取对象的运行时类 Java使用Object类的getClass()函数获取对象的运行时类 Jul 24, 2023 am 11:37 AM

Java使用Object类的getClass()函数获取对象的运行时类在Java中,每个对象都有一个类,这个类定义了对象的属性和方法。我们可以使用getClass()函数来获取对象的运行时类。getClass()函数是Object类的成员函数,因此所有的Java对象都可以调用该函数。本文将介绍getClass()函数的使用方法以及给出一些代码示例。使用get

一篇搞懂this指向,赶超70%的前端人 一篇搞懂this指向,赶超70%的前端人 Sep 06, 2022 pm 05:03 PM

同事因为this指向的问题卡住的bug,vue2的this指向问题,使用了箭头函数,导致拿不到对应的props。当我给他介绍的时候他竟然不知道,随后也刻意的看了一下前端交流群,至今最起码还有70%以上的前端程序员搞不明白,今天给大家分享一下this指向,如果啥都没学会,请给我一个大嘴巴子。

聊聊Vue2为什么能通过this访问各种选项中属性 聊聊Vue2为什么能通过this访问各种选项中属性 Dec 08, 2022 pm 08:22 PM

本篇文章带大家解读vue源码,来介绍一下Vue2中为什么可以使用 this 访问各种选项中的属性,希望对大家有所帮助!

java中基本数据类型与Object的关系是什么 java中基本数据类型与Object的关系是什么 May 01, 2023 pm 04:04 PM

基本数据类型与Object的关系我知道大家是不是都听说过Object是所有类型的基类,但是这句话其实并不是正确的,因为java中基本数据类型跟Object是没有任何关系的.这里举一个例子这里在进行调用swap方法时,是不能直接将int类型传给swap(Objectobj)方法的,因为Object其实跟基本数据类型没有一点关系,这个时候a就发现我们类型不匹配,所以就自动包装成了Integer类型了,这个时候就能跟Object产生联系了,才能成功调用swap方法了.Object、基本数据类型的包装类

See all articles