Lorsque j'ai appelé le service logger
obtenir ce message d'information dans le fichier journal, cela fonctionne mais écrivez ce message dans le fichier journal:
php.INFO: Utilisateur obsolète: Le service "enregistreur" est privé, le récupérer à partir du conteneur est obsolète depuis Symfony 3.2 et échouera en 4.0. Vous devez soit rendre le service public, soit cesser d'utiliser directement le conteneur et utiliser l'injection de dépendance au lieu. {"exception": "[objet] (ErrorException (code: 0): Utilisateur Désapprouvé: le service \" logger\"est privé. L'obtenir à partir du conteneur est obsolète depuis Symfony 3.2 et échouera dans 4.0 .Vous devez soit rendre le service public, soit cesser d’utiliser le conteneur Directement et utiliser l’injection de dépendance à la place de /Home/****/###/PROJECT/vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Container.php: 275) "} []
Ma version de symfony: 3.4.1
Comme indiqué dans Symfony 3.4, le service logger
fourni par MonologBundle
et tous les autres services est défini sur privé par défaut. [sic]
Pour résoudre le problème, la méthode recommandée consiste à utiliser Dependency Injection . http://symfony.com/doc/3.4/logging.html
namespace AppBundle/Controller;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
public function indexAction(LoggerInterface $logger)
{
$logger->info('Your Message');
}
}
Code source Référence: https://github.com/symfony/monolog-bundle/blob/v3.1.0/Resources/config/monolog.xml#L17
Pour les définitions de service, l’injection de dépendance est disponible lorsque autowire
est activé. [sic]
#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
AppBundle\Controller\:
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
#AppBundle\Service\MyService:
# public: true
#alternatively declare the namespace explicitly as public
#AppBundle\Service\:
# resource: '../../src/AppBundle/Service/*'
# public: true
Ensuite, pour injecter la dépendance dans le service, vous ajoutez l'indicateur de type pour l'argument au constructeur.
namespace AppBundle\Service;
use Psr\Log\LoggerInterface;
class MyService
{
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
}
si autowire
est désactivé, vous pouvez définir manuellement vos services pour injecter l'alias du consignateur.
#app/config/services.yml
services:
AppBundle\Service\MyService:
arguments: ['@logger']
public: true
Sinon, pour forcer l'alias du consignateur à être accessible publiquement à partir du conteneur, vous pouvez re-déclarer l'alias de service dans la configuration de vos services d'application.
#app/config/services.yml
services:
#...
logger:
alias: 'monolog.logger'
public: true
Au lieu de remplacer la valeur dans la configuration, vous pouvez également définir le consignateur en tant que service public dans une passe de compilation. https://symfony.com/doc/3.4/service_container/compiler_passes.html
Symfony Flex
// src/Kernel.php
namespace App;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel 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 Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use AppBundle\DependencyInjection\Compiler\CustomPass;
class AppBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new CustomPass());
}
}
// src/AppBundle/DependencyInjection/Compiler/CustomPass.php
namespace AppBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class CustomPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$container->getDefinition('logger')->setPublic(true);
}
}
$this->container->get('logger')
échoue car l’enregistreur est maintenant (à partir de 3.2) marqué comme service privé; tous les services sont privés par défaut, ce qui signifie que ces services ne peuvent pas être renvoyés du conteneur et doivent plutôt être des dépendances logger en tant que paramètre et devient une propriété de la classe à être accessible), ou marqué comme public dans la configuration du service, et comme le consignateur est un composant symfony, la configuration du service est dans le projet symfony, logger de symfony à votre configuration de service de projet et ajoutez public: true
pour accéder à l’instance de journalisation à partir du conteneur.