web-dev-qa-db-fra.com

Service de journalisation Symfony 3.4

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

6
A.Seddighi

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);
    }
}
12
fyrye

$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.

2
Yasha Nisanov