好得很程序员自学网
  • 首页
  • 后端语言
    • C#
    • PHP
    • Python
    • java
    • Golang
    • ASP.NET
  • 前端开发
    • Angular
    • react框架
    • LayUi开发
    • javascript
    • HTML与HTML5
    • CSS与CSS3
    • jQuery
    • Bootstrap
    • NodeJS
    • Vue与小程序技术
    • Photoshop
  • 数据库技术
    • MSSQL
    • MYSQL
    • Redis
    • MongoDB
    • Oracle
    • PostgreSQL
    • Sqlite
    • 数据库基础
    • 数据库排错
  • CMS系统
    • HDHCMS
    • WordPress
    • Dedecms
    • PhpCms
    • 帝国CMS
    • ThinkPHP
    • Discuz
    • ZBlog
    • ECSHOP
  • 高手进阶
    • Android技术
    • 正则表达式
    • 数据结构与算法
  • 系统运维
    • Windows
    • apache
    • 服务器排错
    • 网站安全
    • nginx
    • linux系统
    • MacOS
  • 学习教程
    • 前端脚本教程
    • HTML与CSS 教程
    • 脚本语言教程
    • 数据库教程
    • 应用系统教程
  • 新技术
  • 编程导航
    • 区块链
    • IT资讯
    • 设计灵感
    • 建站资源
    • 开发团队
    • 程序社区
    • 图标图库
    • 图形动效
    • IDE环境
    • 在线工具
    • 调试测试
    • Node开发
    • 游戏框架
    • CSS库
    • Jquery插件
    • Js插件
    • Web框架
    • 移动端框架
    • 模块管理
    • 开发社区
    • 在线课堂
    • 框架类库
    • 项目托管
    • 云服务

当前位置:首页>后端语言>PHP
<tfoot draggable='sEl'></tfoot>

php实例方法依赖注入 php依赖注入的三种方式

很多站长朋友们都不太清楚php实例方法依赖注入,今天小编就来给大家整理php实例方法依赖注入,希望对各位有所帮助,具体内容如下:

本文目录一览: 1、 实现地址自动识别实例(PHP) 2、 DI(依赖注入)的四种方式 3、 thinkphp中容器是什么?依赖注入是什么? 4、 依赖注入的优点 5、 php依赖注入是在构造函数中注入吗 6、 php怎么实例化有依赖注入的类 实现地址自动识别实例(PHP)

文章正文

址自动识别现在普遍,特别是用在快递填写地址,姓名,手机号码的时候,会把这些按照一定的规范填写后,点击自动识别后,会自动填写到各自的input。最近也简单的实现了这个功能,给后台添加用户的时候,自动识别地址。以下是效果图

具体问题具体分析!代码实现基于laravel完成。一个laravel完整的功能得具备这些:路由route,Model, View, Controller, 我这里用的有依赖注入服务容器等功能,当然,用到地址,你首先要有地址库。。。

下面来看看是如何实现的,这里我只贴出核心代码

UsersController控制器

在这里新建构造函数,实现容器的依赖注入 UsersRepository

接下来就新建地址识别的方法, $discernDel 接收的数据是从前端传过来的,后面再贴前端代码。 业务代码处理交给容器 UsersRepository 里的方法 getDiscern 处理

来看看 userRepository容器处理地址识别的各种业务代码

上面的方法处理手机,名称,和地址处理,地址处理有些繁杂,因为有时候填写的地址有不一样的,比如广西省,有些就填写广西壮族自治区,所以 getAddressArrar 方法处理地址匹配信息,根据自己的业务做调整,如下

前端html部分代码

基本上能看得懂的。jquery用到 getDiscern(); 方法,手机号码,姓名,地址等input这里就不一一列出了。大家根据下面的jquery都能想象到

jquery代码部分

ajax post后交给url: getDiscern 处理,这个就是上面controller的方法,success返回的数据后再追加到每个input里,最后再清除掉自动识别地址框的数据

