0

0

使用 Symfony 组件演示 PHP 中的依赖注入

王林

王林

发布时间:2023-08-28 11:57:09

|

987人浏览过

|

来源于php中文网

原创

使用 symfony 组件演示 php 中的依赖注入

在本文中,我们将介绍一些使用 Symfony DependencyInjection 组件的示例。您将学习依赖注入的基础知识,它允许干净和模块化的代码,并且您将了解如何在带有 Symfony 组件的 PHP 应用程序中使用它。

什么是 Symfony DependencyInjection 组件?

Symfony DependencyInjection 组件提供了一种在 PHP 应用程序中实例化对象和处理依赖关系管理的标准方法。 DependencyInjection 组件的核心是一个容器,它保存应用程序中所有可用的服务。

在应用程序的引导阶段,您应该将应用程序中的所有服务注册到容器中。在稍后阶段,容器负责根据需要创建服务。更重要的是,容器还负责创建和注入服务的依赖项。

这种方法的好处是您不必对实例化对象的过程进行硬编码,因为将自动检测并注入依赖项。这会在应用程序的各个部分之间创建松散耦合。

立即学习PHP免费学习笔记(深入)”;

在本文中,我们将探讨如何释放 DependencyInjection 组件的强大功能。像往常一样,我们将从安装和配置说明开始,然后实现一些实际示例来演示关键概念。

安装和配置

在本节中,我们将继续安装 DependencyInjection 组件。我假设您已经在系统中安装了 Composer,因为我们需要它来安装 Packagist 上提供的 DependencyInjection 组件。

因此,请继续使用以下命令安装 DependencyInjection 组件。

$composer require symfony/dependency-injection

这应该创建了 composer.json 文件,它应该如下所示:

{
    "require": {
        "symfony/dependency-injection": "^5.4"
    }
}

我们还将安装一些在我们的示例中有用的其他组件。

如果您想从 YAML 文件加载服务而不是在 PHP 代码中定义它,那么 Yaml 组件就可以派上用场,因为它可以帮助您将 YAML 字符串转换为 PHP 兼容的数据类型,反之亦然。

$composer require symfony/yaml

最后,我们将安装 Config 组件,它提供了几个实用程序类来初始化和处理在不同类型的文件(如 YAML、INI 和 XML)中定义的配置值。在我们的例子中,我们将使用它从 YAML 文件加载服务。

$composer require symfony/config

让我们将 composer.json 文件修改为如下所示。

{
    "require": {
        "symfony/dependency-injection": "^5.4",
        "symfony/yaml": "^5.4",
        "symfony/config": "^5.4"
    },
    "autoload": {
         "psr-4": {
             "Services\\": "src"
         },
         "classmap": ["src"]
    }
}

由于我们添加了新的 classmap 条目,让我们继续通过运行以下命令来更新 Composer 自动加载器。

$composer dump -o

现在,您可以使用 Services 命名空间来自动加载 src 目录下的类。

这就是安装部分,但是你应该如何使用它呢?事实上,只需将 Composer 创建的 autoload.php 文件包含在您的应用程序中即可,如以下代码片段所示。


如何使用容器

在本节中,我们将通过一个示例来演示如何将服务注入到容器中。容器应该充当中央存储库,保存应用程序中的所有服务。稍后,我们可以使用容器来根据需要获取服务。

首先,让我们继续在 src/DemoService.php 中定义一个非常基本的服务,其中包含以下内容。


这是一个非常简单的服务,暂时只实现了 helloWorld 方法。

接下来,继续在应用程序的根目录中创建包含以下内容的 basic_container.php 文件。

register('demo.service', '\Services\DemoService');
 
// fetch service from the service container
$demoService = $containerBuilder->get('demo.service');
echo $demoService->helloWorld();

首先,我们使用 new ContainerBuilder() 构造函数实例化了 ContainerBuilder 对象。接下来,我们使用 ContainerBuilder 对象的 register 方法将我们的自定义服务 \Services\DemoService 注入到容器中。 demo.service 充当我们服务的别名。

最后,我们使用 ContainerBuilder 对象的 get 方法从容器中获取我们的服务,并用它来调用 helloWorld 方法。

这是如何使用容器的基本演示。在下一节中,我们将扩展此示例以探索如何使用容器解决类依赖关系。

现实世界的示例

在本节中,我们将创建一个示例,演示如何使用 DependencyInjection 组件解析类依赖关系。

为了演示它,我们将创建一个新服务 DependentService ,它需要上一节中创建的 DemoService 服务作为依赖项。因此,我们将看到当实例化 DependentService 服务时,如何将 DemoService 服务作为依赖项自动注入。

