• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

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

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

什么是 Symfony DependencyInjection 组件?

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

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

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

在本文中,我们将探讨如何释放 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();

首先,我们使用const ructor初始化ContainerBuilder对象。接下来,我们使用对象的方法将我们的自定义服务注入到容器中。充当我们服务的别名。new ContainerBuilder() registerContainerBuilder\Services\DemoServicedemo.service

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

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

一个真实的例子

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

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

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

<?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();
  }
}

如您所见,\Services\DemoService服务是实例化服务所必需的DependentService。

接下来,继续创建具有以下内容的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服务的依赖关系。我们已经使用Reference该类来通知容器它需要在服务初始化demo.service时注入服务。dependent.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 DependencyInjection 组件?
  • 安装和配置
  • 如何使用容器
  • 一个真实的例子
  • 如何使用 YAML 文件动态加载服务
  • 结论