亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將 Symfony 的依賴注入(自動裝配)集成到遺留應用程序中

將 Symfony 的依賴注入(自動裝配)集成到遺留應用程序中

PHP
函數式編程 2023-07-21 16:17:43
我有一個遺留應用程序,它是基于舊的自定義 MVC 框架構建的,我希望最終放棄該框架。這個框架不依賴于單個前端控制器,因此大多數頁面仍然有專用的php文件來調用受人尊敬的控制器,其他頁面是混合的php/html。我已經閱讀了有關使用各種方法將應用程序遷移到 symfony 的內容(https://symfony.com/doc/current/migration.html),但是我在使用這兩種方法時都遇到了問題,并且意識到我實際上并不需要 symfony 的路由處理。Symfony 目前存在于我們的應用程序中,但僅由各種命令使用。我們所有的核心邏輯仍然在遺留應用程序中,因此 Symfony 可以毫無問題地訪問它,因為這些類都在全局命名空間中。然而,問題是,遺留應用程序無法使用任何新的 Symfony 類,因為它不支持依賴項注入。為了開始將我們的一些核心邏輯和功能轉移到 Symfony,需要這種能力。理想情況下,我希望能夠完成的是將容器加載到我們的遺留應用程序中,該應用程序具有所有可用的自動裝配服務。允許我在舊應用程序中訪問基于 Symfony 的新服務。非常感謝任何幫助。非常感謝。更新1所以我嘗試了@Cerad所說的,只需訪問內核,因為它是全局的。我將 bootstrap.php 邏輯復制到舊應用程序的主配置(因此它加載現有的 .env* 文件),然后啟動內核(實例化它并在舊配置中調用 boot)。它有效,我可以在我的 php 文件中引用 $kernel (使用全局 $kernel)并訪問容器。然而,這與@Dmitry Solovov 的回應一致,服務必須是公開的。我必須將所有我想要的服務設為公開嗎?如果我在 services.yaml 中手動定義服務,將其設置為公共,它就可以工作。但這并不是很理想,因為我想自動加載我的服務,因此我可以以正確的方式使用服務,而不必顯式定義我希望在舊應用程序中可用的每項服務。如何在不公開服務的情況下將服務注入到我的舊控制器中?就像 Symfony 的控制器如何允許您將服務注入到 Controller 方法中一樣?多謝。
查看完整描述

2 回答

?
慕村225694

TA貢獻1880條經驗 獲得超4個贊

獨立使用依賴注入:


安裝包:

composer require symfony/dependency-injection

在配置文件中定義您的服務(即src/Resources/config/services.yaml)。例子:

services:

    _defaults:

        autowire: true

        autoconfigure: true

        public: false


    App\Services\MyService:

        class: App\Services\MyService

        public: true

您還可以使用服務自動導入功能https://symfony.com/doc/current/service_container.html#importing-many-services-at-once-with-resource


使用以下代碼編譯 DI 容器:

use Symfony\Component\Config\FileLocator;

use Symfony\Component\DependencyInjection\ContainerBuilder;

use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;


$container = new ContainerBuilder();

$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/src/Resources/config'));

$loader->load('services.yaml');

$container->compile();

將此容器實例注入到您的應用程序中。或者擴展該類ContanerBuilder并使其成為單例。

應用程序中使用的服務應該是公共的,因此您可以直接從容器中獲取它們:


$service = $container->get(\App\Services\MyService::class);

您還可以默認公開所有服務:


services:

    _defaults:

        public: true


查看完整回答
反對 回復 2023-07-21
?
拉風的咖菲貓

TA貢獻1995條經驗 獲得超2個贊

我有一個在所有頁面上加載的配置,這是我復制引導邏輯并加載內核的地方:


// ***** legacy config code above


// This probably could just be loaded using require, but kept it here for completeness

if (is_array($env = @include dirname(__DIR__).'/.env.local.php')) {

? ? foreach ($env as $k => $v) {

? ? ? ? $_ENV[$k] = $_ENV[$k] ?? (isset($_SERVER[$k]) && 0 !== strpos($k, 'HTTP_') ? $_SERVER[$k] : $v);

? ? }

} elseif (!class_exists(Dotenv::class)) {

? ? throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.');

} else {

? ? // load all the .env files

? ? (new Dotenv(false))->loadEnv(dirname(__DIR__).'/config/.env');

}


$_SERVER += $_ENV;

$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev';

$_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'dev' == $_SERVER['APP_ENV'];

$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0';

// End Symfony's bootstrap


// Load Symfony's kernel

$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);

$kernel->boot();

從那里我可以訪問我想要的特定服務 - 只要它是公開的:


global $kernel;

$service = $kernel->getContainer()->get(\App\Services\MyService::class);

讓這個項目在我的項目中運行良好的真正想法不是將所有服務設置為公共,而是創建一個遺留服務,該服務是在 services.yaml 中手動定義并設置為公共的:


services:

? ? App\Services\Legacy\AWSLegacy:

? ? ? ? public: true

AWSLegacy 看起來像:


namespace App\Services\Legacy;


use App\Services\AWS\S3;


class AWSLegacy

{

? ? /** @var S3 */

? ? public $s3;


? ? public function __construct(

? ? ? ? S3 $s3

? ? )

? ? {

? ? ? ? $this->s3 = $s3;

? ? }

}

這使我能夠將我想要在舊應用程序中使用的類似服務分組在一起,而無需在 services.yaml 中為每個服務手動創建引用并將其設置為公共。


Symfony 橋接方法對我不起作用,因為我不希望 Symfony 在我的舊應用程序中處理路由(請求和響應),我只想訪問新服務。



查看完整回答
反對 回復 2023-07-21
  • 2 回答
  • 0 關注
  • 176 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號