<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="https://ktherage.github.io/xsl/atom.xsl" media="all"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <id>https://ktherage.github.io/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/blog/2024/atom.xml" rel="self" type="application/atom+xml" />
  <link href="https://ktherage.github.io/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="en">
    <id>https://ktherage.github.io/blog/2024/symfony-and-doctrine-migrations-validation-in-ci/</id>
    <title>Symfony &amp; Doctrine Migrations: Validation in CI</title>
    <published>2024-09-05T00:00:00+00:00</published>
    <link href="https://ktherage.github.io/blog/2024/symfony-and-doctrine-migrations-validation-in-ci/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>I had the opportunity to work on a project with a team that was relatively new to Doctrine migrations. To help them get used to it, and to discard the possibility of having pull (or merge) requests with changes to doctrine entities without generating a migration.</p>
<p>Here is how I did it. I hope you'll enjoy it!</p>
<h2 id="摩獣污業敲">Disclaimer</h2>
<p>We are the 10th of July 2025 now and this article is outdated due to the merge of the Pull Request <a href="https://github.com/doctrine/migrations/issues/1406" rel="noopener noreferrer">https://github.com/doctrine/migrations/issues/1406</a> and so running <code translate="no">bin/console doctrine:migrations:up-to-date</code> shall now take care of <code translate="no">schema_filter</code> configuration.</p>
<h2 id="how-doctrine-migrations-works">How Doctrine Migrations works</h2>
<p>When generating the migration, Doctrine will make a delta between its mapping and the current schema of the database. With this delta in "mind" (dare I say :wink:) it will generate a <strong>migration file</strong> with two main methods :</p>
<ul>
<li><code translate="no">up</code> applies the SQL commands to fill the gap between the current database schema and its mapping. Used to deploy changes in the schema of your database.</li>
<li><code translate="no">down</code> allows to revert the migration with the SQL commands needed to "negate" the changes made in the up method. Used to roll back changes in the schema of your database.</li>
</ul>
<h2 id="the-magic-trick">The magic trick</h2>
<p>There is currently no way to easily check if a migration has not been generated. Having this code merged could lead to a database schema being out of sync with your entity mapping and so resulting in a server error.</p>
<p>The keywords in the above description are <strong>migration files</strong>. I'll use the fact that, running the command bin/console doctrine:migration:diff will result in a newly generated file and will fail if there are no changes to apply.</p>
<p>Knowing the list of existing files before the execution of that command, and then running it, can let me know that there are changes that were not committed to a <strong>migration file</strong> in this pull (or merge) request.</p>
<h2 id="steps-to-do">Steps to do</h2>
<ol>
<li>Create your database</li>
<li>Run your existing migrations</li>
<li>Then run the step to check for missing changes (see below)</li>
</ol>
<h2 id="advantages">Advantages</h2>
<ol>
<li>Testing that your migrations does not fail</li>
<li>Ensure database schema consistency with Doctrine's mapping</li>
</ol>
<h2 id="you-want-the-code-snippet-right">You want the code snippet right!?</h2>
<p>Here is the bash code :</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>And that's it! You can now ensure that each pull (or merge) request has working migrations, with no pending changes left out of the migrations!</p>
<h2 id="ok-but-why-not-use-bin-console-doctrine-schema-validate">Ok but why not use <code translate="no">bin/console doctrine:schema:validate</code>?</h2>
<p>The reason was that the project we were working on was using doctrine's schema_filter configuration to filter out some tables we did not want to deal with (project-related inconvenience).</p>
<p>The problem with bin/console doctrine:schema:validate was that it did not take care of the configuration, and so was dumping changes (trying to delete all the "normally" filtered out tables) not related to what we wanted.</p>
<p>A colleague told me that this is a known issue that might be fixed soon (<a href="https://github.com/doctrine/migrations/issues/1406" rel="noopener noreferrer">https://github.com/doctrine/migrations/issues/1406</a>).</p>
<p>Thank you for reading this article and please leave your comments if you have any questions!</p>]]>
    </content>
  </entry>
  <entry xml:lang="en">
    <id>https://ktherage.github.io/blog/2024/bash-and-curl-simple-http-call-performance-testing/</id>
    <title>Bash &amp; Curl: Simple HTTP call performance testing</title>
    <published>2024-01-19T00:00:00+00:00</published>
    <link href="https://ktherage.github.io/blog/2024/bash-and-curl-simple-http-call-performance-testing/" rel="alternate" type="text/html" />
    <content type="html">
      <![CDATA[<p>HTTP calls are essential to the functioning of the web and are critical to any web development project. You may have wondered how to quickly see how your HTTP call is performing. I’ll show you how I did it easily using Curl.</p>
<p><strong>TL;DR:</strong> You just want the code (I perfectly understand that 😉)? Scroll to the piece of code.</p>
<h1>What was my need regarding HTTP calls?</h1>
<p>I needed to have a quick idea of how the application cache system I’ve placed on an HTTP endpoint was performing, and I wanted it to be quick and simple.</p>
<p>With my notions of Shell and basic knowledge of Curl (a small gift from a colleague: you can find a Curl cheatsheet here), I knew that I could easily run a hundred times the same HTTP call and get the total time as a result.</p>
<p>This solution is a simple short solution that fits my needs which was to locally test my HTTP endpoint.
If you plan to do real performance/load testing on real servers like staging or production ones then you shall take a look at tools like (<a href="https://jmeter.apache.org/)[Apache" rel="noopener noreferrer">https://jmeter.apache.org/)[Apache</a> JMeter], (<a href="https://gatling.io/)[Gatling" rel="noopener noreferrer">https://gatling.io/)[Gatling</a>], or other similar tools.</p>
<h1>How Curl helped me test my HTTP call?</h1>
<p>So I opened my terminal and ran:</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>For some explanations, I copied the request sent by my browser as a Curl request (this could be easily done on most browsers see (<a href="https://quickref.me/curl)[here" rel="noopener noreferrer">https://quickref.me/curl)[here</a>]) and wrapped it in a for loop which is running that HTTP call a hundred times.</p>
<p><strong>The only change I made to the Curl request</strong> was to add the options <code translate="no">-s</code> for a quiet output, <code translate="no">-o /dev/null</code> to avoid having the response body printed and the most important one <code translate="no">-w "%{time_total}s\n"</code> which allows me to format Curl’s output to return the total time. You can have a full list of available “Write out variables” (<a href="https://everything.curl.dev/usingcurl/verbose/writeout.html#available-write-out-variables)[here" rel="noopener noreferrer">https://everything.curl.dev/usingcurl/verbose/writeout.html#available-write-out-variables)[here</a>].</p>
<p>And that’s it 🎉 ! <strong>You can have a quick performance idea only with the tools you may already use.</strong></p>
<p>I hope you’ll find it helpful!</p>
<p>Please feel free to leave your comments or questions below.</p>]]>
    </content>
  </entry>
</feed>