整个过程简单,又清晰明了,以上就是我的代码,分享给大家,觉得哪个地方不对劲的,欢迎留言吐槽!

DI(依赖注入)的四种方式

1.1. 通过 setter 方法注入Bean 的属性值或依赖的对象

1.2. 使用<property>元素, 使用 name 属性指定 Bean 的属性名称,value 属性或 <value> 子节 点指定属性值

2.1 通过构造方法注入Bean 的属性值或依赖的对象,它保证了 Bean 实例在实例化后就可以使用

2.2 构造器注入在 <constructor-arg> 元素里声明属性, <constructor-arg> 中没有 name 属性

Tip:

thinkphp中容器是什么?依赖注入是什么?

依赖注入:即允许通过类的方法传递对象的能力,并且限制了对象的类型(约束);

而传递的对象背后的那个类被自动绑定并且实例化了,这就是依赖注入;

支持使用依赖注入的场景包括(但不限于):

控制器架构方法; 控制器操作方法; 路由的闭包定义; 事件类的执行方法; 中间件的执行方法;

依赖注入的类统一由容器管理的,大多数情况下是自动绑定和自动实例化的;

依赖注入的优点

把对象生成放在了XML里定义,所以换一个实现子类将会变成很简单(一般这样的对象都是实现于某种接口的),只要修改XML就可以。这样甚至可以实现对象的热插拨。

依赖注入:

依赖注入就是Spring设计思想中重要的一部分,它是指Ioc或DI,是一个重要的面向对象编程的法则来削减计算机程序的耦合问题.控制反转还有一个名字叫做依赖注入(DependencyInjection).简称DI.

IoC亦称为“依赖倒置原理”("DependencyInversionPrinciple")。差不多所有框架都使用了“倒置注入(Fowler2004)技巧,这可说是IoC原理的一项应用。SmallTalk,C++,Java或各种.NET语言等面向对象程序语言的程序员已使用了这些原理。

应用控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用,传递给它。也可以说,依赖被注入到对象中。所以,控制反转是,关于一个对象如何获取他所依赖的对象的引用,这个责任的反转。

依赖注入(DependencyInjection)和控制反转(InversionofControl)是同一个概念。具体含义是:当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在Spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。

不管是依赖注入,还是控制反转,都说明Spring采用动态、灵活的方式来管理各种对象。对象与对象之间的具体实现互相透明。在理解依赖注入之前,看如下这个问题在各种社会形态里如何解决:一个人(Java实例,调用者)需要一把斧子(Java实例,被调用者)。

(1)原始社会里,几乎没有社会分工。需要斧子的人(调用者)只能自己去磨一把斧子(被调用者)。对应的情形为:Java程序里的调用者自己创建被调用者。

(2)进入工业社会,工厂出现。斧子不再由普通人完成,而在工厂里被生产出来,此时需要斧子的人(调用者)找到工厂,购买斧子,无须关心斧子的制造过程。对应Java程序的简单工厂的设计模式。

(3)进入“按需分配”社会,需要斧子的人不需要找到工厂,坐在家里发出一个简单指令:需要斧子。斧子就自然出现在他面前。对应Spring的依赖注入。

第一种情况下,Java实例的调用者创建被调用的Java实例,必然要求被调用的Java类出现在调用者的代码里。无法实现二者之间的松耦合。

第二种情况下,调用者无须关心被调用者具体实现过程,只需要找到符合某种标准(接口)的实例,即可使用。此时调用的代码面向接口编程,可以让调用者和被调用者解耦,这也是工厂模式大量使用的原因。但调用者需要自己定位工厂,调用者与特定工厂耦合在一起。

第三种情况下,调用者无须自己定位工厂,程序运行到需要被调用者时,系统自动提供被调用者实例。事实上,调用者和被调用者都处于Spring的管理下,二者之间的依赖关系由Spring提供。

所谓依赖注入,是指程序运行过程中,如果需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部的注入。Spring的依赖注入对调用者和被调用者几乎没有任何要求,完全支持对POJO之间依赖关系的管理。

