<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Programmation-Fonctionnelle on Guillaume Delré</title><link>https://guillaumedelre.github.io/fr/tags/programmation-fonctionnelle/</link><description>Recent content in Programmation-Fonctionnelle on Guillaume Delré</description><generator>Hugo</generator><language>fr-FR</language><lastBuildDate>Sun, 04 Jan 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://guillaumedelre.github.io/fr/tags/programmation-fonctionnelle/index.xml" rel="self" type="application/rss+xml"/><item><title>PHP 8.5 : l'opérateur pipe, une bibliothèque URI et beaucoup de nettoyage</title><link>https://guillaumedelre.github.io/fr/2026/01/04/php-8.5-lop%C3%A9rateur-pipe-une-biblioth%C3%A8que-uri-et-beaucoup-de-nettoyage/</link><pubDate>Sun, 04 Jan 2026 00:00:00 +0000</pubDate><guid>https://guillaumedelre.github.io/fr/2026/01/04/php-8.5-lop%C3%A9rateur-pipe-une-biblioth%C3%A8que-uri-et-beaucoup-de-nettoyage/</guid><description>Part 11 of 11 in &amp;quot;Sorties PHP&amp;quot;: PHP 8.5 ajoute un opérateur pipe pour des pipelines fonctionnels lisibles et une classe URI native qui met fin au parsing fragile de strings.</description><category>php-releases</category><content:encoded><![CDATA[<p>PHP 8.5 est sorti le 20 novembre. Deux fonctionnalités définissent cette version : l&rsquo;opérateur pipe et l&rsquo;extension URI. Elles résolvent des problèmes différents, mais partagent la même motivation : rendre les opérations courantes moins maladroites à exprimer.</p>
<h2 id="lopérateur-pipe">L&rsquo;opérateur pipe</h2>
<p>Les pipelines fonctionnels en PHP ont toujours été un bazar. Enchaîner des transformations nécessitait soit d&rsquo;imbriquer les appels de fonctions à l&rsquo;envers, soit de les découper en variables intermédiaires :</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// avant — se lit de droite à gauche
</span></span></span><span style="display:flex;"><span>$result <span style="color:#f92672">=</span> <span style="color:#a6e22e">array_sum</span>(<span style="color:#a6e22e">array_map</span>(<span style="color:#e6db74">&#39;strlen&#39;</span>, <span style="color:#a6e22e">array_filter</span>($strings, <span style="color:#e6db74">&#39;strlen&#39;</span>)));
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// ou verbeux mais lisible
</span></span></span><span style="display:flex;"><span>$filtered   <span style="color:#f92672">=</span> <span style="color:#a6e22e">array_filter</span>($strings, <span style="color:#e6db74">&#39;strlen&#39;</span>);
</span></span><span style="display:flex;"><span>$lengths    <span style="color:#f92672">=</span> <span style="color:#a6e22e">array_map</span>(<span style="color:#e6db74">&#39;strlen&#39;</span>, $filtered);
</span></span><span style="display:flex;"><span>$result     <span style="color:#f92672">=</span> <span style="color:#a6e22e">array_sum</span>($lengths);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// après — se lit de gauche à droite
</span></span></span><span style="display:flex;"><span>$result <span style="color:#f92672">=</span> $strings
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">|&gt;</span> <span style="color:#a6e22e">array_filter</span>(<span style="color:#f92672">?</span>, <span style="color:#e6db74">&#39;strlen&#39;</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">|&gt;</span> <span style="color:#a6e22e">array_map</span>(<span style="color:#e6db74">&#39;strlen&#39;</span>, <span style="color:#f92672">?</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">|&gt;</span> <span style="color:#a6e22e">array_sum</span>(<span style="color:#f92672">?</span>);
</span></span></code></pre></div><p>L&rsquo;opérateur <code>|&gt;</code> passe la valeur de gauche dans l&rsquo;expression de droite. Le placeholder <code>?</code> marque où elle va. Les pipelines se lisent maintenant dans l&rsquo;ordre où les opérations se produisent : gauche à droite, haut en bas.</p>
<p>Ça se marie bien avec les callables de première classe de PHP 8.1. Les deux fonctionnalités se composent bien :</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$result <span style="color:#f92672">=</span> $input <span style="color:#f92672">|&gt;</span> <span style="color:#a6e22e">trim</span>(<span style="color:#f92672">...</span>) <span style="color:#f92672">|&gt;</span> <span style="color:#a6e22e">strtolower</span>(<span style="color:#f92672">...</span>) <span style="color:#f92672">|&gt;</span> $this<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">normalize</span>(<span style="color:#f92672">...</span>);
</span></span></code></pre></div><h2 id="lextension-uri">L&rsquo;extension URI</h2>
<p>Gérer les URIs en PHP a toujours signifié soit se tourner vers une bibliothèque tierce, soit assembler <code>parse_url()</code> (retourne un tableau, pas un objet), <code>http_build_query()</code>, et de la concaténation manuelle de strings.</p>
<p>La nouvelle extension <code>Uri</code> donne une vraie API orientée objet :</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$uri <span style="color:#f92672">=</span> <span style="color:#a6e22e">Uri\Uri</span><span style="color:#f92672">::</span><span style="color:#a6e22e">parse</span>(<span style="color:#e6db74">&#39;https://example.com/path?query=value#fragment&#39;</span>);
</span></span><span style="display:flex;"><span>$modified <span style="color:#f92672">=</span> $uri<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">withPath</span>(<span style="color:#e6db74">&#39;/new-path&#39;</span>)<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">withQuery</span>(<span style="color:#e6db74">&#39;key=val&#39;</span>);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">echo</span> $modified; <span style="color:#75715e">// https://example.com/new-path?key=val#fragment
</span></span></span></code></pre></div><p>Des objets-valeur immutables, un parsing conforme aux RFC, modifier des composants individuels sans parser et reconstruire la string entière. Attendu depuis longtemps.</p>
<h2 id="nodiscard">#[\NoDiscard]</h2>
<p>Un nouvel attribut qui génère un avertissement quand la valeur de retour est ignorée :</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">#[\NoDiscard(&#34;Use the returned collection, the original is unchanged&#34;)]
</span></span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">filter</span>(<span style="color:#a6e22e">callable</span> $fn)<span style="color:#f92672">:</span> <span style="color:#66d9ef">static</span> { <span style="color:#f92672">...</span> }
</span></span></code></pre></div><p>Utile pour les méthodes immutables où ignorer la valeur de retour est presque certainement un bug. Courant dans d&rsquo;autres langages depuis des années, maintenant en PHP où ça appartient.</p>
<h2 id="clone-with">clone with</h2>
<p>Cloner un objet avec des propriétés modifiées sans utiliser de property hooks ni une méthode <code>with()</code> personnalisée :</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$updated <span style="color:#f92672">=</span> <span style="color:#66d9ef">clone</span>($point) <span style="color:#a6e22e">with</span> { <span style="color:#a6e22e">x</span><span style="color:#f92672">:</span> <span style="color:#ae81ff">10</span>, <span style="color:#a6e22e">y</span><span style="color:#f92672">:</span> <span style="color:#ae81ff">20</span> };
</span></span></code></pre></div><p>Syntaxe propre pour un pattern que les objets readonly nécessitaient : on clone pour &ldquo;modifier&rdquo; puisque la mutation directe n&rsquo;est pas permise.</p>
<p>PHP 8.5 a une tendance fonctionnelle. L&rsquo;opérateur pipe et l&rsquo;extension URI ensemble rendent le code de transformation de données significativement plus lisible. Le langage continue dans une direction cohérente.</p>
<h2 id="les-closures-dans-les-expressions-constantes">Les closures dans les expressions constantes</h2>
<p>Une contrainte qui existait depuis PHP 5 : les expressions constantes (arguments d&rsquo;attributs, valeurs par défaut de propriétés, valeurs par défaut de paramètres, déclarations <code>const</code>) ne pouvaient pas contenir de closures ni de callables de première classe. 8.5 supprime ça.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">#[Validate(fn($v) =&gt; $v &gt; 0)]
</span></span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#a6e22e">int</span> $count <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#66d9ef">NORMALIZER</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">strtolower</span>(<span style="color:#f92672">...</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Config</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">__construct</span>(
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#a6e22e">readonly</span> <span style="color:#a6e22e">Closure</span> $transform <span style="color:#f92672">=</span> <span style="color:#a6e22e">trim</span>(<span style="color:#f92672">...</span>),
</span></span><span style="display:flex;"><span>    ) {}
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>C&rsquo;est la pièce manquante qui rend les attributs vraiment expressifs pour les règles de validation et de transformation. Avant 8.5, il fallait passer des noms de classes ou des références string aux attributs et laisser le framework les retrouver. Maintenant le callable vit directement dans l&rsquo;attribut.</p>
<h2 id="les-attributs-sur-les-constantes">Les attributs sur les constantes</h2>
<p>L&rsquo;attribut <code>#[\Deprecated]</code> de 8.4 ne pouvait pas être appliqué aux déclarations <code>const</code>. 8.5 ajoute le support des attributs pour les constantes en général :</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#66d9ef">OLD_LIMIT</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">100</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#[\Deprecated(&#39;Use RATE_LIMIT instead&#39;, since: &#39;3.0&#39;)]
</span></span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#66d9ef">API_TIMEOUT</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">30</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#66d9ef">RATE_LIMIT</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">60</span>;
</span></span></code></pre></div><p><code>ReflectionConstant</code>, une nouvelle classe de réflexion dans 8.5, expose <code>getAttributes()</code> pour que les outils puissent les lire. Combiné avec les closures dans les expressions constantes, les attributs sur les constantes deviennent une vraie couche de métadonnées pour les valeurs à la compilation.</p>
<h2 id="override-sétend-aux-propriétés">#[\Override] s&rsquo;étend aux propriétés</h2>
<p>PHP 8.3 a apporté <code>#[\Override]</code> pour les méthodes. 8.5 l&rsquo;étend aux propriétés :</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Base</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#a6e22e">string</span> $name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;default&#39;</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Derived</span> <span style="color:#66d9ef">extends</span> <span style="color:#a6e22e">Base</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">#[\Override]
</span></span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#a6e22e">string</span> $name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;derived&#39;</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Si la propriété n&rsquo;existe pas dans le parent, PHP lève une erreur. Particulièrement utile avec les property hooks de 8.4 : on peut maintenant signaler qu&rsquo;une propriété hookée surcharge intentionnellement celle d&rsquo;un parent.</p>
<h2 id="la-visibilité-asymétrique-statique">La visibilité asymétrique statique</h2>
<p>8.4 a introduit la visibilité asymétrique (<code>public private(set)</code>) pour les propriétés d&rsquo;instance. 8.5 l&rsquo;apporte aussi aux propriétés <code>static</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Registry</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">private</span>(<span style="color:#a6e22e">set</span>) <span style="color:#66d9ef">array</span> $items <span style="color:#f92672">=</span> [];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">register</span>(<span style="color:#a6e22e">string</span> $key, <span style="color:#a6e22e">mixed</span> $value)<span style="color:#f92672">:</span> <span style="color:#a6e22e">void</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">self</span><span style="color:#f92672">::</span>$items[$key] <span style="color:#f92672">=</span> $value;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">echo</span> <span style="color:#a6e22e">Registry</span><span style="color:#f92672">::</span>$items[<span style="color:#e6db74">&#39;foo&#39;</span>]; <span style="color:#75715e">// lisible
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">Registry</span><span style="color:#f92672">::</span>$items[<span style="color:#e6db74">&#39;bar&#39;</span>] <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>; <span style="color:#75715e">// Error: cannot write outside class
</span></span></span></code></pre></div><p>Pattern direct : exposer une collection statique en lecture, bloquer la mutation externe.</p>
<h2 id="la-promotion-de-constructeur-pour-les-propriétés-final">La promotion de constructeur pour les propriétés final</h2>
<p>La promotion de propriétés dans les constructeurs existe depuis PHP 8.0. Le modificateur <code>final</code> sur les propriétés promuées était la pièce manquante, 8.5 l&rsquo;ajoute :</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ValueObject</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">function</span> <span style="color:#a6e22e">__construct</span>(
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">final</span> <span style="color:#a6e22e">readonly</span> <span style="color:#a6e22e">string</span> $id,
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">final</span> <span style="color:#a6e22e">readonly</span> <span style="color:#a6e22e">string</span> $name,
</span></span><span style="display:flex;"><span>    ) {}
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Une sous-classe ne peut pas surcharger <code>$id</code> ni <code>$name</code> avec une propriété du même nom. La combinaison <code>final readonly</code> sur les propriétés promuées rend les objets-valeur aussi verrouillés que possible sans sceller la classe entière.</p>
<h2 id="les-casts-dans-les-expressions-constantes">Les casts dans les expressions constantes</h2>
<p>Autre lacune dans les expressions constantes : pas de casts de type. 8.5 les permet :</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#66d9ef">PRECISION</span> <span style="color:#f92672">=</span> (<span style="color:#a6e22e">int</span>) <span style="color:#ae81ff">3.7</span>;      <span style="color:#75715e">// 3
</span></span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#66d9ef">THRESHOLD</span> <span style="color:#f92672">=</span> (<span style="color:#a6e22e">float</span>) <span style="color:#e6db74">&#39;1.5&#39;</span>;  <span style="color:#75715e">// 1.5
</span></span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#66d9ef">FLAG</span> <span style="color:#f92672">=</span> (<span style="color:#a6e22e">bool</span>) <span style="color:#ae81ff">1</span>;            <span style="color:#75715e">// true
</span></span></span></code></pre></div><p>Ça semble mineur jusqu&rsquo;à ce qu&rsquo;on ait des constantes de configuration dérivées de variables d&rsquo;environnement qui nécessitent une coercition de type directement à la déclaration.</p>
<h2 id="les-erreurs-fatales-incluent-les-backtraces">Les erreurs fatales incluent les backtraces</h2>
<p>Avant 8.5, une erreur fatale (mémoire insuffisante, dépassement de pile, erreur de type dans certains contextes) produisait un message sans contexte sur où dans le code ça s&rsquo;est passé. Trouver la cause signifiait insérer des logs de debug et reproduire.</p>
<p>8.5 ajoute des backtraces à la stack aux messages d&rsquo;erreur fatale, dans le même format que les backtraces d&rsquo;exceptions. Une nouvelle directive INI, <code>fatal_error_backtraces</code>, contrôle le comportement. Elle est activée par défaut.</p>
<h2 id="array_first-et-array_last">array_first() et array_last()</h2>
<p>PHP avait <code>reset()</code> et <code>end()</code> pour accéder au premier et dernier élément d&rsquo;un tableau depuis PHP 3. Les deux mutent le pointeur interne du tableau (pas sûr à appeler sur une référence), et ils retournent <code>false</code> pour les tableaux vides d&rsquo;une façon indiscernable d&rsquo;une valeur <code>false</code> stockée.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$values <span style="color:#f92672">=</span> [<span style="color:#ae81ff">10</span>, <span style="color:#ae81ff">20</span>, <span style="color:#ae81ff">30</span>];
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$first <span style="color:#f92672">=</span> <span style="color:#a6e22e">array_first</span>($values);  <span style="color:#75715e">// 10
</span></span></span><span style="display:flex;"><span>$last  <span style="color:#f92672">=</span> <span style="color:#a6e22e">array_last</span>($values);   <span style="color:#75715e">// 30
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$first <span style="color:#f92672">=</span> <span style="color:#a6e22e">array_first</span>([]);       <span style="color:#75715e">// null
</span></span></span></code></pre></div><p>Les nouvelles fonctions retournent <code>null</code> pour les tableaux vides, ne touchent pas le pointeur interne, et fonctionnent sur n&rsquo;importe quelle expression de tableau sans avoir besoin d&rsquo;une variable. <code>reset($this-&gt;getItems())</code> était un avertissement de dépréciation en attente de se produire.</p>
<h2 id="get_error_handler-et-get_exception_handler">get_error_handler() et get_exception_handler()</h2>
<p>PHP a <code>set_error_handler()</code> et <code>set_exception_handler()</code>. Obtenir le handler courant nécessitait soit de le stocker soi-même avant de le définir, soit d&rsquo;appeler <code>set_error_handler(null)</code> et de capturer ce qui revenait, ce qui effaçait aussi le handler au passage.</p>
<p>8.5 ajoute :</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$current <span style="color:#f92672">=</span> <span style="color:#a6e22e">get_error_handler</span>();
</span></span><span style="display:flex;"><span>$current <span style="color:#f92672">=</span> <span style="color:#a6e22e">get_exception_handler</span>();
</span></span></code></pre></div><p>Pratique dans les chaînes de middleware où on veut envelopper le handler existant sans le perdre, ou dans les tests où on veut vérifier qu&rsquo;un handler a bien été installé.</p>
<h2 id="intllistformatter">IntlListFormatter</h2>
<p>Formater une liste avec les conjonctions appropriées à la locale nécessitait toujours un assemblage manuel de strings. 8.5 ajoute <code>IntlListFormatter</code> :</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span>$formatter <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">IntlListFormatter</span>(<span style="color:#e6db74">&#39;en_US&#39;</span>, <span style="color:#a6e22e">IntlListFormatter</span><span style="color:#f92672">::</span><span style="color:#a6e22e">TYPE_AND</span>);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">echo</span> $formatter<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">format</span>([<span style="color:#e6db74">&#39;apples&#39;</span>, <span style="color:#e6db74">&#39;oranges&#39;</span>, <span style="color:#e6db74">&#39;pears&#39;</span>]);
</span></span><span style="display:flex;"><span><span style="color:#75715e">// &#34;apples, oranges, and pears&#34;
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>$formatter <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> <span style="color:#a6e22e">IntlListFormatter</span>(<span style="color:#e6db74">&#39;fr_FR&#39;</span>, <span style="color:#a6e22e">IntlListFormatter</span><span style="color:#f92672">::</span><span style="color:#a6e22e">TYPE_OR</span>);
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">echo</span> $formatter<span style="color:#f92672">-&gt;</span><span style="color:#a6e22e">format</span>([<span style="color:#e6db74">&#39;rouge&#39;</span>, <span style="color:#e6db74">&#39;bleu&#39;</span>, <span style="color:#e6db74">&#39;vert&#39;</span>]);
</span></span><span style="display:flex;"><span><span style="color:#75715e">// &#34;rouge, bleu ou vert&#34;
</span></span></span></code></pre></div><p>La classe enveloppe le <code>ListFormatter</code> d&rsquo;ICU. Trois types : <code>TYPE_AND</code>, <code>TYPE_OR</code>, <code>TYPE_UNITS</code>. Les constantes de largeur contrôlent si on obtient &ldquo;et&rdquo; ou &ldquo;&amp;&rdquo;. Gestion de la virgule d&rsquo;Oxford, placement de conjonction spécifique à la locale, tout géré par ICU.</p>
<h2 id="filter_throw_on_failure-pour-filter_var">FILTER_THROW_ON_FAILURE pour filter_var()</h2>
<p><code>filter_var()</code> retourne <code>false</code> en cas d&rsquo;échec de validation, ce qui produit l&rsquo;ambiguïté classique <code>false vs null vs 0</code> quand on filtre des entrées non fiables. Un nouveau flag change ça :</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#66d9ef">try</span> {
</span></span><span style="display:flex;"><span>    $email <span style="color:#f92672">=</span> <span style="color:#a6e22e">filter_var</span>($input, <span style="color:#a6e22e">FILTER_VALIDATE_EMAIL</span>, <span style="color:#a6e22e">FILTER_THROW_ON_FAILURE</span>);
</span></span><span style="display:flex;"><span>} <span style="color:#66d9ef">catch</span> (<span style="color:#a6e22e">Filter\FilterFailedException</span> $e) {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// explicitement invalide, pas faussement false
</span></span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Les classes <code>Filter\FilterFailedException</code> et <code>Filter\FilterException</code> sont nouvelles dans 8.5. Le flag ne peut pas être combiné avec <code>FILTER_NULL_ON_FAILURE</code> : les comportements sont mutuellement exclusifs.</p>
<h2 id="les-dépréciations-qui-nettoient-des-années-de-dette-technique">Les dépréciations qui nettoient des années de dette technique</h2>
<p>L&rsquo;opérateur backtick (<code>`commande`</code> comme alias de <code>shell_exec()</code>) est déprécié. C&rsquo;est une syntaxe obscure qui surprend quiconque lit le code et est incohérente avec tous les autres appels de fonctions PHP.</p>
<p>Les noms de cast non canoniques (<code>(boolean)</code>, <code>(integer)</code>, <code>(double)</code>, <code>(binary)</code>) sont dépréciés au profit de leurs formes courtes : <code>(bool)</code>, <code>(int)</code>, <code>(float)</code>, <code>(string)</code>. Les formes longues sont non documentées depuis des années ; 8.5 commence la suppression formelle.</p>
<p>Les instructions <code>case</code> terminées par un point-virgule sont dépréciées :</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-php" data-lang="php"><span style="display:flex;"><span><span style="color:#75715e">// déprécié
</span></span></span><span style="display:flex;"><span><span style="color:#66d9ef">switch</span> ($x) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">case</span> <span style="color:#ae81ff">1</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">break</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// correct
</span></span></span><span style="display:flex;"><span><span style="color:#66d9ef">switch</span> ($x) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">case</span> <span style="color:#ae81ff">1</span><span style="color:#f92672">:</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">break</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>La forme avec point-virgule est syntaxiquement valide depuis PHP 4 mais personne ne l&rsquo;utilise intentionnellement. C&rsquo;est une faute de frappe que PHP acceptait.</p>
<p><code>__sleep()</code> et <code>__wakeup()</code> sont dépréciés au profit de <code>__serialize()</code> et <code>__unserialize()</code>, qui retournent et reçoivent des tableaux et se composent correctement avec l&rsquo;héritage. Les anciennes méthodes avaient une sémantique confuse autour de la visibilité des propriétés.</p>
<h2 id="max_memory_limit-plafonne-les-allocations-incontrôlées">max_memory_limit plafonne les allocations incontrôlées</h2>
<p>Une nouvelle directive INI accessible seulement au démarrage : <code>max_memory_limit</code>. Elle définit un plafond que <code>memory_limit</code> ne peut pas dépasser à l&rsquo;exécution. Si un script appelle <code>ini_set('memory_limit', '10G')</code> et que <code>max_memory_limit</code> est à <code>512M</code>, PHP avertit et plafonne la valeur.</p>
<p>Utile dans les environnements d&rsquo;hébergement partagé, ou partout où on veut s&rsquo;assurer qu&rsquo;un bug ou un payload malveillant ne peut pas convaincre PHP d&rsquo;élever sa propre limite et de dévorer toute la RAM de la machine.</p>
<h2 id="opcache-est-toujours-présent">Opcache est toujours présent</h2>
<p>Dans 8.5, Opcache est toujours compilé dans le binaire PHP et toujours chargé. L&rsquo;ancienne situation (Opcache comme extension chargeable qui pouvait ou non être présente selon la configuration de build) est révolue.</p>
<p>On peut toujours le désactiver : <code>opcache.enable=0</code> fonctionne bien. Ce qui change, c&rsquo;est la garantie que l&rsquo;API Opcache (<code>opcache_get_status()</code>, <code>opcache_invalidate()</code>, etc.) est toujours disponible, quelle que soit la façon dont PHP a été compilé. Tout code qui vérifie <code>extension_loaded('opcache')</code> avant d&rsquo;appeler les fonctions Opcache peut supprimer la vérification.</p>
]]></content:encoded></item></channel></rss>