继续创建包含以下内容的 src/DependentService.php 文件来定义 DependentService 服务。

demo_service = $demoService;
  }
 
  public function helloWorld()
  {
    return $this->demo_service->helloWorld();
  }
}

如您所见,为了实例化 DependentService 服务,需要 \Services\DemoService 服务。

ArrowMancer
ArrowMancer

手机上的宇宙动作RPG,游戏角色和元素均为AI生成

下载

接下来,继续创建包含以下内容的 di_container.php 文件。

register('demo.service', '\Services\DemoService');
 
// add dependent service into the service container
$containerBuilder->register('dependent.service', '\Services\DependentService')
                 ->addArgument(new Reference('demo.service'));
 
// fetch service from the service container
$dependentService = $containerBuilder->get('dependent.service');
echo $dependentService->helloWorld();

我们使用相同的 register 方法将自定义服务 \Services\DependentService 注入到容器中。

除此之外,我们还使用了 addArgument 方法来通知容器有关 DependentService 服务的依赖关系。我们使用 Reference 类来通知容器在实例化 dependent.service 服务时需要注入 demo.service 服务。这样,就会根据需要自动注入依赖项!

最后,我们使用 ContainerBuilder 对象的 get 方法从 dependent.service 服务获取inline">ContainerBuilder 对象并用它来调用 helloWorld 方法。

通过这种方式,DependencyInjection 组件提供了一种在应用程序中实例化对象和注入依赖项的标准方法。

如何使用 YAML 文件动态加载服务

在本节中,我们将探讨如何从 YAML 文件动态加载服务。基本上,我们将更新上一节中讨论的示例。

除了 DependencyInjection 组件之外,我们还需要另外两个 Symfony 组件来实现 YAML 示例:Config 和 Yaml。回想一下,我们已经在安装和配置部分中安装了这两个组件以及 DependencyInjection 组件本身。那么我们就可以出发了!

继续在应用程序的根目录中创建包含以下内容的 services.yaml 文件。

services:
    demo.service:
        class:     \Services\DemoService
    dependent.service:
        class:     \Services\DependentService
        arguments: ["@demo.service"]

如您所见,使用 YAML 语法定义服务非常简单。要定义服务的依赖项,您需要使用 arguments 键。

接下来,继续创建包含以下内容的 di_yaml_container.php 文件。

load('services.yaml');
 
// fetch service from the service container
$serviceOne = $containerBuilder->get('dependent.service');
echo $serviceOne->helloWorld();

一切都几乎相同,只是我们从 services.yaml 文件加载服务,而不是在 PHP 代码本身中定义它。这允许动态定义应用程序依赖项。

如何注入惰性服务

在某些情况下,您想要注入惰性服务。有时,您的服务实例化起来非常繁重。因此,您只希望在真正需要时注入这样的服务,而不是在此之前。这个问题的答案是惰性服务。

但是这到底是如何工作的呢?事实上,当您配置惰性服务时,不是注入实际的服务,而是注入该服务的代理。从表面上看,代理服务的行为就像实际服务一样,但是一旦您开始与代理服务交互,实际服务就会被实例化。

要使用惰性服务,我们需要安装 symfony/proxy-manager-bridge 软件包。让我们首先这样做。

$composer require symfony/proxy-manager-bridge

接下来,我们将修改 di_container.php 示例,以了解如何使用代理管理器创建和注入代理服务。

继续将 di_container.php 文件的代码替换为以下内容。

get('demo.service'); // fill your object with values here

    return true; // confirm that initialization occurred correctly
};
$proxy = $factory->createProxy('\Services\DemoService', $initializer);
// code for creating proxy ends

global $containerBuilder;
$containerBuilder = new ContainerBuilder();
$containerBuilder->register('demo.service', '\Services\DemoService');
$containerBuilder->register('dependent.service', '\Services\DependentService')->addArgument($proxy);
$dependentService = $containerBuilder->get('dependent.service');

echo $dependentService->helloWorld();

首先,我们创建了 LazyLoadingValueHolderFactory 类的实例。接下来,我们使用此类的 createProxy 方法来定义如何创建 \Services\DemoService 类的实例。 createProxy 方法的第二个参数是一个匿名函数,当需要实例化类的实际实例而不是代理对象时,将调用该函数。因此,匿名函数处理创建实际实例的逻辑。

除此之外,几乎是一样的。创建代理实例后,我们将在 addArgument 方法中传递它,而不是使用 Reference 类创建实例。

这种方法的好处是,每当我们创建 \Services\DependentService 类的实例时,它都不会创建 \Services\DemoService 类的实际对象,而是创建一个代理对象。 \Services\DemoService 类的实际对象只有在调用它的任何方法时才会被创建。

