Foire aux questions Symfony

L'un des premiers endroits où passer quand vous avez un souci avec ce framework

a marqué ce sujet comme résolu.

Je n'arrive pas à utiliser les méthodes de mon repository ! J'ai l'erreur

Undefined method 'UneMéthodeDeMonRepository'. The method name must start with either findBy or findOneBy!

Vous avez très probablement

  • oublié de renseigner votre repository dans vos mappings
1
2
3
4
5
6
<?php
/**
 * @ORM\Entity(
 *   repositoryClass="[[ le nom de votre classe repository, avec le namespace ]]"
 * )
 */

Annotation pour préciser l'existence d'un repository

  • mis le mauvais nom/namespace pour le repository (attention à la casse et aux contre-obliques)
  • mis le fichier de votre repository dans un dossier ne correspondant pas au namespace dudit repository
  • mal nommé la classe

Je n'arrive toujours pas à utiliser les méthodes de mon repository, et j'ai ajouté l'annotation ci-dessus, avec le namespace, et je suis SÛR qu'il est correct aux trois points mentionnés ci-dessus !

Alors passez au message suivant ^^

+0 -0
Mappings pas pris en compte

Quand j’utilise doctrine:schema:update --force, il m’est dit que tout est bon, mais les tables pour certaines entités ne sont jamais créées/mises à jour !

Quand j’utilise doctrine:generate:entities, les getters et setters ne sont pas créés dans certaines de mes entités !

Quand j’utilise doctrine:migration:diff, je n’ai rien de nouveau dans la migration créée, alors que j’ai bien ajouté des choses !

Certaines de mes entités ne sont pas reconnues ou génèrent des erreurs comme quoi ce ne sont pas des entités valides !

Vous avez probablement un mélange de types de mappings dans votre bundle, et Symfony ne prend jamais qu’un seul type à la fois. Plusieurs types ne cohabitent pas.

Quelque part dans la génération de l’une de vos entités ou de votre bundle, vous n’avez pas spécifié le bon format pour les mappings. Vous n’avez probablement

  • pas de #[ORM\QuelqueChose]
  • pas de @ORM\QuelqueChose
  • un mélange des deux ci-dessus

dans vos entités (du moins pas partout, ou vous en avez ajoutés vous-même), ou encore si vous allez regarder dans le dossier Ressources/config de votre bundle, vous y trouverez un dossier doctrine, et des fichiers *.orm.xml (ou *.orm.yml), ou un dossier metadata/orm, ou d’autres trucs encore. C’est dû au choix de yml respectivement xml ou php au lieu de attributes ou annotations soit lors de la génération de l’entité, soit lors de la génération du bundle.

Les mappings dans des fichiers à part vont primer sur les attributs ou annotations que vous avez mis dans vos entités, et du coup Doctrine ignorera les attributs ou annotations pour toutes les entités de l’espace de nom.

  1. Vérifiez que votre bundle est bien déclaré dans AppKernel.php
  2. Vérifiez que vous avez bien déclaré votre bundle dans la configuration pour les mappings. Si vous n’utilisez pas doctrine.orm.auto_mapping: true, votre bundle doit être listé pour que les mappings soient pris en compte
  3. Déplacez les fichiers sur lesquels vous avez travaillé pour cette entité quelque part ailleurs ;
  4. Utilisez la commande doctrine:mappings:convert annotation le/chemin/vers/le/dossier/pour/votre/entité --filter="le nom de votre entité avec le namespace" --force ;
  5. Supprimez le dossier doctrine (vous pouvez en garder une copie de sécurité quelque part, mais vous ne devriez plus en avoir besoin) ;
  6. Dupliquez les modifications que vous aviez faites vous-même dans la nouvelle version de l’entité depuis l’ancienne version
  7. N’oubliez pas de purger votre cache !

Normalement, vous devriez récupérer une belle entité annotée et avec vos modifications, et celles-ci sont prises en compte.

Si cela n’a pas marché, re-générez l’entité en faisant attention aux options que vous choisissez.

Si cela n’a pas fonctionné non-plus et que vous n’avez que cette entité dans le bundle, re-générez le bundle, en faisant attention aux options que vous choisissez.

+0 -0

J'ai cette erreur, comment faire ?

An exception occurred while executing '… FOREIGN KEY (…) REFERENCES … (id)':
Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`symfony`.<result 2 when explaining filename '…'>, CONSTRAINT `…` FOREIGN KEY (`…_id`) REFERENCES `…` (`id`))

Cette erreur survient lorsque l'on a une entité existante déjà matérialisée dans la base de donnée.

Imaginez que vous souhaitez ajouter cette relation facultative ( facultative car JoinColumn(nullable=false))

1
2
3
4
5
6
<?php
   /**
    * @ORM\ManyToOne(targetEntity="Kyna\CollectionBundle\Entity\Categorymaster")
    * @ORM\JoinColumn(nullable=false)
    */
   private $categorymaster;

Exemple de relation facultative