依赖注入通常有两种:

1、设值注入。

2、构造注入。

php依赖注入是在构造函数中注入吗

PHP 依赖注入

tags: dependency injection,php

by Ryan on January 8, 2009

Dependency injection is the answer to more maintainable, testable, modular code.

依赖注入是对于要求更易维护,更易测试,更加模块化的代码的答案。

Every project has dependencies and the more complex the project is the more dependencies it will most likely have. The most common dependency in today’s web application is the database and chances are if it goes down the app will all together stop working. That is because the code is dependent on the database server… and that is perfectly fine. Not using a database server because it could one day crash is a bit ridiculous. Even though the dependency has its flaws, it still makes life for the code, and thus the developer, a lot easier.

每个项目都有依赖(外界提供的输入), 项目越复杂,越需要更多的依赖。在现今的网络应用程序中,最常见的依赖是数据库,其风险在于,一旦数据库暂停运行,那么整个程序也因此而停止运行。这是因为代码依赖数据库服务器。。。这已足够。因为数据库服务器有时会崩溃而弃用它是荒谬的。尽管依赖有其自身的瑕疵,它仍然使代码,因而也使程序开发人员的生活更容易些。

The problem with most dependencies its the way that code handles and interacts with them, meaning, the problem is the code and not the dependency. If you are not using dependency injection, chances are your code looks something like this:

对于大多依赖而言,问题在于代码如何处理它们及与它们交往。也就是说,问题是代码本身而非依赖。如果你没有使用依赖注入,有机会遇到下列代码:

class Book {

publicfunction __construct(){

$registry = RegistrySingleton::getInstance();

$this->_databaseConnection=$registry->databaseConnection;

// or

global$databaseConnection;

$this->_databaseConnection=$databaseConnection;

}

}

The book object now is given full access to the database once it is constructed. That is good, the book needs to be able to talk to the database and pull data. The problem lies in the way the book gained its access. In order for the book to be able to talk to the database the code must have an outside variable named $databaseConnection, or worse, it must have a singleton pattern class (registry) object containing a record for a databaseConnection. If these don’t exist the book fails, making this code is far from modular.

现在对象book一旦建立,就已经完全连到数据库。这没什么不好,book需要跟数据库交谈并取得数据。问题在于book取得其接入的方法。要使book能够与数据库交谈,代码必须有一个外来的变量$databaseConnect, 更糟糕的是,它必须有个singleton类型类(registry)的对象,其包含一个databaseConnection的记录。如果这些不存在的话,book会无法运行,这就使得这些代码远远不够模块化。

This raises the question, how exactly does the book get access to the database? This is where inversion of control comes in.

这就提出一个问题,到底book如何接入数据库?这就是IoC出现的原因了。

In Hollywood a struggling actor does not call up Martin Scorsese and ask for a role in his next film. No, the opposite happens. Martin Scorsese calls up the broke actor and asks him to play the main character in his next movie. Objects are struggling actors, they do not get to pick the roles they play, the director needs to tell them what to do. Objects do not get to pick the outside systems they interact with, instead, the outside systems are given to the objects. Remember this as Inversion of Control: The Hollywood Way.

在好莱坞,一个濒临绝境的演员不会打电话给Martin Scoresese要求在他的下个影片中扮演一个角色。绝不会这样,实际正相反。Martin Scorese 会打电话给这个困顿的演员并邀请他在下一部影片中扮演重要的角色。对象是挣扎中的演员,他们不会去捡自己所扮演的角色,导演需要告诉他们去做什么。对象不会到它所接触的外界挑选系统,相反,外界系统会被赋予对象。记住这就是IoC( Inversion of Control):好莱坞的做法。

This is how a developer tells his objects how to interact with outside dependencies:

如下是开发人员告诉他的对象如何与外界的依赖打交道:

class Book {

publicfunction __construct(){}

publicfunction setDatabaseConnection($databaseConnection){

$this->_databaseConnection=$databaseConnection;

}

}