要确认这一点,您可以转储 $dependentService 对象,您应该会看到类似这样的内容。

Services\DependentService Object
(
    [demo_service:Services\DependentService:private] => ProxyManagerGeneratedProxy\__PM__\Services\DemoService\Generatedccdf8241e892da36c12500ed72d82829 Object
        (
            [valueHoldera1fd8:ProxyManagerGeneratedProxy\__PM__\Services\DemoService\Generatedccdf8241e892da36c12500ed72d82829:private] => 
            [initializere3996:ProxyManagerGeneratedProxy\__PM__\Services\DemoService\Generatedccdf8241e892da36c12500ed72d82829:private] => Closure Object
                (
                    [parameter] => Array
                        (
                            [&$wrappedObject] => 
                            [$proxy] => 
                            [$method] => 
                            [$parameters] => 
                            [&$initializer] => 
                        )

                )

        )

)

如您所见,它创建了代理对象而不是实际的 \Services\DemoService 对象。

如果没有使用代理方法,输出会是这样的。

Services\DependentService Object
(
    [demo_service:Services\DependentService:private] => Services\DemoService Object
        (
        )

)

如您所见,它创建了 \Services\DemoService 类的实例。这就是服务延迟加载的工作原理!

结论

Symfony DependencyInjection 组件在本教程中占据了中心位置。我们了解了如何安装和配置 DependencyInjection,以及一些如何使用它的实际示例。

我对 Symfony 框架的解耦组件非常着迷和兴奋,您可以为您的应用程序挑选这些组件。将它们插入您的代码中,它们就可以工作了!总而言之,我只能看到这种框架方法对我们 PHP 社区的好处。

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

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

相关专题

更多
Java编译相关教程合集
Java编译相关教程合集

本专题整合了Java编译相关教程,阅读专题下面的文章了解更多详细内容。

11

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

4

2026.01.21

无人机驾驶证报考 uom民用无人机综合管理平台官网
无人机驾驶证报考 uom民用无人机综合管理平台官网

无人机驾驶证(CAAC执照)报考需年满16周岁,初中以上学历,身体健康(矫正视力1.0以上,无严重疾病),且无犯罪记录。个人需通过民航局授权的训练机构报名,经理论(法规、原理)、模拟飞行、实操(GPS/姿态模式)及地面站训练后考试合格,通常15-25天拿证。

16

2026.01.21

Python多线程合集
Python多线程合集

本专题整合了Python多线程相关教程,阅读专题下面的文章了解更多详细内容。

1

2026.01.21

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

4

2026.01.21

windows激活码分享 windows一键激活教程指南
windows激活码分享 windows一键激活教程指南

Windows 10/11一键激活可以通过PowerShell脚本或KMS工具实现永久或长期激活。最推荐的简便方法是打开PowerShell(管理员),运行 irm https://get.activated.win | iex 脚本,按提示选择数字激活(选项1)。其他方法包括使用HEU KMS Activator工具进行智能激活。

2

2026.01.21

excel表格操作技巧大全 表格制作excel教程
excel表格操作技巧大全 表格制作excel教程

Excel表格操作的核心技巧在于 熟练使用快捷键、数据处理函数及视图工具,如Ctrl+C/V(复制粘贴)、Alt+=(自动求和)、条件格式、数据验证及数据透视表。掌握这些可大幅提升数据分析与办公效率,实现快速录入、查找、筛选和汇总。

6

2026.01.21

毒蘑菇显卡测试网站入口 毒蘑菇测试官网volumeshader_bm
毒蘑菇显卡测试网站入口 毒蘑菇测试官网volumeshader_bm

毒蘑菇VOLUMESHADER_BM测试网站网址为https://toolwa.com/vsbm/,该平台基于WebGL技术通过渲染高复杂度三维分形图形评估设备图形处理能力,用户可通过拖动彩色物体观察画面流畅度判断GPU与CPU协同性能;测试兼容多种设备,但中低端手机易卡顿或崩溃,高端机型可能因发热降频影响表现,桌面端需启用独立显卡并使用支持WebGL的主流浏览器以确保准确结果

25

2026.01.21

github中文官网入口 github中文版官网网页进入
github中文官网入口 github中文版官网网页进入

github中文官网入口https://docs.github.com/zh/get-started,GitHub 是一种基于云的平台,可在其中存储、共享并与他人一起编写代码。 通过将代码存储在GitHub 上的“存储库”中,你可以: “展示或共享”你的工作。 持续“跟踪和管理”对代码的更改。

7

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号