Symfony 3.4 记录器服务



当我调用logger服务时,它在日志文件中收到此信息消息,但它已经工作,但将此消息写入日志文件中:

php.INFO:用户已弃用:"记录器"服务 是私有的,从容器中获取它已被弃用,因为 Symfony 3.2 并将在 4.0 中失败。应将服务设为公开,或者直接停止使用容器并使用依赖项注入 相反。{"exception":"[object] (ErrorException(code: 0): User 已弃用:"记录器"服务是私有的,从 容器自 Symfony 3.2 起已弃用,并将在 4.0 中失败。你 应将服务设为公共,或停止使用容器 直接并使用依赖注入。在/home/****/###/PROJECT/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php:275)"} []

我的符号版本:3.4.1

如Symfony 3.4中所述,MonologBundle提供的logger服务和所有其他服务默认设置为私有。[原文如此]

若要解决此问题,建议使用依赖关系注入。 http://symfony.com/doc/3.4/logging.html

namespace AppBundleController;
use PsrLogLoggerInterface;
use SymfonyBundleFrameworkBundleControllerController;
class DefaultController extends Controller
{
public function indexAction(LoggerInterface $logger)
{
$logger->info('Your Message');
}
}

源代码参考: https://github.com/symfony/monolog-bundle/blob/v3.1.0/Resources/config/monolog.xml#L17

对于服务定义,启用autowire时,依赖项注入可用。[原文如此]

#app/config/services.yml
services:
# default configuration for services in *this* file
_defaults:
# automatically injects dependencies in your services
autowire: true
# automatically registers your services as commands, event subscribers, etc.
autoconfigure: true
# this means you cannot fetch services directly from the container via $container->get()
# if you need to do this, you can override this setting on individual services
public: false
# makes classes in src/AppBundle available to be used as services
# this creates a service per class whose id is the fully-qualified class name
AppBundle:
resource: '../../src/AppBundle/*'
# you can exclude directories or files
# but if a service is unused, it's removed anyway
exclude: '../../src/AppBundle/{Entity,Repository,Tests}'
#enables dependency injection in controller actions
AppBundleController:
resource: '../../src/AppBundle/Controller'
public: true
tags: ['controller.service_arguments']
#all of your custom services should be below this line
#which will override the above configurations
#optionally declare an individual service as public
#AppBundleServiceMyService: 
#    public: true
#alternatively declare the namespace explicitly as public
#AppBundleService:
#    resource: '../../src/AppBundle/Service/*'
#    public: true

然后,若要将依赖项注入服务,请将参数的类型提示添加到构造函数中。

namespace AppBundleService;
use PsrLogLoggerInterface;
class MyService
{
private $logger;

public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}

}

如果禁用autowire,则可以手动定义服务以注入记录器别名。

#app/config/services.yml
services:
AppBundleServiceMyService:
arguments: ['@logger']
public: true

或者,若要强制从容器公开访问记录器别名,可以在应用程序服务配置中重新声明服务别名。

#app/config/services.yml
services:
#...

logger:
alias: 'monolog.logger'
public: true

除了覆盖配置中的值,还可以在编译器传递中将记录器设置为公共服务。 https://symfony.com/doc/4.4/service_container/compiler_passes.html

Symfony Flex

// src/Kernel.php
namespace App;
use SymfonyBundleFrameworkBundleKernelMicroKernelTrait;
use SymfonyComponentDependencyInjectionCompilerCompilerPassInterface;
use SymfonyComponentDependencyInjectionContainerBuilder;
use SymfonyComponentHttpKernelKernel as BaseKernel;
class Kernel extends BaseKernel implements CompilerPassInterface
{
use MicroKernelTrait;
public function process(ContainerBuilder $container)
{
// in this method you can manipulate the service container:
// for example, changing some container service:
$container->getDefinition('logger')->setPublic(true);
}
}

Symfony Bundle

// src/AppBundle/AppBundle.php
namespace AppBundle;
use SymfonyComponentHttpKernelBundleBundle;
use SymfonyComponentDependencyInjectionContainerBuilder;
use AppBundleDependencyInjectionCompilerCustomPass;
class AppBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new CustomPass());
}
}
// src/AppBundle/DependencyInjection/Compiler/CustomPass.php
namespace AppBundleDependencyInjectionCompiler;
use SymfonyComponentDependencyInjectionCompilerCompilerPassInterface;
use SymfonyComponentDependencyInjectionContainerBuilder;
class CustomPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$container->getDefinition('logger')->setPublic(true);
}
}

$this->container->get('logger')失败,因为记录器现在(从 3.2 开始)标记为私有服务,默认情况下所有服务都是私有的,这意味着这些服务不能从容器返回,而是必须注入依赖关系(类构造函数必须将记录器作为参数并成为类的属性才能访问), 或者在服务配置中标记为公共,并且由于记录器是Symfony组件,服务配置在Symfony项目中,您必须将Logger配置从Symfony复制到项目服务配置并添加public: true,才能从容器访问记录器实例。

最新更新