$book=new Book();

$book->setDatabase($databaseConnection);

This code allows for the book class to be used in any web app. The Book is no longer dependent on anything other than the developer supplying a database shortly after object creation.这代码允许这个book类能在任何的网页程序中使用。此book不再依赖任何事项,除了程序开发者要在对象创建后立即要提供一个数据库。

This is, at its finest, dependency injection. There are two common practices of injecting dependencies. The first being constructor injection and the second being setter injection. Constructor injection involves passing all of the dependencies as arguments when creating a new object. The code would look something like this:

这就是最佳方法—依赖注入。有两种常用的依赖注入的方式。一种是 constructor (注:构造函数。这种译法似乎并不恰当,类中此方法更多是用来对某些属性进行初始化)注入,一种是setter 注入。Constructor注入涉及到将所有依赖作为参数,传递给新创建的对象。看起来像这样:

$book=new Book($databaseConnection,$configFile);

The more dependencies an object has, the messier this construction becomes. There are other reasons why this is a bad approach, involving ideas around code reusability and constructors doing work.

对象的依赖越多,construction就会变得越杂乱。这里还有其他的原因为什么这是一个坏方法,其涉及到包括代码重用和constructors要做的工作。

This leaves us with other method of dependency injection, called setting injection, which involves creating a public method inside the object for the dependencies that need injection.

这就给我们留下其他的方法进行依赖注入,称为设置注入,包含在需要注入依赖的对象里创建一个公共方法:

$book=new Book();

$book->setDatabase($databaseConnection);

$book->setConfigFile($configFile);

This is easy to follow, but it leads writing more and more code for your application. When a book object is created three lines of code are required. If we have to inject another dependency, a 4th line of code is now needed. This gets messy quickly.

这很容易实现,但是它会导致为您的程序写大量代码。当创建一个book对象时,需要三行代码。如果我们必须注入另外的依赖时,必须增加第四行代码。这很快变得一团糟。

The answer to this problem is a factory, which is class that is designed to create and then inject all the dependencies needed for an object. Here is an example:

此问题的对策是一个工厂factory,它是一个类,用来创建然后注入一个对象的所有依赖。举例如下:

class Factory {

public static $_database;

public static function makeBook(){

$book=new Book();

$book->setDatabase(self::$_database);

// more injection...(更多注入)

return$book;

}

}

And then:

然后:

$book= Factory::makeBook();

All dependencies should be registered into the factory object during run time. This object is now the gateway that all dependencies must pass through before they can interact with any classes. In other words, this is the dependency container.

所有的依赖在运行期间都应在此factory对象中注册。它现在是大门,在依赖可以与任何对象打交道前,都必经此门。

The reason makeBook is a public static function is for ease of use and global access. When I started this article off I made a reference to the singleton pattern and global access being a poor choices of code. They are… for the most part. It is bad design when they control access, but it is perfectly ok when they control creation. The makeBook function is only a shortcut for creation. There is no dependency what-so-ever between the book class and the factory class. The factory class exists so we can contain our dependencies in one location and automatically inject those dependencies with one line of code creation.

makeBook作为一个静态方法的原因是易用并且可以在全局得到。在本文开头,我提出使用singleton类型和全局变量对代码而言是一个糟糕的选择。多数情形下,确实如此!当他们控制接入时,是一个差设计。但是在他们控制创建时,是一个不错的选择。makeBook方法仅仅是创建的一个捷径。在book类和factory类之间,没有任何依赖。由于factory类的存在,我们的依赖可以存放在一个地点,并且用一行创建代码就可自动注入这些依赖。

The factory or container class removes all of the extra work of dependency injection.

此处的factory或者容器类移走了依赖注入的所有额外工作。

Before injection:

以前的注入:

$book=new Book();

And now:

目前的方法:

$book= Factory::makeBook();

Hardly any extra work, but tons of extra benefits.

几乎没有任何的额外工作,但是有大量益处。

