awesome PHP之依赖注入器皿pimple
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']);});

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Editor Laporan Kuasa Mesin: Wu Xin Versi domestik robot humanoid + pasukan model besar menyelesaikan tugas operasi bahan fleksibel yang kompleks seperti melipat pakaian buat kali pertama. Dengan pelancaran Figure01, yang mengintegrasikan model besar berbilang modal OpenAI, kemajuan berkaitan rakan domestik telah menarik perhatian. Baru semalam, UBTECH, "stok robot humanoid nombor satu" China, mengeluarkan demo pertama robot humanoid WalkerS yang disepadukan secara mendalam dengan model besar Baidu Wenxin, menunjukkan beberapa ciri baharu yang menarik. Kini, WalkerS, diberkati oleh keupayaan model besar Baidu Wenxin, kelihatan seperti ini. Seperti Rajah01, WalkerS tidak bergerak, tetapi berdiri di belakang meja untuk menyelesaikan satu siri tugasan. Ia boleh mengikut perintah manusia dan melipat pakaian

Objek kepada bait dan bait kepada Objek Hari ini kita akan menyedari cara menukar daripada Objek kepada bait dan cara menukar daripada bait kepada Objek. Mula-mula, tentukan pelajar kelas: packagecom.byteToObject;importjava.io.Serializable;publicclassstudentimplementsSerializable{privateintsid;privateStringname;publicintgetSid(){returnsid;}publicvoidsetSid(in

1. Pengenalan kepada kelas Objek Objek ialah kelas yang disediakan oleh Java secara lalai. Kecuali untuk kelas Objek, semua kelas di Jawa mempunyai hubungan warisan. Secara lalai, ia akan mewarisi kelas induk Objek. Iaitu, objek semua kelas boleh diterima menggunakan rujukan Object. Contoh: Gunakan Object untuk menerima objek semua kelas classPerson{}classStudent{}publicclassTest{publicstaticvoidmain(String[]args){function(newPerson());function(newStudent());}public

1. Ciri asas 1. Ia bermula dengan kunci optimistik, dan jika konflik kunci kerap berlaku, ia ditukar kepada kunci pesimis 2. Ia bermula dengan pelaksanaan kunci ringan, dan jika kunci itu dipegang untuk masa yang lama, ia ditukar kepada kunci heavyweight 3. Strategi kunci putaran yang paling mungkin digunakan semasa melaksanakan kunci ringan 4. Ia adalah kunci tidak adil 5. Ia adalah kunci masuk semula 6. Ia bukan kunci baca-tulis 2. JVM akan menyegerakkan proses penguncian Kunci dibahagikan kepada tiada kunci, kunci berat sebelah, kunci ringan dan keadaan kunci berat. Ia akan dinaik taraf secara berurutan mengikut situasi. Kunci berat sebelah menganggap bahawa protagonis lelaki adalah kunci dan protagonis wanita adalah benang Jika hanya benang ini menggunakan kunci ini, maka protagonis lelaki dan protagonis wanita boleh hidup bahagia selama-lamanya walaupun mereka tidak mendapat sijil nikah (mengelakkan tinggi. -operasi kos). Tetapi peranan sokongan wanita muncul

Java menggunakan fungsi getClass() kelas Objek untuk mendapatkan kelas runtime objek Dalam Java, setiap objek mempunyai kelas, yang mentakrifkan sifat dan kaedah objek. Kita boleh menggunakan fungsi getClass() untuk mendapatkan kelas runtime sesuatu objek. Fungsi getClass() ialah fungsi ahli kelas Objek, jadi semua objek Java boleh memanggil fungsi ini. Artikel ini akan memperkenalkan cara menggunakan fungsi getClass() dan memberikan beberapa contoh kod. gunakan dapatkan

Seorang rakan sekerja tersekat kerana pepijat yang ditunjukkan oleh masalah penunjuk Vue2 ini menyebabkan fungsi anak panah digunakan, mengakibatkan ketidakupayaan untuk mendapatkan prop yang sepadan. Dia tidak tahu apabila saya memperkenalkannya kepadanya, dan kemudian saya sengaja melihat kumpulan pertukaran bahagian hadapan Setakat ini, sekurang-kurangnya 70% pengaturcara bahagian hadapan masih tidak memahaminya anda pautan ini. Jika semuanya tidak jelas saya belum belajar bagaimana untuk melakukannya, sila berikan saya mulut yang besar.

PHPNotice: Tryingtogetpropertyofnon-object solution Apabila anda sedang membangunkan dalam PHP, anda mungkin menghadapi mesej ralat ini: "Notis: Tryingtogetpropertyofnon-object." dalam sekeping kod tertentu dan tidak boleh mengakses sifat dengan betul.

Apakah mata wang THE (Tokenized Healthcare Ecosystem) ialah mata wang digital yang menggunakan teknologi blockchain untuk menumpukan pada inovasi dan pembaharuan dalam industri penjagaan kesihatan. Misi syiling adalah untuk menggunakan teknologi blockchain untuk meningkatkan kecekapan dan ketelusan industri perubatan dan menggalakkan kerjasama yang lebih cekap dalam kalangan semua pihak, termasuk pesakit, kakitangan perubatan, syarikat farmaseutikal dan institusi perubatan. Nilai dan Ciri-ciri THE Coin Pertama sekali, THE Coin, sebagai mata wang digital, mempunyai kelebihan rantaian blok - desentralisasi, keselamatan tinggi, urus niaga telus, dsb., membolehkan peserta mempercayai dan bergantung pada sistem ini. Kedua, keunikan THE coin ialah ia memberi tumpuan kepada industri perubatan dan kesihatan, menggunakan teknologi blockchain untuk mengubah sistem perubatan tradisional dan menambah baik.
