<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="https://ktherage.github.io/fr/xsl/atom.xsl" media="all"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
  <id>https://ktherage.github.io/fr/blog/2024/</id>
  <title>Kévin THÉRAGE | Symfony Lead Developer (Expert Symfony 7 Certified) - 2024</title>
  <subtitle><![CDATA[Kévin THÉRAGE – Symfony Lead Developer, Expert Symfony 7 Certified. Technical blog on Symfony, PHP, web development with tutorials, best practices and expert advice for developers.]]></subtitle>
  <link href="https://ktherage.github.io/fr/blog/2024/atom.xml" rel="self" type="application/atom+xml" />
  <link href="https://ktherage.github.io/fr/blog/2024/" rel="alternate" type="text/html" />
  <updated>2026-08-28T15:17:52+00:00</updated>
  <author>
    <name>Kévin THÉRAGE</name>
    <uri>https://ktherage.github.io/</uri>
  </author>
  <entry xml:lang="fr">
    <id>https://ktherage.github.io/fr/blog/2024/symfony-and-doctrine-migrations-validation-in-ci/</id>
    <title>Symfony &amp; Doctrine Migrations : Validation en CI</title>
    <published>2024-09-05T00:00:00+00:00</published>
    <link href="https://ktherage.github.io/fr/blog/2024/symfony-and-doctrine-migrations-validation-in-ci/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>J'ai eu l'opportunité de travailler sur un projet avec une équipe relativement novice en matière de migrations Doctrine. Pour les aider à s'y habituer et écarter la possibilité d'avoir des pull (ou merge) requests avec des modifications d'entités Doctrine sans migration générée.</p>
<p>Voici comment j'ai procédé. J'espère que cela vous plaira !</p>
<h2 id="avertissement">Avertissement</h2>
<p>Nous sommes le 10 juillet 2025 et cet article est obsolète en raison du merge de la Pull Request <a href="https://github.com/doctrine/migrations/issues/1406" rel="noopener noreferrer">https://github.com/doctrine/migrations/issues/1406</a> ; désormais, l'exécution de <code translate="no">bin/console doctrine:migrations:up-to-date</code> prend en compte la configuration <code translate="no">schema_filter</code>.</p>
<h2 id="comment-fonctionnent-les-migrations-doctrine">Comment fonctionnent les migrations Doctrine</h2>
<p>Lors de la génération de la migration, Doctrine calcule un delta entre son mapping et le schéma actuel de la base de données. Avec ce delta en mémoire, il génère un <strong>fichier de migration</strong> avec deux méthodes principales :</p>
<ul>
<li><code translate="no">up</code> applique les commandes SQL pour combler l'écart entre le schéma actuel de la base de données et son mapping. Utilisé pour déployer les modifications du schéma de votre base de données.</li>
<li><code translate="no">down</code> permet d'annuler la migration avec les commandes SQL nécessaires pour « annuler » les modifications effectuées dans la méthode up. Utilisé pour revenir en arrière sur les modifications du schéma de votre base de données.</li>
</ul>
<h2 id="l-astuce-magique">L'astuce magique</h2>
<p>Il n'existe actuellement aucun moyen simple de vérifier si une migration n'a pas été générée. Si ce code était fusionné, le schéma de la base de données pourrait ne plus être synchronisé avec le mapping des entités, entraînant ainsi une erreur serveur.</p>
<p>Les mots-clés dans la description ci-dessus sont <strong>fichiers de migration</strong>. J'utilise le fait que l'exécution de la commande <code translate="no">bin/console doctrine:migration:diff</code> génère un nouveau fichier et échoue s'il n'y a aucun changement à appliquer.</p>
<p>Connaître la liste des fichiers existants avant l'exécution de cette commande, puis l'exécuter, permet de détecter qu'il y a des modifications qui n'ont pas été commitées dans un <strong>fichier de migration</strong> dans cette pull (ou merge) request.</p>
<h2 id="etapes-a-suivre">Étapes à suivre</h2>
<ol>
<li>Créez votre base de données</li>
<li>Exécutez vos migrations existantes</li>
<li>Puis exécutez l'étape de vérification des modifications manquantes (voir ci-dessous)</li>
</ol>
<h2 id="avantages">Avantages</h2>
<ol>
<li>Tester que vos migrations ne échouent pas</li>
<li>Assurer la cohérence du schéma de base de données avec le mapping de Doctrine</li>
</ol>
<h2 id="vous-voulez-l-extrait-de-code-n-est-ce-pas">Vous voulez l'extrait de code, n'est-ce pas ?</h2>
<p>Voici le code bash :</p>
<pre><code class="language-bash hljs bash" translate="no"><span class="hljs-meta">#!/bin/bash
</span>
<span class="hljs-built_in">set</span> -e
<span class="hljs-built_in">set</span> -o pipefail

