[RESOLU] symfony 5 services.yaml arguments dans un fichier indépendant

Mammouth du PHP | 19672 Messages

04 avr. 2023, 15:07

Bonjour tout le monde,
je cherche à ajouter un container dans mon application avec symfony 5.

L'ajout dans le fichier services.yaml fonctionne correctement et je vois vien apparaître le container dans la liste lorsque j'appelle « php bin/console debug:container » .
Cette étape franchie, je dois cependant ajouter des arguments, mais ces arguments sont déjà dans un fichier.

Dans mon fichier services .yaml, j'ai ajouté quelque chose qui ressemble a`ceci :

Code : Tout sélectionner

toto: class: cyrano\toto\toto
Logiquement, je dois ajouter :

Code : Tout sélectionner

toto: class: cyrano\toto\toto arguments: ???? <== c'est là que je bloque
Ce qui est attendu en l'occurrence est un tableau de données, ce tableau est dans un fichier qui est généré automatiquement par ailleurs. Et dans ce fichier, il n'y qu'une seule variable qui ressemble par exemple à $totoConf = [....]

Ce fichier pourrait être là où je déciderai de le mettre, donc à moins que ce ne soit pas une bonne idée, je le mettrai probablement dans config/packages/totoConf.php et ce que je veux récupérer, c'est la variable qui est dedans.

Je ne trouve pas l'information dans la documentation, et ce n'est pas faute de fouiller dedans. Est-ce que quelqu'un aurait la réponse ?
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Avatar du membre
Mammouth du PHP | 1609 Messages

04 avr. 2023, 16:02

Salut Cyrano,

Je pense que comme ça, ça devrait fonctionner (à adapter).

Clé imports dans services.yaml au début du fichier pour importer le fichier de configuration :
# config/services.yaml
imports:
    - { resource: 'packages/toto_conf.php' }

Fichier de configuration en php dans packages/toto_conf.php :
// config/packages/toto_conf.php
namespace Symfony\Component\DependencyInjection\Loader\Configurator;

return static function (ContainerConfigurator $containerConfigurator) {
    $containerConfigurator->extension('toto_conf', [
        'parameter_name' => 'parameter value',
        // ...
    ]);
};

On revient au services.yaml section services :
# config/services.yaml
services:
    # ...
    App\Cyrano\Toto:
        arguments:
            $parameterName: '%toto_conf.parameter_name%'

Avec une classe Toto ayant un paramètre $parameterName à son construct.
Développeur web depuis + de 20 ans

Mammouth du PHP | 19672 Messages

04 avr. 2023, 16:06

Ok merci bien, je vais essayer ça.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Mammouth du PHP | 19672 Messages

06 avr. 2023, 09:25

Bon ben je ne m'en sors pas, j'exècre ces frameworks dont la documentation est systématiquement merdique à souhait.

Pour l'import, j'ai mis ceci dans le fichier services.yaml qui ne semble pas poser de problème :

Code : Tout sélectionner

imports: - {resource: "packages/totoConf.php"}
Pour la création du service, j'ai ensuite fini par obtenir un résultat et vu apparaître mon service dans le container :

Code : Tout sélectionner

services: # ... # add more service definitions when explicit configuration is needed # please note that last definitions always *replace* previous ones Cyrano\toto\toto: autowire: true public: true class: Cyrano\toto\toto arguments: $totoConf: ???????????????? <==== Ça bloque toujours ici app.toto: '@Cyrano\toto\toto'
Mais j'ai toujours un problème avec l'argument.

Mon fichier importé contient une variable qui s'appelle ... mettons $tConf qui est un tableau. J'ai besoin que ce tableau soit envoyé en argument lors de la création de l'instance de mon service.

J'ai essayé le fichier toto_conf.php, mais il bloque avec une histoire de namespace me disant qu'il ne le trouve pas et m'en cite d'autres dont je n'ai rien à faire. ... et en fait je ne comprends même pas l'utilité d'ajouter ce fichier php : est-ce que je ne peux pas indiquer le nom d'une variable du fichier importé ? Je ne trouve rien sur la syntaxe yaml pour faire ça.

Une idée ?
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

ynx
Mammouth du PHP | 586 Messages

06 avr. 2023, 09:53

j'ai pas le même avis sur la doc mais c'est subjectif, elle a au moins le mérite d'exister.
Est-ce que tu as définis le namepace Symfony\Component\DependencyInjection\Loader\Configurator; au début de ton fichier de config comme montré dans tous les exemples des fichiers de config au format php sur la doc ?
Pourquoi ne pas utiliser le format YAML pour la config de ton service ?
https://symfony.com/doc/current/configu ... parameters

Mammouth du PHP | 19672 Messages

06 avr. 2023, 11:12

j'ai pas le même avis sur la doc mais c'est subjectif, elle a au moins le mérite d'exister.
Est-ce que tu as définis le namepace Symfony\Component\DependencyInjection\Loader\Configurator; au début de ton fichier de config comme montré dans tous les exemples des fichiers de config au format php sur la doc ?
Pourquoi ne pas utiliser le format YAML pour la config de ton service ?
https://symfony.com/doc/current/configu ... parameters
Oui, j'ai fait ça sans résultat.

Mais laissez tomber, j'ai contourné le problème en créant une classe Factory et je gère le paramétrage de mon package par là.
Donc je mets le sujet en résolu, mais en pratique, le problème de fond ne l'est pas.

Et je maintiens que cette documentation est totalement merdique, je persiste et signe.
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

Avatar du membre
Mammouth du PHP | 1609 Messages

06 avr. 2023, 13:27

A priori le problème vient de la méthode extension (désolé), j'avais vu ça dans la doc mais ça ne colle pas ici, elle sert à autre chose... c'est mieux avec la méthode parameters :
$containerConfigurator->parameters()
    ->set('toto_conf.parameter_name', ['parameter value']);

Rien ne t'empêche de mettre totoConf tout court.
$containerConfigurator->parameters()
    ->set('totoConf', /*...*/);
Et
arguments:
    $totoConf: '%totoConf%'
J'essayais juste de respecter un peu les conventions symfony.

Testé et approuvé !
App\Service\TotoService {#2033 ▼
  -totoConf: array:1 [▼
    0 => "parameter value"
  ]
}

Avec services.yaml :
imports:
    - { resource: 'packages/toto_conf.php' }

services:
    App\Service\TotoService:
        arguments:
            $totoConf: '%totoConf%'
toto_conf.php :
<?php

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

return static function (ContainerConfigurator $containerConfigurator) {
    $containerConfigurator->parameters()
        ->set('totoConf', ['parameter value']);
};
et classe :
<?php

namespace App\Service;

class TotoService
{
    private array $totoConf;

    public function __construct(array $totoConf)
    {
        $this->totoConf = $totoConf;
    }
}
Développeur web depuis + de 20 ans