A la mise à jour, Doctrine vas vous créer la colonne dans votre table, puis va vous afficher l'erreur dans la console, car les entrées existantes dans votre table auront pour valeur NULL d'assigné à la colonne que vous venez de créer. Or vous avez bien indiqué @ORM\JoinColumn(nullable=false) qui interdit la valeur NULL.

Ce qu'il faut faire lors de l'ajout de votre attribut à votre entité, c'est passer nullable à true, mettre à jour votre base de donnée, ensuite la passer à false et la mettre à nouveau à jour, vous êtes donc obligé de procéder en deux étapes. Cette erreur ne surviendra jamais si vous ajoutez nullable=true à une entité existante déjà présente en BDD, car la première étape aura déjà été effectuée par le passé au moment de la création de votre entité – si vous avez mis votre BDD à jour à ce moment là.

+0 -0

J'ai traduit mon interface. Depuis que j'ai créé mes fichiers messages.(fr|en|…).(xliff|xlf|xml|yml|php), je n'ai plus que la version anglaise qui s'affiche, ou des chaînes incompréhensibles et moches

Il y a plusieurs choses auxquelles il faut faire attention quand on met en place les traductions de l'interface :

  1. La locale globale de votre application, spécifiée dans config.yml depuis Symfony 2.7.x, dans parameters.yml auparavant

    1
    2
    3
    parameters:
         # …
         locale: fr
    
  2. le domaine de traduction spécifié dans le template

    1
    2
    3
    4
    <p>{{ 'fos_user.registration.fos_user_registration_username'|trans(
        {},
        'FOSUserBundle'
    ) }}</p>
    

    N'oubliez pas le premier argument si vous spécifiez un domaine

    Notez que vous n'avez pas besoin de spécifier le domaine 'messages', car c'est celui par défaut.

    Vous pouvez aussi utiliser {% trans_default_domain "myDefaultDomainForThisTemplate" %}

  3. Si vous utilisez le format XLIFF, il y a un paramètre à spécifier dans le fichier de traduction, à la ligne 4 du code ci-dessous

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    <?xml version="1.0"?>
    <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
        <file
            source-language="fr"
            datatype="plaintext"
            original="file.ext"
        >
            <body>
                <trans-unit id="1">
                    <source>J'aime Symfony2</source>
                    <target>Symfony2 is great</target>
                </trans-unit>
            </body>
        </file>
    </xliff>
    
+0 -0

J'ai traduit mes entités avec StofDoctrineExtensionsBundle et/ou Doctrine Extensions, mais je n'ai que le contenu en Anglais qui s'affiche !

Là aussi, il y a une locale qui est par défaut en anglais, et qu'il vous faut faire coller à celle déclarée dans votre fichier principal config.yml ou, avant Symfony 2.7.x, dans parameters.yml

1
2
stof_doctrine_extensions:
    default_locale: %locale%

Paramétrage de la locale pour StofDoctrineExtensionsBundle

+0 -0

J'ai tout bien suivi le tutoriel sur la traduction, mais rien n'est traduit dans les vues où j'ai des {{ render() }} !

{{ render(…) }} génère une nouvelle requête HTTP interne. Seulement, cette requête doit aussi connaître la locale souhaitée, et Symfony ne la renseigne pas automatiquement quand vous utilisez {{ render() }}. Du coup, c'est la locale par défaut qui sera utilisée… pour l'entier de la page, et non juste pour la partie intégrée !

Il vous faut donc spécifier la locale en utilisant un paramètre supplémentaire, ce qui donne {{ render(controller([votre action], { '_locale': app.request.locale })) }}

+0 -0

J'ai une boucle for et j'aimerais pouvoir exécuter du code toute les x boucles, comment faire ?