<span class="hljs-comment"># run doctrine migration diff to check if there is a new migration file generated and check last exit code</span>
<span class="hljs-keyword">if</span> [[ -z $(bin/console doctrine:migrations:diff -n --quiet) ]]; <span class="hljs-keyword">then</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"Error ! bin/console doctrine:migration:diff found a new migration which must not be the case."</span>;
    <span class="hljs-comment"># cat last file (should be the newly generated one)</span>
    cat $(ls -Art migrations/*.php | tail -n 1);
    <span class="hljs-comment"># remove that file (just in case to comply with my paranoïac side)</span>
    rm -f $(ls -Art migrations/*.php | tail -n 1);
    <span class="hljs-built_in">exit</span> 1;
<span class="hljs-keyword">else</span>
    <span class="hljs-built_in">exit</span> 0;
<span class="hljs-keyword">fi</span>
</code></pre>
<p>Et voilà ! Vous pouvez désormais vous assurer que chaque pull (ou merge) request contient des migrations fonctionnelles, sans modification en attente laissée de côté !</p>
<h2 id="ok-mais-pourquoi-ne-pas-utiliser-bin-console-doctrine-schema-validate">Ok, mais pourquoi ne pas utiliser <code translate="no">bin/console doctrine:schema:validate</code> ?</h2>
<p>La raison est que le projet sur lequel nous travaillions utilisait la configuration <code translate="no">schema_filter</code> de Doctrine pour filtrer certaines tables dont nous ne voulions pas nous occuper (contrainte liée au projet).</p>
<p>Le problème avec <code translate="no">bin/console doctrine:schema:validate</code> est qu'il ne prenait pas en compte cette configuration, et signalait donc des modifications (tentant de supprimer toutes les tables normalement filtrées) sans rapport avec ce que nous voulions.</p>
<p>Un collègue m'a dit qu'il s'agit d'un problème connu qui pourrait être corrigé prochainement (<a href="https://github.com/doctrine/migrations/issues/1406" rel="noopener noreferrer">https://github.com/doctrine/migrations/issues/1406</a>).</p>
<p>Merci d'avoir lu cet article et n'hésitez pas à laisser vos commentaires si vous avez des questions !</p>]]>
    </content>
  </entry>
  <entry xml:lang="fr">
    <id>https://ktherage.github.io/fr/blog/2024/bash-and-curl-simple-http-call-performance-testing/</id>
    <title>Bash &amp; Curl : Test de performance simple d&#039;appels HTTP</title>
    <published>2024-01-19T00:00:00+00:00</published>
    <link href="https://ktherage.github.io/fr/blog/2024/bash-and-curl-simple-http-call-performance-testing/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>Les appels HTTP sont essentiels au fonctionnement du Web et sont critiques pour tout projet de développement web. Vous vous êtes peut-être demandé comment visualiser rapidement les performances de vos appels HTTP. Je vais vous montrer comment j'ai fait simplement avec Curl.</p>
<p><strong>TL;DR :</strong> Vous voulez juste le code (je comprends parfaitement 😉) ? Faites défiler jusqu'à l'extrait de code.</p>
<h1>Quel était mon besoin concernant les appels HTTP ?</h1>
<p>J'avais besoin d'avoir une idée rapide des performances du système de cache que j'avais mis en place sur un point de terminaison HTTP, et je voulais que ce soit rapide et simple.</p>
<p>Avec mes notions de Shell et ma connaissance de base de Curl (un petit cadeau d'un collègue : vous trouverez une antisèche Curl ici), je savais que je pouvais facilement exécuter cent fois le même appel HTTP et obtenir le temps total en résultat.</p>
<p>Cette solution est une solution courte et simple qui correspond à mes besoins, à savoir tester localement mon point de terminaison HTTP.
Si vous prévoyez de faire de véritables tests de performance/charge sur des serveurs réels comme la staging ou la production, alors jetez un œil à des outils comme <a href="https://jmeter.apache.org/" rel="noopener noreferrer">Apache JMeter</a>, <a href="https://gatling.io/" rel="noopener noreferrer">Gatling</a>, ou d'autres outils similaires.</p>
<h1>Comment Curl m'a aidé à tester mon appel HTTP ?</h1>
<p>J'ai donc ouvert mon terminal et exécuté :</p>
<pre><code class="language-bash hljs bash" translate="no"><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> {1..100}; <span class="hljs-keyword">do</span> curl <span class="hljs-string">'https://some-domain/some-uri/some-path?cache=false'</span> \
-H <span class="hljs-string">'cache-control: no-cache'</span> \
-H <span class="hljs-string">'pragma: no-cache'</span> \
--compressed \
--insecure -s -o /dev/null -w <span class="hljs-string">"%{time_total}s\n"</span>;
<span class="hljs-keyword">done</span>

<span class="hljs-comment"># Which printed :</span>
0.057703s
0.067895s
0.063033s
0.062455s
0.074864s
...</code></pre>
<p>Pour quelques explications, j'ai copié la requête envoyée par mon navigateur sous forme de requête Curl (cela se fait facilement sur la plupart des navigateurs, voir <a href="https://quickref.me/curl" rel="noopener noreferrer">ici</a>) et je l'ai encapsulée dans une boucle <code translate="no">for</code> qui exécute cet appel HTTP cent fois.</p>
<p><strong>Le seul changement que j'ai apporté à la requête Curl</strong> a été d'ajouter les options <code translate="no">-s</code> pour une sortie silencieuse, <code translate="no">-o /dev/null</code> pour éviter d'afficher le corps de la réponse et, le plus important, <code translate="no">-w "%{time_total}s\n"</code> qui permet de formater la sortie de Curl pour retourner le temps total. Vous pouvez trouver la liste complète des « Write out variables » disponibles <a href="https://everything.curl.dev/usingcurl/verbose/writeout.html#available-write-out-variables" rel="noopener noreferrer">ici</a>.</p>
<p>Et voilà 🎉 ! <strong>Vous pouvez avoir une idée rapide des performances uniquement avec les outils que vous utilisez peut-être déjà.</strong></p>
<p>J'espère que cela vous sera utile !</p>
<p>N'hésitez pas à laisser vos commentaires ou questions ci-dessous.</p>]]>
    </content>
  </entry>
</feed>