When test code is run, specifically unit tests, the goal is to see if a method of a class is working correctly. Since the book class requires database access to read the book data it adds a whole layer of complexity. The test has to acquire a database connection, pull data, and test it. All of a sudden the test is no longer testing a single method in the book class, it is now also testing database. If the database is offline, the test would fail. This is FAR from the goal a unit test.当运行测试代码时,尤其是单元测试,其目标是检查类中的方法是否正确地工作。由于book类要求接入数据库并且读取图书数据,它增加了一层复杂度。此测试不得不进行数据库连接,取得数据,然后测试它。瞬间,测试不再是测试book类中的单个方法,它目前同时也测试数据库。如果数据库离线,测试就会失败。这已经远离了单元测试的目的。

A way of dealing with this is just using a different database dependency for the unit tests. When the test suite starts up a dummy database is injected into the book. The dummy database will always have the data the developer expects it to have. If a live database was used in a unit test the data could potentially change causing tests to unnecessarily fail. There is no need for a unit test to be refactored when a record in a database changes.

解决上述问题的方法是用不同的数据库依赖来作单元测试。当测试套件开始时,虚拟的数据库被注入book.虚拟数据库将永远拥有开发人员所期待的数据。如果使用一个真实数据库,数据的潜在变化会导致测试不必要的失败。当数据库的记录改变了,不需因此重新进行单元测试。

The code is more modular because it can dropped into any other web application. Create the book object and inject a database connection with $book->setDatabase(). It does not matter if the database is in Registery::Database, $database, or $someRandomDatabaseVarible. As long as there is a database connection the book will work inside any system.

此代码现在更加模块化,因为它可以被放到任何其他的网页程序。创建book对象并且用$book->setDatabase()注入数据库连接。此时,数据库在 Registery::Database, $database,或者$someRandomDatabaseVarible都无关大局。只要有一个数据库连接,book就可以在任何系统内工作。

The code is more maintainable because each object given exactly what it needs. If separate database connections are required between different instances of the same class then there no extra code needed inside the class what-so-ever. Give book1 access to database1 and book2 access to database2.

代码更加易维护,因为每个对象都被赋予了它的所需。如果同一类的实例需要不同的数据库连接,在类内部一点儿也不需要额外的代码。例如book1连接到数据库1,book2连接到数据库2

Factory::$_database=$ourDatabaseVarForDB1;

$book1= Factory::makeBook();

$book2= Factory::makeBook();

$book2->setDatabase($database2);

Dependency injection really is the answer to more maintainable, testable, modular code.

依赖注入真的是更易维护,更易测试和更加模块化的答案。

php怎么实例化有依赖注入的类

PHP依赖注入的理解。分享给大家供大家参考,具体如下:

看Laravel的IoC容器文档只是介绍实例,但是没有说原理,之前用MVC框架都没有在意这个概念,无意中在phalcon的文档中看到这个详细的介绍,感觉豁然开朗,复制粘贴过来,主要是好久没有写东西了,现在确实很懒变得!

首先,我们假设,我们要开发一个组件命名为SomeComponent。这个组件中现在将要注入一个数据库连接。

在这个例子中,数据库连接在component中被创建,这种方法是不切实际的,这样做的话,我们将不能改变数据库连接参数及数据库类型等一些参数。

class SomeComponent {

/**

* The instantiation of the connection is hardcoded inside

* the component so is difficult to replace it externally

* or change its behavior

*/

public function someDbTask()

{

$connection = new Connection(array(

"host" => "localhost",

"username" => "root",

"password" => "secret",

"dbname" => "invo"

));

// ...

}

}

$some = new SomeComponent();

$some->someDbTask();

为了解决上面所说的问题,我们需要在使用前创建一个外部连接,并注入到容器中。就目前而言,这看起来是一个很好的解决方案:

class SomeComponent {

protected $_connection;

/**

* Sets the connection externally

*/

public function setConnection($connection)

{

$this->_connection = $connection;

}

public function someDbTask()

{

$connection = $this->_connection;

// ...

}

}