1
2
3
4
5
{% for video in videosRecentes %}
   <article class="column{{ cycle(['1', '2', '3'], loop.index0) }}" style="display:inline-block">
      <!-- {# Un peu de code HTML et éventuellement Twig ici #} -->
   </article>
{% endfor %}

Exemple de définition de classe selon le numéro d'itération

loop.index0 permet de compter le nombre de boucle en partant de 0 (0, 1, 2, 3, 4, etc.). Dans cycle(), on défini les options que l'on souhaite répéter. Pour l'exemple, on va tourner simplement parmi les valeurs 1, 2 et 3.

Le code ci-dessus affichera :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<section id="videosRecentes" class="padding">
   <article class="column1" style="display:inline-block">
      <!-- -->
   </article>
   <article class="column2" style="display:inline-block">
      <!-- -->
   </article>
   <article class="column3" style="display:inline-block">
      <!-- -->
   </article>
   <article class="column1" style="display:inline-block">
      <!-- -->
   </article>
   <article class="column2" style="display:inline-block">
      <!-- -->
   </article>
</section>

Résultat avec 5 éléments dans videosRecentes

+0 -0

J'ai plusieurs catégories, j'aimerais afficher dans ma vue le nombre d'articles que contiennent chacune d'elles, comment faire ?

1
2
3
4
5
{% for category in categories %}
   {{ category.mods.count }} {# retourne le nombre d'élément si utilisé sur une collection #}
     {# OU #}
   {{ category.articles|length }} {# retourne le nombre d'élément si utilisé sur un array #}
{% endfor %}

Exemple de récupération du nombre d'entités liées

C'est tout, pas besoin de requêtes supplémentaire ou de quoi que ce soit côté controller :)

+0 -0

Comment puis-je générer un lien avec une ancre (la partie après le #) dans Twig, pour avoir quelque chose comme mon/url#monAncre ? N’y a-t-il pas moyen de le faire avec {{ path() }} ?

Depuis la version 3.2, il existe un paramètre de route nommé _fragment qui, passé comme "argument de route" à la fonction {{ path() }}, va vous placer le croisillon et l’ancre dans l’URL généré. Exemple :

{{ path(…, {…, '_fragment': entite.propriete}) }}

+0 -0
Concerne Symfony avant la version 4

Je viens de créer un nouveau bundle, mais Symfony ne me le trouve pas !
J’ai ajouté une dépendance, et Symfony ne trouve plus mes bundles !
Moi j’ai supprimé un de mes bundles, et Symfony le cherche toujours !

On fait quoi maintenant ?

Le souci vient en partie de Composer qui parfois renseigne des données un peu particulières dans le fichier composer.json. Notamment quand vous créez un bundle, il va mettre le nom et le chemin correspondant dans composer.json pour que vous n’ayez pas à faire de include Mon\BôBundle\…. Seulement, il arrive que ça pose problème, soit parce que la ligne pour votre nouveau bundle n’y est pas, soit parce que celle de votre ancien bundle y est toujours. Il y a un moyen de régler cela une fois pour toutes.

Ouvrez composer.json avec votre éditeur de code, et modifiez comme suit.

Remplacez :

// …
"psr-4": {
    // …
    "[Nom de l'un de vos bundles]\\": "src/[Nom du même bundle]"
    // …
},
// …
Ce que vous avez probablement dans composer.json et qui pose problème

Par :

// …
"psr-4": {
    // Plus besoin de lister tous vos bundles
    "": "src/"
},
// …
Ce que vous devriez avoir et qui règle le problème

Et concluez la modification par la commande de composer dump-autoload.

Peut-être lancez-vous aussi les commandes directement depuis le dossier bin/ de Symfony ? Evitez.

Le script regarde depuis où est lancée la commande, et adapte les résultats. Or, s’il est mentionné d’utiliser …/symfony> php bin/console plutôt que …/symfony/bin> console, c’est aussi pour ne pas avoir ce genre de problèmes.

+0 -0

Pourquoi je ne vois pas la barre de débogage de Symfony ?
Comment faire pour l’afficher ?
Pourquoi elle n’affiche pas les informations de débogage ?

Pourquoi mes assets ne sont pas trouvés ?

Le problème survient surtout si vous n’utilisez pas d’hôte virtuel pour votre projet Symfony, et si c’est le cas, il est mal configuré. Vous avez deux solutions possibles. Vous pouvez appliquer les deux, mais c’est inutile si celle que vous utilisez pour l’instant est correctement mise en place et utilisée dans le bon contexte.

Définir un hôte virtuel pour votre projet

Ou le corriger le cas échéant

C’est la solution la plus efficace, mais pas la plus simple. La documentation officielle explique presque tout. La seule chose est de bien savoir quelle solution serveur vous utilisez.

  1. Apache ou nginx ?
    • En cas d’Apache, version 2.2.x ou 2.4.x ?
  2. PHP utilisé en module Apache (mod_php), en FPM ou en FastCGI (FCGI) ?

Sachez au moins qu’avec WampServer, c’est Apache 2.4 avec mod_php.

Récupérer le fichier .htaccess nécessaire

La solution la plus rapide, mais qui impacte un peu votre serveur.

Pour Symfony 4 et ultérieures, vous pouvez installer la dépendance symfony/apache-pack avec Composer.

Pour toutes versions avant Symfony 4, ce .htaccess est fourni dans le code initial.

N’oubliez pas que sous Windows, il s’agit d’un fichier caché.

Dans le cas où vous devez récupérer le contenu, inspirez-vous de la version de symfony/apache-pack. Pour Symfony avant la version 4, n’oubliez pas de remplacer index.php par app.php ou app_dev.php.

Il arrive aussi parfois que, suivant le tutoriel que vous suivez, vous n’ayez pas installé la version web de Symfony, et que le composant gérant la barre de débogage n’est pas présent. Auquel cas, il faut en plus des manipulations ci-dessus, installer symfony/profiler-pack.

+0 -0

J’ai l’erreur « An exception occured in driver: could not find driver », que se passe-t’il ?

Du moment que le package doctrine/orm est installé (ce qui est fait par défaut avec symfony/website-skeleton), il faut que la base de données soit disponible. Or, depuis la version 2.9 dudit package, les données par défaut pour la connexion sont pour PostgreSQL.

Il faut donc soit :

  • adapter les données de connexion pour votre moteur de bases de données (regardez attentivement le fichier .env qui contient des exemples ainsi qu’un lien vers la documentation) ;
  • vérifier que le driver pour votre moteur de bases de données est bien activé pour Apache comme pour la ligne de commandes ;
  • temporairement enlever les packages doctrine/* de votre projet.
+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte