具有Symfony组件的PHP中的依赖注入示例

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

什么是Symfony DependencyInjection组件?

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

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

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

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

安装与配置

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

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

$composer require symfony/dependency-injection

那应该已经创建了composer.json文件,它应该看起来像这样:

{
    "require": {
        "symfony/dependency-injection": "^4.1",
    }
}

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

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

$composer require symfony/yaml

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

$composer require symfony/config

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

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

在添加新的类映射条目后,我们继续运行以下命令来更新composer自动加载器。

$composer dump -o

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

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

<?php
require_once './vendor/autoload.php';

// application code
?>

如何使用容器

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

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

<?php
// src/DemoService.php
namespace Services;

class DemoService
{
  public function helloWorld()
  {
    return "Hello World!\n";
  }
}

这是一个非常简单的服务,目前仅实现helloWorld方法。

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

<?php
// basic_container.php
require_once './vendor/autoload.php';
use Symfony\Component\DependencyInjection\ContainerBuilder;

// init service container
$containerBuilder = new ContainerBuilder();

// add service into the service container
$containerBuilder->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方法从ContainerBuilder中获取我们的服务,并使用它来调用helloWorld方法。

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

真实的例子

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

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

继续并使用以下内容创建src / DependentService.php文件,以定义DependentService服务。

<?php
// src/DependentService.php
namespace Services;

class DependentService
{
  private $demo_service;

  public function __construct(\Services\DemoService $demoService)
  {
    $this->demo_service = $demoService;
  }

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

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

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

<?php
// di_container.php
require_once './vendor/autoload.php';
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

// init service container
$containerBuilder = new ContainerBuilder();

// add demo service into the service container
$containerBuilder->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服务的DependentService 。 我们已经使用Reference类来通知容器,当dependent.service服务初始化时,它需要注入demo.service服务。 这样,将根据需要自动注入依赖项!

最后,我们使用了get的方法ContainerBuilder对象,以获取dependent.service从服务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文件。

<?php
// di_yaml_container.php
require_once './vendor/autoload.php';
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

// init service container
$containerBuilder = new ContainerBuilder();

// init yaml file loader
$loader = new YamlFileLoader($containerBuilder, new FileLocator(__DIR__));

// load services from the yaml file
$loader->load('services.yaml');

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

除了我们从services.yaml文件加载服务,而不是在PHP代码本身中定义服务之外,所有内容几乎相同。 这样可以动态定义应用程序依赖项。

结论

Symfony DependencyInjection组件在本教程中处于中心地位。 我们看到了如何安装和配置DependencyInjection,以及一些有关如何使用它的真实示例。

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

使用下面的提要分享您的想法和建议。 我想与您进一步讨论!

翻译自: https://code.tutsplus.com/tutorials/examples-of-dependency-injection-in-php-with-symfony-components--cms-31293

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值