$some = new SomeComponent();

//Create the connection

$connection = new Connection(array(

"host" => "localhost",

"username" => "root",

"password" => "secret",

"dbname" => "invo"

));

//Inject the connection in the component

$some->setConnection($connection);

$some->someDbTask();

现在我们来考虑一个问题,我们在应用程序中的不同地方使用此组件,将多次创建数据库连接。使用一种类似全局注册表的方式,从这获得一个数据库连接实例,而不是使用一次就创建一次。

class Registry

{

/**

* Returns the connection

*/

public static function getConnection()

{

return new Connection(array(

"host" => "localhost",

"username" => "root",

"password" => "secret",

"dbname" => "invo"

));

}

}

class SomeComponent

{

protected $_connection;

/**

* Sets the connection externally

*/

public function setConnection($connection){

$this->_connection = $connection;

}

public function someDbTask()

{

$connection = $this->_connection;

// ...

}

}

$some = new SomeComponent();

//Pass the connection defined in the registry

$some->setConnection(Registry::getConnection());

$some->someDbTask();

现在,让我们来想像一下,我们必须在组件中实现两个方法,首先需要创建一个新的数据库连接,第二个总是获得一个共享连接:

class Registry

{

protected static $_connection;

/**

* Creates a connection

*/

protected static function _createConnection()

{

return new Connection(array(

"host" => "localhost",

"username" => "root",

"password" => "secret",

"dbname" => "invo"

));

}

/**

* Creates a connection only once and returns it

*/

public static function getSharedConnection()

{

if (self::$_connection===null){

$connection = self::_createConnection();

self::$_connection = $connection;

}

return self::$_connection;

}

/**

* Always returns a new connection

*/

public static function getNewConnection()

{

return self::_createConnection();

}

}

class SomeComponent

{

protected $_connection;

/**

* Sets the connection externally

*/

public function setConnection($connection){

$this->_connection = $connection;

}

/**

* This method always needs the shared connection

*/

public function someDbTask()

{

$connection = $this->_connection;

// ...

}

/**

* This method always needs a new connection

*/

public function someOtherDbTask($connection)

{

}

}

$some = new SomeComponent();

//This injects the shared connection

$some->setConnection(Registry::getSharedConnection());

$some->someDbTask();

//Here, we always pass a new connection as parameter

$some->someOtherDbTask(Registry::getConnection());

到此为止,我们已经看到了如何使用依赖注入解决我们的问题。不是在代码内部创建依赖关系,而是让其作为一个参数传递,这使得我们的程序更容易维护,降低程序代码的耦合度,实现一种松耦合。但是从长远来看,这种形式的依赖注入也有一些缺点。

例如,如果组件中有较多的依赖关系,我们需要创建多个setter方法传递,或创建构造函数进行传递。另外,每次使用组件时,都需要创建依赖组件,使代码维护不太易,我们编写的代码可能像这样:

//Create the dependencies or retrieve them from the registry

$connection = new Connection();

$session = new Session();

$fileSystem = new FileSystem();

$filter = new Filter();

$selector = new Selector();

//Pass them as constructor parameters

$some = new SomeComponent($connection, $session, $fileSystem, $filter, $selector);

// ... or using setters

$some->setConnection($connection);

$some->setSession($session);

$some->setFileSystem($fileSystem);

$some->setFilter($filter);

$some->setSelector($selector);

我想,我们不得不在应用程序的许多地方创建这个对象。如果你不需要依赖的组件后,我们又要去代码注入部分移除构造函数中的参数或者是setter方法。为了解决这个问题,我们再次返回去使用一个全局注册表来创建组件。但是,在创建对象之前,它增加了一个新的抽象层:

class SomeComponent

{

// ...

/**

* Define a factory method to create SomeComponent instances injecting its dependencies

*/

public static function factory()

{

$connection = new Connection();

$session = new Session();

$fileSystem = new FileSystem();

$filter = new Filter();

$selector = new Selector();

return new self($connection, $session, $fileSystem, $filter, $selector);

}

}

这一刻,我们好像回到了问题的开始,我们正在创建组件内部的依赖,我们每次都在修改以及找寻一种解决问题的办法,但这都不是很好的做法。

一种实用和优雅的来解决这些问题,是使用容器的依赖注入,像我们在前面看到的,容器作为全局注册表,使用容器的依赖注入做为一种桥梁来解决依赖可以使我们的代码耦合度更低,很好的降低了组件的复杂性:

class SomeComponent

{

protected $_di;

public function __construct($di)

{

$this->_di = $di;

}

public function someDbTask()

{

// Get the connection service

// Always returns a new connection

$connection = $this->_di->get('db');

}

public function someOtherDbTask()

{

// Get a shared connection service,

// this will return the same connection everytime

$connection = $this->_di->getShared('db');

//This method also requires a input filtering service

$filter = $this->_db->get('filter');

}

}

$di = new Phalcon\DI();

//Register a "db" service in the container

$di->set('db', function(){

return new Connection(array(

"host" => "localhost",

"username" => "root",

"password" => "secret",

"dbname" => "invo"

));

});

//Register a "filter" service in the container

$di->set('filter', function(){

return new Filter();

});

//Register a "session" service in the container

$di->set('session', function(){

return new Session();

});

//Pass the service container as unique parameter

$some = new SomeComponent($di);

$some->someTask();

现在,该组件只有访问某种service的时候才需要它,如果它不需要,它甚至不初始化,以节约资源。该组件是高度解耦。他们的行为,或者说他们的任何其他方面都不会影响到组件本身。我们的实现办法

Phalcon\DI 是一个实现了服务的依赖注入功能的组件,它本身也是一个容器。

由于Phalcon高度解耦,Phalcon\DI 是框架用来集成其他组件的必不可少的部分,开发人员也可以使用这个组件依赖注入和管理应用程序中不同类文件的实例。

基本上,这个组件实现了 Inversion of Control 模式。基于此,对象不再以构造函数接收参数或者使用setter的方式来实现注入,而是直接请求服务的依赖注入。这就大大降低了整体程序的复杂性,因为只有一个方法用以获得所需要的一个组件的依赖关系。

此外,这种模式增强了代码的可测试性,从而使它不容易出错。

在容器中注册服务

框架本身或开发人员都可以注册服务。当一个组件A要求调用组件B(或它的类的一个实例),可以从容器中请求调用组件B,而不是创建组件B的一个实例。

这种工作方式为我们提供了许多优点:

我们可以更换一个组件,从他们本身或者第三方轻松创建。

在组件发布之前,我们可以充分的控制对象的初始化,并对对象进行各种设置。

我们可以使用统一的方式从组件得到一个结构化的全局实例

服务可以通过以下几种方式注入到容器:

//Create the Dependency Injector Container

$di = new Phalcon\DI();

//By its class name

$di->set("request", 'Phalcon\Http\Request');

//Using an anonymous function, the instance will lazy loaded

$di->set("request", function(){

return new Phalcon\Http\Request();

});

//Registering directly an instance

$di->set("request", new Phalcon\Http\Request());

//Using an array definition

$di->set("request", array(

"className" => 'Phalcon\Http\Request'

));

在上面的例子中,当向框架请求访问一个请求数据时,它将首先确定容器中是否存在这个”reqeust”名称的服务。

容器会反回一个请求数据的实例,开发人员最终得到他们想要的组件。

在上面示例中的每一种方法都有优缺点,具体使用哪一种,由开发过程中的特定场景来决定的。

用一个字符串来设定一个服务非常简单,但缺少灵活性。设置服务时,使用数组则提供了更多的灵活性,而且可以使用较复杂的代码。lambda函数是两者之间一个很好的平衡,但也可能导致更多的维护管理成本。

Phalcon\DI 提供服务的延迟加载。除非开发人员在注入服务的时候直接实例化一个对象,然后存存储到容器中。在容器中,通过数组,字符串等方式存储的服务都将被延迟加载,即只有在请求对象的时候才被初始化。

//Register a service "db" with a class name and its parameters

$di->set("db", array(

"className" => "Phalcon\Db\Adapter\Pdo\Mysql",

"parameters" => array(

"parameter" => array(

"host" => "localhost",

"username" => "root",

"password" => "secret",

"dbname" => "blog"

)

)

));

//Using an anonymous function

$di->set("db", function(){

return new Phalcon\Db\Adapter\Pdo\Mysql(array(

"host" => "localhost",

"username" => "root",

"password" => "secret",

"dbname" => "blog"

));

});

以上这两种服务的注册方式产生相同的结果。然后,通过数组定义的,在后面需要的时候,你可以修改服务参数:

$di->setParameter("db", 0, array(

"host" => "localhost",

"username" => "root",

"password" => "secret"

));

从容器中获得服务的最简单方式就是使用”get”方法,它将从容器中返回一个新的实例:

$request = $di->get("request");

或者通过下面这种魔术方法的形式调用:

$request = $di->getRequest();

Phalcon\DI 同时允许服务重用,为了得到一个已经实例化过的服务,可以使用 getShared() 方法的形式来获得服务。

具体的 Phalcon\Http\Request 请求示例:

$request = $di->getShared("request");

参数还可以在请求的时候通过将一个数组参数传递给构造函数的方式:

$component = $di->get("MyComponent", array("some-parameter", "other"));

关于php实例方法依赖注入的介绍到此就结束了,不知道本篇文章是否对您有帮助呢?如果你还想了解更多此类信息,记得收藏关注本站,我们会不定期更新哦。

查看更多关于php实例方法依赖注入 php依赖注入的三种方式的详细内容...

声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did253979
更新时间:2023-09-13   阅读:42次

上一篇: ideaphp环境搭建 idea配置php环境

下一篇:php爱心表白代码 html爱心表白代码

相关资讯

最新资料更新

  • 1.php求数组的交集 php数组处理函数
  • 2.php项目任务分配 php任务调度框架
  • 3.php登录和注册 php登录和注册不使用数据库
  • 4.免费php空间shery 免费PHP空间 免备案 V52版本
  • 5.php每个小时执行 php定时执行每天执行一次
  • 6.php网站界面代码 php网页
  • 7.php客户信息管理 php用户管理
  • 8.php视频直播源码 php直播源码免费
  • 9.php获取url# php获取url id
  • 10.关于php用户同时登录的信息
  • 11.PHP外部引用样式 php引用外部文件
  • 12.php图片上传及显示 php 图片上传
  • 13.字符串对齐方法php php字符串赋值
  • 14.PHP画饼图动态 python 动态饼图
  • 15.iconv函数php iconv函数参数
  • 16.免费版仓库管理系统php 仓库管理系统php源码
  • 17.输出图片php 输出图片英文
  • 18.php短信android Php短信对接视频
  • 19.php配置外网访问 phpstudy外网映射
  • 20.php浏览页面乱码 php页面字符出现乱码怎么解决

CopyRight:2016-2025好得很程序员自学网 备案ICP:湘ICP备09009000号-16 http://haodehen.cn
本站资讯不构成任何建议,仅限于个人分享,参考须谨慎!
本网站对有关资料所引致的错误、不确或遗漏,概不负任何法律责任。
本网站刊载的所有内容(包括但不仅限文字、图片、LOGO、音频、视频、软件、程序等)版权归原作者所有。任何单位或个人认为本网站中的内容可能涉嫌侵犯其知识产权或存在不实内容时,请及时通知本站,予以删除。

网站内容来源于网络分享,如有侵权发邮箱到:kenbest@126.com,收到邮件我们会即时下线处理。
网站框架支持:HDHCMS   51LA统计 百度统计
Copyright © 2018-2025 「好得很程序员自学网」
[ SiteMap ]