From c19676073732f6866affdd20c0dcd4d8926432cb Mon Sep 17 00:00:00 2001 From: Henri-Damien LAURENT <hdlaurent@afi-sa.net> Date: Wed, 9 Aug 2023 10:20:17 +0000 Subject: [PATCH] hotline#183443 : RSS : Fixing Atom Feed import --- VERSIONS_HOTLINE/183443 | 1 + library/Class/RssItem.php | 10 +- tests/fixtures/php.atom | 3485 +++++++++++++++++++++++++++ tests/library/Class/RssItemTest.php | 30 +- 4 files changed, 3520 insertions(+), 6 deletions(-) create mode 100644 VERSIONS_HOTLINE/183443 create mode 100644 tests/fixtures/php.atom diff --git a/VERSIONS_HOTLINE/183443 b/VERSIONS_HOTLINE/183443 new file mode 100644 index 00000000000..7ccbb592fda --- /dev/null +++ b/VERSIONS_HOTLINE/183443 @@ -0,0 +1 @@ + - correctif #183443 : RSS : Intégration des flux au format Atom et support de la balise content \ No newline at end of file diff --git a/library/Class/RssItem.php b/library/Class/RssItem.php index 8abbbb1ee9c..ebec00ae133 100644 --- a/library/Class/RssItem.php +++ b/library/Class/RssItem.php @@ -30,7 +30,7 @@ class Class_RssItem { protected string $_first_image_url; protected string $_date; - public function __construct(Zend_Feed_Entry_Rss $item) { + public function __construct(Zend_Feed_Entry_Abstract $item) { $this->_link = $item->link(); $this->_title = $item->title(); $this->_pub_date = trim($item->pubDate()); @@ -62,7 +62,7 @@ class Class_RssItem { } - protected function _extractDate(Zend_Feed_Entry_Rss $item) : string { + protected function _extractDate(Zend_Feed_Entry_Abstract $item) : string { $date = ''; if ($item_date = trim($item->pubDate())) { $locale = Zend_Registry::get('locale'); @@ -90,8 +90,10 @@ class Class_RssItem { } - protected function _getRawDescription(Zend_Feed_Entry_Rss $item) : string{ - $description = $item->description(); + protected function _getRawDescription(Zend_Feed_Entry_Abstract $item) : string{ + $description = $item->description() ?? $item->content(); + if (!$description) + return ''; if (is_array($description)) { $description = reset($description); } diff --git a/tests/fixtures/php.atom b/tests/fixtures/php.atom new file mode 100644 index 00000000000..da1d3794665 --- /dev/null +++ b/tests/fixtures/php.atom @@ -0,0 +1,3485 @@ +<?xml version="1.0" encoding="UTF-8"?> +<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom" xmlns:wfw="http://wellformedweb.org/CommentAPI/"> + <id>tag:linuxfr.org,2005:/sections/php</id> + <link rel="alternate" type="text/html" href="https://linuxfr.org/sections/php"/> + <link rel="self" type="application/atom+xml" href="https://linuxfr.org/sections/php.atom"/> + <title>LinuxFr.org : les dépêches de PHP</title> + <updated>2023-06-28T09:39:54+02:00</updated> + <icon>/favicon.png</icon> + <entry> + <id>tag:linuxfr.org,2005:News/41566</id> + <published>2023-06-28T09:39:54+02:00</published> + <updated>2023-06-28T09:39:54+02:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/wallabag-a-10-ans-et-sort-sa-version-2-6-pour-l-occasion"/> + <title>wallabag a 10 ans et sort sa version 2.6 pour l'occasion</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>wallabag est une application open source (licence MIT) qui sauvegarde des articles et vous permet de les lire plus tard, sur votre smartphone, votre tablette ou votre liseuse.</p> + +<p><img src="//img.linuxfr.org/img/68747470733a2f2f75706c6f61642e77696b696d656469612e6f72672f77696b6970656469612f636f6d6d6f6e732f7468756d622f622f62382f4c6f676f2d77616c6c616261672d7376672e7376672f32303270782d4c6f676f2d77616c6c616261672d7376672e7376672e706e67/202px-Logo-wallabag-svg.svg.png" alt="Logo Wallabag" title="Source : https://upload.wikimedia.org/wikipedia/commons/thumb/b/b8/Logo-wallabag-svg.svg/202px-Logo-wallabag-svg.svg.png"></p> + +<p>wallabag 🦘 fête ses 10 ans 🎂 ! Pour célébrer cet anniversaire, nous sommes heureux de vous annoncer la sortie de la version 2.6.0. (NdM: une version <a href="https://github.com/wallabag/wallabag/releases/tag/2.6.1">2.6.1</a> est parue pour corriger un problème de mise à jour). Nous avons travaillé sur celle-ci pendant un an et je souhaite remercier chaque personne ayant contribué. J’espère que vous allez adorer les nouvelles fonctionnalités et les bugs que nous avons corrigés. </p> + +<p>Dix ans pour un logiciel développé par des bénévoles et encore activement utilisé, je crois que nous commençons à arriver dans la cour des grands et je suis fier de l’équipe derrière ce beau projet. </p> +</div><ul><li>lien náµ’Â 1 : <a title="https://wallabag.org/news/20230620-new-release-wallabag-260/" hreflang="en" href="https://linuxfr.org/redirect/112370">wallabag 2.6.0</a></li><li>lien náµ’Â 2 : <a title="https://wallabag.org/" hreflang="en" href="https://linuxfr.org/redirect/112371">wallabag.org</a></li><li>lien náµ’Â 3 : <a title="https://github.com/wallabag/wallabag" hreflang="en" href="https://linuxfr.org/redirect/112372">Github wallabag</a></li><li>lien náµ’Â 4 : <a title="https://www.wallabag.it/fr" hreflang="fr" href="https://linuxfr.org/redirect/112373">service en ligne wallabag.it</a></li></ul><div><h3 id="toc-jetons-un-Å“il-sur-les-nouvelles-fonctionnalités">Jetons un Å“il sur les nouvelles fonctionnalités</h3> + +<p>Avec ses dix ans derrière elle, l’application web wallabag commençait à être un peu rouillée par endroit. C’est pourquoi nous avons fourni un gros effort pour améliorer beaucoup de choses techniques sous le capot. <br> +Énormément de ce travail a été réalisé par Yassine, nouveau contributeur sur le projet : merci à lui ! Grâce à lui, wallabag peut regarder de l’avant (pour les dix prochaines années ?). </p> +<h4 id="toc-la-possibilité-dajouter-des-étiquettes-en-masse">La possibilité d’ajouter des étiquettes en masse</h4> + +<p>Nous avons maintenant une très belle interface (sur la vue Carte) pour gérer massivement certaines actions. <br> +Ainsi, une case à cocher est disponible sur chaque carte et vous pouvez donc facilement archiver un article, le supprimer ou le marquer comme favori et aussi, ajouter des étiquettes. </p> + +<p>Merci Kevin et Simounet !</p> + +<p><img src="//img.linuxfr.org/img/68747470733a2f2f77616c6c616261672e6f72672f6e6577732f32303233303632302d6e65772d72656c656173652d77616c6c616261672d3236302f6d6173735f7461672e706e67/mass_tag.png" alt="La possibilité d’ajouter des étiquettes en masse" title="Source : https://wallabag.org/news/20230620-new-release-wallabag-260/mass_tag.png"></p> +<h4 id="toc-améliorer-lexpérience-utilisateur-lors-de-lajout-dune-url-depuis-linterface-web">Améliorer l’expérience utilisateur lors de l’ajout d’une URL depuis l’interface web</h4> + +<p>L’icône « + » dans la barre supérieure de l’interface n’est pas si grande que ça. Et lorsque vous souhaitez enregistrer plusieurs URL à la suite, ça peut être assez énervant de devoir cliquer précisément sur cette icône. </p> + +<p>Simounet a augmenté la zone de clic et il vous suffit simplement de cliquer partout sur la barre supérieure. </p> +<h4 id="toc-un-paramètre-pour-afficher-ou-masquer-les-miniatures-des-articles">Un paramètre pour afficher ou masquer les miniatures des articles</h4> + +<p>Lorsque votre connexion internet est lente ou que votre instance wallabag est hébergée sur un petit serveur, il peut être intéressant de ne pas charger l’ensemble des miniatures des articles. </p> + +<p>Un nouveau paramètre a fait son apparition : la page web chargée sera ainsi plus légère ! </p> + +<p><img src="//img.linuxfr.org/img/68747470733a2f2f77616c6c616261672e6f72672f6e6577732f32303233303632302d6e65772d72656c656173652d77616c6c616261672d3236302f696d675f6c6973745f6e6f5f707265766965772e706e67/img_list_no_preview.png" alt="Un paramètre pour afficher ou masquer les miniatures des articles" title="Source : https://wallabag.org/news/20230620-new-release-wallabag-260/img_list_no_preview.png"></p> + +<p><img src="//img.linuxfr.org/img/68747470733a2f2f77616c6c616261672e6f72672f6e6577732f32303233303632302d6e65772d72656c656173652d77616c6c616261672d3236302f696d675f636172645f6e6f5f707265766965772e706e67/img_card_no_preview.png" alt="Un paramètre pour afficher ou masquer les miniatures des articles" title="Source : https://wallabag.org/news/20230620-new-release-wallabag-260/img_card_no_preview.png"></p> +<h3 id="toc-mettre-à -jour-votre-instance">Mettre à jour votre instance</h3> + +<p>Depuis quelques versions, c’est relativement simple de mettre à jour votre wallabag : vous n’avez qu’à exécuter la commande <code>make update</code>. Si vous le souhaitez, vous trouverez plus d’informations sur <a href="https://wallabag.org/news/20230620-new-release-wallabag-260/">le billet de blog du projet</a>. </p> +<h3 id="toc-et-lavenir">Et l’avenir ?</h3> + +<p>Nous n’avons pas de feuille de route : nous travaillons sur les bugs et les fonctionnalités que nous souhaitons, jour après jour. Mais nous avons des dizaines et des dizaines d’idées : et vous aussi ! Alors rejoignez-nous, discutez avec nous, contribuez (pas nécessairement en codant, mais en rédigeant de la documentation ou en remontant des bugs). </p> + +<p>Pour rappel, si vous ne souhaitez pas héberger votre instance de wallabag, il est possible d’utiliser <a href="https://www.wallabag.it/fr">le service en ligne wallabag.it</a>. À ce sujet, les tarifs vont augmenter prochainement et <a href="https://nicolas.loeuillet.org/billets/2023/06/26/nouveaux-tarifs-pour-wallabagit/">j’explique les raisons dans ce billet</a>. </p> + +<p>Merci à toutes et tous d’utiliser et aimer wallabag : j’espère être encore là dans dix ans pour vous annoncer les nouvelles fonctionnalités implémentées dans ce beau projet ! </p> +</div><div><a href="https://linuxfr.org/news/wallabag-a-10-ans-et-sort-sa-version-2-6-pour-l-occasion.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/131705/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/wallabag-a-10-ans-et-sort-sa-version-2-6-pour-l-occasion#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>Nicolas LÅ“uillet</name> + </author> + <author> + <name>Benoît Sibaud</name> + </author> + <author> + <name>Florent Zara</name> + </author> + <author> + <name>gUI</name> + </author> + <author> + <name>Ysabeau</name> + </author> + <category term="PHP"/> + <category term="wallabag"/> + <category term="readitlater"/> + <category term="marque-page"/> + <category term="open_source"/> + <category term="entreprenariat"/> + <category term="saas"/> + <wfw:commentRss>https://linuxfr.org/nodes/131705/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/41352</id> + <published>2023-03-06T15:09:53+01:00</published> + <updated>2023-03-06T15:09:53+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/sortie-de-laravel-10"/> + <title>Sortie de Laravel 10</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>Laravel, l'un des frameworks PHP les plus en vogue en ce moment, est sorti en version 10 le 7 février 2023.<br> +Petit tour des nouveautés !</p> +</div><ul><li>lien náµ’Â 1 : <a title="https://laravel.com/" hreflang="en" href="https://linuxfr.org/redirect/111809">Site officiel</a></li><li>lien náµ’Â 2 : <a title="https://laravel-news.com/laravel-10" hreflang="en" href="https://linuxfr.org/redirect/111810">Annonce de la sortie</a></li></ul><div><h2 class="sommaire">Sommaire</h2> +<ul class="toc"> +<li> +<ul> +<li> +<a href="#toc-liste-non-exhaustive-des-nouveaut%C3%A9s">Liste (non-exhaustive) des nouveautés</a><ul> +<li><a href="#toc-fin-du-support-de-php-80">Fin du support de PHP 8.0</a></li> +<li><a href="#toc-d%C3%A9clarations-natives-et-typage-fort">Déclarations natives et typage fort</a></li> +<li><a href="#toc-les-r%C3%A8gles-de-validation-invokable-deviennent-le-fonctionnement-par-d%C3%A9faut">Les règles de validation <em>Invokable</em> deviennent le fonctionnement par défaut</a></li> +<li><a href="#toc-process-layer">Process Layer</a></li> +<li><a href="#toc-d%C3%A9tecter-les-tests-les-plus-lents">Détecter les tests les plus lents</a></li> +</ul> +</li> +<li><a href="#toc-fin-du-partenariat-avec-le-laravel-certification-program">Fin du partenariat avec le "Laravel Certification Program"</a></li> +<li><a href="#toc-laravel-pennant">Laravel Pennant</a></li> +<li><a href="#toc-laravel-11">Laravel 11 ?</a></li> +</ul> +</li> +</ul> +<p>Un an après la version 9, Laravel maintient son rythme de sortie (qui était autrefois d'une nouvelle version majeure tous les six mois).<br> +Avec, toutefois, une évolution qui se veut sans (trop de) révolution : les changements sont plus discrets, et nécessitent moins d'intervention ou d'attention lors de la montée de version, <a href="https://laravel.com/docs/10.x/upgrade#main-content">comme le montre d'ailleurs la taille de la page "Upgrade Guide"</a>, qui est <a href="https://twitter.com/PovilasKorop/status/1625766366572605441">l'une des plus petites de ces dernières années.</a></p> +<h3 id="toc-liste-non-exhaustive-des-nouveautés">Liste (non-exhaustive) des nouveautés</h3> +<h4 id="toc-fin-du-support-de-php-80">Fin du support de PHP 8.0</h4> + +<p>Avec cette nouvelle version vient l'abandon du support de la version 8.0 de PHP (qui est, de toute façon, dans sa phase "<em>security support</em>" <a href="https://www.php.net/supported-versions.php">depuis novembre 2022</a>). En effet, des nouveautés de PHP 8.1 et 8.2 (seules versions supportées, donc) sont utilisées par Laravel, telles que les <code>enum</code> et les propriétés de classes <em>readonly</em>.</p> +<h4 id="toc-déclarations-natives-et-typage-fort">Déclarations natives et typage fort</h4> + +<p>Désormais, Laravel aura beaucoup plus recours au typage et aux déclarations natives. Finis les commentaires en PHPDoc : place aux types partout !<br> +Ainsi, <a href="https://github.com/laravel/framework/blob/9.x/src/Illuminate/Foundation/Console/stubs/cast.inbound.stub">ce fichier stub de Laravel 9</a> :</p> + +<pre><code class="php"><span class="k">namespace</span> <span class="p">{{</span> <span class="k">namespace</span> <span class="p">}};</span> + +<span class="k">use</span> <span class="nx">Illuminate\Database\Eloquent\Model</span><span class="p">;</span> +<span class="k">use</span> <span class="nx">Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes</span><span class="p">;</span> + +<span class="k">class</span> <span class="err">{{ </span><span class="nc">class</span> <span class="p">}}</span> <span class="k">implements</span> <span class="nx">CastsInboundAttributes</span> +<span class="p">{</span> + <span class="sd">/**</span> +<span class="sd"> * Prepare the given value for storage.</span> +<span class="sd"> *</span> +<span class="sd"> * @param \Illuminate\Database\Eloquent\Model $model</span> +<span class="sd"> * @param string $key</span> +<span class="sd"> * @param mixed $value</span> +<span class="sd"> * @param array $attributes</span> +<span class="sd"> * @return mixed</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="k">function</span> <span class="nf">set</span><span class="p">(</span><span class="nv">$model</span><span class="p">,</span> <span class="nx">string</span> <span class="nv">$key</span><span class="p">,</span> <span class="nv">$value</span><span class="p">,</span> <span class="k">array</span> <span class="nv">$attributes</span><span class="p">)</span> + <span class="p">{</span> + <span class="k">return</span> <span class="nv">$value</span><span class="p">;</span> + <span class="p">}</span> +<span class="p">}</span></code></pre> + +<p><a href="https://github.com/laravel/framework/blob/be2ddb5c31b0b9ebc2738d9f37a9d4c960aa3199/src/Illuminate/Foundation/Console/stubs/cast.inbound.stub">devient désormais, en Laravel 10</a> :</p> + +<pre><code class="php"><span class="k">namespace</span> <span class="p">{{</span> <span class="k">namespace</span> <span class="p">}};</span> + +<span class="k">use</span> <span class="nx">Illuminate\Database\Eloquent\Model</span><span class="p">;</span> +<span class="k">use</span> <span class="nx">Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes</span><span class="p">;</span> + +<span class="k">class</span> <span class="err">{{ </span><span class="nc">class</span> <span class="p">}}</span> <span class="k">implements</span> <span class="nx">CastsInboundAttributes</span> +<span class="p">{</span> + <span class="sd">/**</span> +<span class="sd"> * Prepare the given value for storage.</span> +<span class="sd"> *</span> +<span class="sd"> * @param array&lt;string, mixed&gt; $attributes</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="k">function</span> <span class="nf">set</span><span class="p">(</span><span class="nx">Model</span> <span class="nv">$model</span><span class="p">,</span> <span class="nx">string</span> <span class="nv">$key</span><span class="p">,</span> <span class="nx">mixed</span> <span class="nv">$value</span><span class="p">,</span> <span class="k">array</span> <span class="nv">$attributes</span><span class="p">)</span><span class="o">:</span> <span class="nx">mixed</span> + <span class="p">{</span> + <span class="k">return</span> <span class="nv">$value</span><span class="p">;</span> + <span class="p">}</span> +<span class="p">}</span></code></pre> + +<p>Deux choses à noter :</p> + +<ul> +<li>La documentation est certes réduite (inutile de déclarer le type d'un paramètre en commentaire ET dans la signature de la méthode), mais il reste encore les informations concernant la structure des tableaux (en attendant qu'une future version de PHP permette de déclarer cela, comme en Java ?) ;</li> +<li>L'exemple ci-dessus provient d'un fichier stub de Laravel : ce sont des fichiers "à trous" (d'où le fait que ni le <em>namespace</em> ni le nom de la classe ne soient renseignés) utilisés lorsque le développeur veut créer une nouvelle classe (modèle, contrôleur, job, …) au sein de son projet. Le but ici étant de ne pas limiter au framework uniquement cette nouveauté mais, au contraire, de propager cet usage du typage dans le code du développeur.</li> +</ul> +<h4 id="toc-les-règles-de-validation-invokable-deviennent-le-fonctionnement-par-défaut">Les règles de validation <em>Invokable</em> deviennent le fonctionnement par défaut</h4> + +<p>Laravel fournit de base un ensemble de règles de validation (appelées <em>Rules</em>) pour vérifier que les données provenant des formulaires sont correctes. Il est néanmoins possible de créer les siennes.<br> +Jusqu'à présent, une telle rule devait être écrite ainsi :</p> + +<pre><code class="php"><span class="k">namespace</span> <span class="nx">App\Rules</span><span class="p">;</span> +<span class="nx"> </span> +<span class="k">use</span> <span class="nx">Illuminate\Contracts\Validation\Rule</span><span class="p">;</span> +<span class="nx"> </span> +<span class="k">class</span> <span class="nc">Uppercase</span> <span class="k">implements</span> <span class="nx">Rule</span> +<span class="p">{</span> + <span class="sd">/**</span> +<span class="sd"> * Determine if the validation rule passes.</span> +<span class="sd"> *</span> +<span class="sd"> * @param string $attribute</span> +<span class="sd"> * @param mixed $value</span> +<span class="sd"> * @return bool</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="k">function</span> <span class="nf">passes</span><span class="p">(</span><span class="nv">$attribute</span><span class="p">,</span> <span class="nv">$value</span><span class="p">)</span> + <span class="p">{</span> + <span class="k">return</span> <span class="nb">strtoupper</span><span class="p">(</span><span class="nv">$value</span><span class="p">)</span> <span class="o">===</span> <span class="nv">$value</span><span class="p">;</span> + <span class="p">}</span> +<span class="nx"> </span> + <span class="sd">/**</span> +<span class="sd"> * Get the validation error message.</span> +<span class="sd"> *</span> +<span class="sd"> * @return string</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="k">function</span> <span class="nf">message</span><span class="p">()</span> + <span class="p">{</span> + <span class="k">return</span> <span class="s1">'The :attribute must be uppercase.'</span><span class="p">;</span> + <span class="p">}</span> +<span class="p">}</span></code></pre> + +<p>À partir de Laravel 9, on peut la simplifier en utilisant la méthode magique <code>__invoke</code> de PHP, et donc écrire la même <em>rule</em> ainsi :</p> + +<pre><code class="php"><span class="k">namespace</span> <span class="nx">App\Rules</span><span class="p">;</span> +<span class="nx"> </span> +<span class="k">use</span> <span class="nx">Illuminate\Contracts\Validation\InvokableRule</span><span class="p">;</span> +<span class="nx"> </span> +<span class="k">class</span> <span class="nc">Uppercase</span> <span class="k">implements</span> <span class="nx">InvokableRule</span> +<span class="p">{</span> + <span class="sd">/**</span> +<span class="sd"> * Run the validation rule.</span> +<span class="sd"> *</span> +<span class="sd"> * @param string $attribute</span> +<span class="sd"> * @param mixed $value</span> +<span class="sd"> * @param \Closure $fail</span> +<span class="sd"> * @return void</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="k">function</span> <span class="fm">__invoke</span><span class="p">(</span><span class="nv">$attribute</span><span class="p">,</span> <span class="nv">$value</span><span class="p">,</span> <span class="nv">$fail</span><span class="p">)</span> + <span class="p">{</span> + <span class="k">if</span> <span class="p">(</span><span class="nb">strtoupper</span><span class="p">(</span><span class="nv">$value</span><span class="p">)</span> <span class="o">!==</span> <span class="nv">$value</span><span class="p">)</span> <span class="p">{</span> + <span class="nv">$fail</span><span class="p">(</span><span class="s1">'The :attribute must be uppercase.'</span><span class="p">);</span> + <span class="p">}</span> + <span class="p">}</span> +<span class="p">}</span></code></pre> + +<p>Néanmoins, pour que ce changement se fasse en douceur, il avait été décidé qu'il ne serait possible qu'en ajoutant le paramètre <code>--invokable</code> à la ligne de commande.<br> +Ainsi, pour obtenir la classe telle que dans l'exemple ci-dessus, il fallait faire : <code>php artisan make:rule Uppercase --invokable</code>.</p> + +<p>Depuis Laravel 10, ce comportement est désormais celui par défaut, et le paramètre optionnel a donc disparu de la ligne de commande indiqué précédemment.</p> +<h4 id="toc-process-layer">Process Layer</h4> + +<p>Déjà existant dans Symfony depuis longtemps, ce service-objet permet de lancer des processus en ligne de commande, et d’interagir avec (code d'erreur, valeur renvoyée, …). Comme souvent dans Laravel, l'usage d'une <em>fluent interface</em> y est très présent, permettant l'enchaînement d'appels de méthodes pour construire le processus voulu, avant de l'exécuter.</p> + +<pre><code class="php"><span class="k">use</span> <span class="nx">Illuminate\Support\Facades\Process</span><span class="p">;</span> + +<span class="nv">$result</span> <span class="o">=</span> <span class="nx">Process</span><span class="o">::</span><span class="na">run</span><span class="p">(</span><span class="s1">'ls -la'</span><span class="p">);</span> + +<span class="nv">$result</span><span class="o">-&gt;</span><span class="na">successful</span><span class="p">();</span> +<span class="nv">$result</span><span class="o">-&gt;</span><span class="na">failed</span><span class="p">();</span> +<span class="nv">$result</span><span class="o">-&gt;</span><span class="na">exitCode</span><span class="p">();</span> +<span class="nv">$result</span><span class="o">-&gt;</span><span class="na">output</span><span class="p">();</span> +<span class="nv">$result</span><span class="o">-&gt;</span><span class="na">errorOutput</span><span class="p">();</span> +<span class="nv">$result</span><span class="o">-&gt;</span><span class="na">throw</span><span class="p">();</span> +<span class="nv">$result</span><span class="o">-&gt;</span><span class="na">throwIf</span><span class="p">(</span><span class="nv">$condition</span><span class="p">);</span></code></pre> + +<p>À noter que, comme <a href="https://laravel.com/docs/10.x/http-client#main-content">le client HTTP</a> déjà présent dans Laravel, qui (comme son nom l'indique) permet d'interagir avec des appels HTTP(S), ce service est prévu pour pouvoir être "mocké", afin de faciliter l'écriture des tests.</p> +<h4 id="toc-détecter-les-tests-les-plus-lents">Détecter les tests les plus lents</h4> + +<p>Une nouvelle option <code>--profile</code> est apparue, pour faire ressortir les 10 tests les plus lents à l'exécution. Cela permet de détecter ceux qui auraient peut-être besoin d'être optimisés ou, parce que ça n'est pas toujours possible de les rendre plus rapides, de voir lesquels devraient être regroupés dans un lot de tests lents (qui ne seraient pas exécutés tout le temps, par exemple).</p> +<h3 id="toc-fin-du-partenariat-avec-le-laravel-certification-program">Fin du partenariat avec le "Laravel Certification Program"</h3> + +<p>Depuis plusieurs années, Laravel avait un partenariat avec un organisme extérieur, le reconnaissant comme seul autorisé à délivrer officiellement une certification de Laravel. <a href="https://twitter.com/taylorotwell/status/1610661365110247425">Depuis ce début d'année</a>, ce partenariat n'existe plus, et il n'y en a pas d'autres officiels pour autant (ce qui n'interdit pas quiconque de créer une certification Laravel).</p> +<h3 id="toc-laravel-pennant">Laravel Pennant</h3> + +<p>Il s'agit non pas d'une nouveauté de Laravel 10, mais d'un <em>first-class package</em> dont la sortie coïncide quasiment, et qui était très demandé et attendu par la communauté.</p> + +<p><a href="https://laravel.com/docs/10.x/pennant">Laravel Pennant</a> est un package officiel dont le but est de permettre de faire du <em>feature flag</em>. Il s'agit d'une technique d'ingénierie logicielle permettant d'activer/désactiver une fonctionnalité à tout ou partie des utilisateurs d'une application. Ainsi, on peut tester en production l'accueil qu'aura une nouvelle interface graphique, ne proposer dans un premier temps une fonctionnalité qu'à des utilisateurs triés sur le volet.</p> +<h3 id="toc-laravel-11">Laravel 11 ?</h3> + +<p>Bien que la prochaine version majeure de Laravel ne soit pas attendue avec début 2024, on sait déjà au moins une chose la concernant : <a href="https://github.com/laravel/framework/pull/45526">elle abandonnera le support de PHP 8.1</a> ! Seules les versions 8.2 et 8.3 (dont la sortie est prévue en novembre 2023) de PHP seront donc supportées.</p> +</div><div><a href="https://linuxfr.org/news/sortie-de-laravel-10.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/129952/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/sortie-de-laravel-10#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>windu.2b</name> + </author> + <author> + <name>Benoît Sibaud</name> + </author> + <author> + <name>Nÿco</name> + </author> + <author> + <name>Xavier Teyssier</name> + </author> + <author> + <name>bobble bubble</name> + </author> + <category term="PHP"/> + <category term="php"/> + <category term="laravel"/> + <wfw:commentRss>https://linuxfr.org/nodes/129952/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/41347</id> + <published>2023-01-09T09:52:55+01:00</published> + <updated>2023-01-09T09:52:55+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/sortie-de-prestashop-8-0-1"/> + <title>Sortie de PrestaShop 8.0.1</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>La version 8.0.1 de PrestaShop <a href="https://build.prestashop-project.org/news/2023/prestashop-8-0-1-maintenance-release/">vient d’être publiée</a>, la première version de correctifs pour PrestaShop 8.</p> + +<p>PrestaShop est un système de gestion de contenu (CMS) libre français de commerce en ligne, développé en PHP + MySQL et placé sous licence <a href="https://opensource.org/licenses/OSL-3.0">OSL v3</a>.</p> + +<p>La version 8.0.0 publiée en octobre 2022 est la première version majeure du projet depuis 2016, l’occasion de mettre à jour, simplifier et réorganiser de nombreux composants internes.</p> + +<p>Les <a href="https://www.prestashop-project.org/releases/prestashop80/">nouveautés</a> de cette version sont très nombreuses, on peut mentionner le support de PHP 8.0 et PHP 8.1, le support du format d’image <a href="https://fr.wikipedia.org/wiki/Scalable_Vector_Graphics">SVG</a>, l’usage de <a href="https://blog.dashlane.com/fr/le-nouveau-guide-zxcvbn-de-dashlane-vous-aide-a-creer-des-mots-de-passe-maitre-plus-complexes-et-vous-evite-les-prises-de-tete/">zxcvbn</a> pour sécuriser les mots de passe, une nouvelle page dédiée à la sécurité…</p> + +<p>La liste complète des nouveautés est disponible dans les <a href="https://build.prestashop-project.org/news/2022/prestashop-8-0-0-available/">notes de publication</a> (en anglais).</p> +</div><ul><li>lien náµ’Â 1 : <a title="https://www.prestashop-project.org/" hreflang="en" href="https://linuxfr.org/redirect/111558">Site du projet PrestaShop</a></li><li>lien náµ’Â 2 : <a title="https://build.prestashop-project.org/news/2022/prestashop-8-0-0-available/" hreflang="en" href="https://linuxfr.org/redirect/111559">Notes de publication de la version 8.0.0</a></li><li>lien náµ’Â 3 : <a title="https://build.prestashop-project.org/news/2023/prestashop-8-0-1-maintenance-release/" hreflang="en" href="https://linuxfr.org/redirect/111560">Notes de publication de la version 8.0.1</a></li></ul><div></div><div><a href="https://linuxfr.org/news/sortie-de-prestashop-8-0-1.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/129916/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/sortie-de-prestashop-8-0-1#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>Mathieu Ferment</name> + </author> + <author> + <name>Ysabeau</name> + </author> + <category term="PHP"/> + <category term="php"/> + <category term="cms"/> + <category term="symfony"/> + <category term="prestashop"/> + <wfw:commentRss>https://linuxfr.org/nodes/129916/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/40993</id> + <published>2022-12-05T19:36:21+01:00</published> + <updated>2022-12-06T09:58:52+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/php-sort-en-version-8-2"/> + <title>PHP sort en version 8.2</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>Après 3 Alpha, 3 Beta et 7 RC, et tout juste un an après la sortie de <a href="//linuxfr.org/news/la-version-8-1-de-php-et-creation-de-la-fondation-php">PHP 8.1</a>, PHP, le langage de programmation pour le Web le plus connu et le plus utilisé, devrait être disponible après-demain en version 8.2, la sortie initiale prévue au 24 novembre ayant été reportée.<br> +Petit tour (non-exhaustif) des nouveautés !</p> +</div><ul></ul><div><h2 class="sommaire">Sommaire</h2> +<ul class="toc"> +<li> +<ul> +<li> +<a href="#toc-nouvelles-fonctionnalit%C3%A9s">Nouvelles fonctionnalités</a><ul> +<li> +<a href="#toc-classes-en-lecture-seule-readonly-classes--rfc">Classes en lecture seule (<em>Readonly classes</em> : </a><a href="https://wiki.php.net/rfc/readonly_classes">RFC</a>)</li> +<li> +<a href="#toc-d%C3%A9pr%C3%A9ciation-des-propri%C3%A9t%C3%A9s-dynamiques-deprecate-dynamic-properties--rfc">Dépréciation des propriétés dynamiques (<em>Deprecate dynamic properties</em> : </a><a href="https://wiki.php.net/rfc/deprecate_dynamic_properties">RFC</a>)<ul> +<li><a href="#toc-ajouter-les-m%C3%A9thodes-magiques-__get-etou-__set-">Ajouter les méthodes magiques <code>__get</code> et/ou <code>__set</code> :</a></li> +<li><a href="#toc-utiliser-la-classe-stdclass-de-php-ou-en-h%C3%A9riter-">Utiliser la classe <code>stdClass</code> de PHP (ou en hériter) :</a></li> +<li><a href="#toc-ajouter-lattribut-allowdynamicproperties-%C3%A0-la-classe-">Ajouter l'attribut <code>#[AllowDynamicProperties]</code> à la classe :</a></li> +</ul> +</li> +<li> +<a href="#toc-nouveaux-types-de-retour--null-true-et-false-allow-null-and-false-as-stand-alone-types--rfc">Nouveaux types de retour : <code>null</code>, <code>true</code>, et <code>false</code> (<em>Allow null and false as stand-alone types</em> : </a><a href="https://wiki.php.net/rfc/null-false-standalone-types">RFC</a>)</li> +<li> +<a href="#toc-masquage-des-donn%C3%A9es-sensibles-dans-les-logs-redacting-parameters-in-back-traces--rfc">Masquage des données sensibles dans les logs (<em>Redacting parameters in back traces</em> : </a><a href="https://wiki.php.net/rfc/redact_parameters_in_back_traces">RFC</a>)</li> +<li> +<a href="#toc-constantes-dans-les-traits-rfc">Constantes dans les Traits (</a><a href="https://wiki.php.net/rfc/constants_in_traits">RFC</a>)</li> +<li> +<a href="#toc-retrait-du-support-de-libmysql-remove-support-for-libmysql-from-mysqli--rfc">Retrait du support de <em>libmysql</em> (<em>Remove support for libmysql from mysqli</em> : </a><a href="https://wiki.php.net/rfc/mysqli_support_for_libmysql">RFC</a>)</li> +<li><a href="#toc-liste-compl%C3%A8te-des-rfc">Liste complète des RFC</a></li> +</ul> +</li> +<li><a href="#toc-php-83">PHP 8.3</a></li> +</ul> +</li> +</ul> +<h3 id="toc-nouvelles-fonctionnalités">Nouvelles fonctionnalités</h3> +<h4 id="toc-classes-en-lecture-seule-readonly-classes--rfc">Classes en lecture seule (<em>Readonly classes</em> : <a href="https://wiki.php.net/rfc/readonly_classes">RFC</a>)</h4> + +<p>Après la possibilité offerte par PHP 8.1 d'ajouter le mot-clé <em><a href="https://wiki.php.net/rfc/readonly_properties_v2">readonly</a></em> aux propriétés d'une classe, c'est désormais directement sur la classe que l'on peut le faire.<br> +Cela permet d'alléger le code, en évitant la répétition du même mot-clé sur chacune des propriétés d'une classe (au risque de l'oublier sur l'une d'entre elles, notamment lorsque le code vient à évoluer), et de le rendre plus clair (quand la classe est <em>readonly</em>, toutes ses propriétés le sont forcément).<br> +Cela permet aussi d'empêcher la création de propriétés dynamiques (propriétés non déclarées dans le corps de la classe).<br> +Le principal usage est bien évidemment les classes DTO (<em>Data Transfer Object</em>), en permettant d'instancier des objets garantis immuables.</p> + +<p>On est donc passé de ceci, en PHP 8.0 :</p> + +<pre><code class="php"><span class="k">class</span> <span class="nc">Book</span> +<span class="p">{</span> + <span class="sd">/**</span> +<span class="sd"> * Constructeur PHP utilisant la nouvelle syntaxe "Constructor property promotion" apparue avec PHP 8.0</span> +<span class="sd"> * @see https://stitcher.io/blog/new-in-php-8#constructor-property-promotion-rfc</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="k">function</span> <span class="fm">__construct</span><span class="p">(</span> + <span class="k">private</span> <span class="nx">string</span> <span class="nv">$title</span><span class="p">,</span> + <span class="k">private</span> <span class="nx">string</span> <span class="nv">$author</span><span class="p">;</span> + <span class="p">)</span> + <span class="p">{}</span> + + <span class="k">public</span> <span class="k">function</span> <span class="nf">getTitle</span><span class="p">()</span><span class="o">:</span> <span class="nx">string</span> + <span class="p">{</span> + <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">title</span><span class="p">;</span> + <span class="p">}</span> + + <span class="k">public</span> <span class="k">function</span> <span class="nf">getAuthor</span><span class="p">()</span><span class="o">:</span> <span class="nx">string</span> + <span class="p">{</span> + <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">author</span><span class="p">;</span> + <span class="p">}</span> +<span class="p">}</span> + +<span class="nv">$book</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Book</span><span class="p">(</span><span class="s1">'A Game of Thrones'</span><span class="p">,</span> <span class="s1">'George R.R. Martin'</span><span class="p">);</span> +<span class="nv">$book</span><span class="o">-&gt;</span><span class="na">getAuthor</span><span class="p">();</span> <span class="c1">// "George R.R. Martin"</span></code></pre> + +<p>Puis ça, en PHP 8.1 :</p> + +<pre><code class="php"><span class="k">class</span> <span class="nc">Book</span> +<span class="p">{</span> + <span class="sd">/**</span> +<span class="sd"> * Les propriétés étant déclarées 'readonly', elles peuvent être déclarées 'public' sans risque.</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="k">function</span> <span class="fm">__construct</span><span class="p">(</span> + <span class="k">public</span> <span class="nx">readonly</span> <span class="nx">string</span> <span class="nv">$title</span><span class="p">,</span> + <span class="k">public</span> <span class="nx">readonly</span> <span class="nx">string</span> <span class="nv">$author</span><span class="p">,</span> + <span class="p">)</span> + <span class="p">{}</span> + + <span class="c1">// Suppression des getters, devenus inutiles</span> +<span class="p">}</span> + +<span class="nv">$book</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Book</span><span class="p">(</span><span class="s1">'A Game of Thrones'</span><span class="p">,</span> <span class="s1">'George R.R. Martin'</span><span class="p">);</span> + +<span class="c1">// On peut désormais appeler directement la propriété, sans craindre de la modifier</span> +<span class="k">echo</span> <span class="nv">$book</span><span class="o">-&gt;</span><span class="na">author</span><span class="p">;</span> <span class="c1">// "George R.R. Martin"</span> +<span class="nv">$book</span><span class="o">-&gt;</span><span class="na">author</span> <span class="o">=</span> <span class="s1">'J.R.R. Tolkien'</span><span class="p">;</span> <span class="c1">// Error: Cannot modify readonly property Book::$author</span></code></pre> + +<p>Pour arriver finalement à ceci, en PHP 8.2 :</p> + +<pre><code class="php"><span class="c1">// utilisation du mot-clé 'readonly' sur la classe directement</span> +<span class="nx">readonly</span> <span class="k">class</span> <span class="nc">Book</span> +<span class="p">{</span> + <span class="sd">/**</span> +<span class="sd"> * La classe étant déclarée 'readonly', les propriétés peuvent être déclarées 'public' sans risque,</span> +<span class="sd"> * sans pour autant avoir encore besoin de les déclarer 'readonly' une à une.</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="k">function</span> <span class="fm">__construct</span><span class="p">(</span> + <span class="k">public</span> <span class="nx">string</span> <span class="nv">$title</span><span class="p">,</span> + <span class="k">public</span> <span class="nx">string</span> <span class="nv">$author</span><span class="p">,</span> + <span class="p">)</span> + <span class="p">{}</span> + + <span class="c1">// Suppression des getters, devenus inutiles</span> +<span class="p">}</span> + +<span class="nv">$book</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Book</span><span class="p">(</span><span class="s1">'A Game of Thrones'</span><span class="p">,</span> <span class="s1">'George R.R. Martin'</span><span class="p">);</span> +<span class="k">echo</span> <span class="nv">$book</span><span class="o">-&gt;</span><span class="na">author</span><span class="p">;</span> <span class="c1">// "George R.R. Martin"</span> +<span class="nv">$book</span><span class="o">-&gt;</span><span class="na">author</span> <span class="o">=</span> <span class="s1">'J.R.R. Tolkien'</span><span class="p">;</span> <span class="c1">// Error: Cannot modify readonly property Book::$author</span> +<span class="nv">$book</span><span class="o">-&gt;</span><span class="na">genre</span> <span class="o">=</span> <span class="s1">'Epic fantasy'</span><span class="p">;</span> <span class="c1">// Uncaught Error: Cannot create dynamic property Book::$genre</span></code></pre> + +<p><strong>ATTENTION !</strong><br> +Un objet <em>readonly</em> n'est pas forcément immuable ! Si un objet A a une référence vers un objet B (composition), le fait que cette référence soit <em>readonly</em> garantit uniquement que A ne pointera jamais vers C à la place de B. Mais cela n'empêche pas pour autant les propriétés de B de pouvoir changer dans le temps (si elles ne sont pas elles-mêmes <em>readonly</em>, évidemment).</p> +<h4 id="toc-dépréciation-des-propriétés-dynamiques-deprecate-dynamic-properties--rfc">Dépréciation des propriétés dynamiques (<em>Deprecate dynamic properties</em> : <a href="https://wiki.php.net/rfc/deprecate_dynamic_properties">RFC</a>)</h4> + +<p>Dans la continuité du refus d'ajouter une propriété dynamique sur une classe <em>readonly</em>, une Deprecated est désormais levée lorsqu'on fait appel à une propriété inexistante au sein de la classe/de l'objet.<br> +Ex :</p> + +<pre><code class="php"><span class="k">class</span> <span class="nc">User</span> <span class="p">{</span> + <span class="k">public</span> <span class="nv">$name</span><span class="p">;</span> +<span class="p">}</span> +<span class="nv">$user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">User</span><span class="p">;</span> + +<span class="c1">// Assigns declared property User::$name</span> +<span class="nv">$user</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">=</span> <span class="s2">"foo"</span><span class="p">;</span> + +<span class="c1">// Oops, a typo:</span> +<span class="nv">$user</span><span class="o">-&gt;</span><span class="na">nane</span> <span class="o">=</span> <span class="s2">"foo"</span><span class="p">;</span> +<span class="c1">// PHP &lt;= 8.1: Silently creates dynamic $user-&gt;nane property.</span> +<span class="c1">// PHP 8.2: "Deprecated: Creation of dynamic property User::$nane is deprecated"</span> +<span class="c1">// PHP 9.0: Throws Error exception.</span></code></pre> + +<p>Néanmoins, les cas où il faut pouvoir continuer à créer des propriétés dynamiques ont été pris en compte. Pour cela, 3 solutions :</p> +<h5 id="toc-ajouter-les-méthodes-magiques-__get-etou-__set-">Ajouter les méthodes magiques <code>__get</code> et/ou <code>__set</code> :</h5> + +<pre><code class="php"><span class="k">class</span> <span class="nc">Post</span> +<span class="p">{</span> + <span class="k">private</span> <span class="k">array</span> <span class="nv">$properties</span> <span class="o">=</span> <span class="p">[];</span> + + <span class="k">public</span> <span class="k">function</span> <span class="fm">__set</span><span class="p">(</span><span class="nx">string</span> <span class="nv">$name</span><span class="p">,</span> <span class="nx">mixed</span> <span class="nv">$value</span><span class="p">)</span><span class="o">:</span> <span class="nx">void</span> + <span class="p">{</span> + <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">properties</span><span class="p">[</span><span class="nv">$name</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$value</span><span class="p">;</span> + <span class="p">}</span> + + <span class="c1">// …</span> +<span class="p">}</span> + +<span class="c1">// …</span> + +<span class="nv">$post</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">=</span> <span class="s1">'Name'</span><span class="p">;</span> <span class="c1">// Pas de message de dépréciation</span></code></pre> +<h5 id="toc-utiliser-la-classe-stdclass-de-php-ou-en-hériter-">Utiliser la classe <code>stdClass</code> de PHP (ou en hériter) :</h5> + +<pre><code class="php"><span class="cm">/*</span> +<span class="cm"> * Ne faites pas ça : ça marche mais c'est une solution fortement déconseillée !</span> +<span class="cm"> */</span> +<span class="k">class</span> <span class="nc">Post</span> <span class="k">extends</span> <span class="k">stdClass</span> +<span class="p">{</span> +<span class="p">}</span> + +<span class="nv">$post</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Post</span><span class="p">();</span> + +<span class="nv">$post</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">=</span> <span class="s1">'Name'</span><span class="p">;</span> <span class="c1">// Pas de message de dépréciation</span></code></pre> +<h5 id="toc-ajouter-lattribut-allowdynamicproperties-à -la-classe-">Ajouter l'attribut <code>#[AllowDynamicProperties]</code> à la classe :</h5> + +<pre><code class="php"><span class="cm">/*</span> +<span class="cm"> * Solution la plus recommandée pour gérer le code legacy, car l'impact est nul.</span> +<span class="cm"> */</span> +<span class="c1">#[AllowDynamicProperties]</span> +<span class="k">class</span> <span class="nc">Post</span> +<span class="p">{</span> +<span class="p">}</span> + +<span class="nv">$post</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Post</span><span class="p">();</span> + +<span class="nv">$post</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">=</span> <span class="s1">'Name'</span><span class="p">;</span> <span class="c1">// Pas de message de dépréciation</span></code></pre> + +<p>À terme (PHP 9), le message passera de <code>Deprecated</code> à la levée d'une exception de type <code>Error</code>.</p> +<h4 id="toc-nouveaux-types-de-retour--null-true-et-false-allow-null-and-false-as-stand-alone-types--rfc">Nouveaux types de retour : <code>null</code>, <code>true</code>, et <code>false</code> (<em>Allow null and false as stand-alone types</em> : <a href="https://wiki.php.net/rfc/null-false-standalone-types">RFC</a>)</h4> + +<p>Il est désormais possible d'indiquer que le type de retour d'une fonction/méthode est <code>null</code>, <code>true</code>, ou <code>false</code>. C'est notamment utile pour les fonctions de PHP qui renvoient une valeur, ou <code>false</code> si un problème a été rencontré.<br> +Par exemple :</p> + +<pre><code class="php"><span class="cm">/*</span> +<span class="cm"> * Trouve la première occurrence de $needle dans $haystack</span> +<span class="cm"> * @return la portion de la chaîne, ou false si needle n'est pas trouvé.</span> +<span class="cm"> */</span> +<span class="nb">strstr</span><span class="p">(</span><span class="nx">string</span> <span class="nv">$haystack</span><span class="p">,</span> <span class="nx">string</span> <span class="nv">$needle</span><span class="p">,</span> <span class="nx">bool</span> <span class="nv">$before_needle</span> <span class="o">=</span> <span class="k">false</span><span class="p">)</span><span class="o">:</span> <span class="nx">string</span><span class="o">|</span><span class="k">false</span></code></pre> +<h4 id="toc-masquage-des-données-sensibles-dans-les-logs-redacting-parameters-in-back-traces--rfc">Masquage des données sensibles dans les logs (<em>Redacting parameters in back traces</em> : <a href="https://wiki.php.net/rfc/redact_parameters_in_back_traces">RFC</a>)</h4> + +<p>Il est désormais possible d'indiquer que la valeur d'un paramètre ne doit jamais se retrouver dans des traces d'erreurs. C'est évidemment très utile pour éviter qu'un mot de passe ne finisse en clair dans un fichier de logs.<br> +Pour cela, il faut ajouter un attribut à la variable concernée, comme ceci :</p> + +<pre><code class="php"><span class="k">function</span> <span class="nf">test</span><span class="p">(</span> + <span class="nv">$foo</span> <span class="o">=</span> <span class="k">null</span><span class="p">,</span> + <span class="c1">#[\SensitiveParameter] $bar = null,</span> + <span class="nv">$baz</span> <span class="o">=</span> <span class="k">null</span> +<span class="p">)</span> <span class="p">{</span> + <span class="k">throw</span> <span class="k">new</span> <span class="nx">\Exception</span><span class="p">(</span><span class="s1">'Error'</span><span class="p">);</span> +<span class="p">}</span> +<span class="nx">test</span><span class="p">(</span><span class="nx">baz</span><span class="o">:</span> <span class="s1">'baz'</span><span class="p">);</span> +<span class="cm">/*</span> +<span class="cm">Fatal error: Uncaught Exception: Error in test.php:8</span> +<span class="cm">Stack trace:</span> +<span class="cm">#0 test.php(11): test(NULL, Object(SensitiveParameterValue), 'baz')</span> +<span class="cm">#1 {main}</span> +<span class="cm"> thrown in test.php on line 8</span> +<span class="cm">*/</span></code></pre> + +<p>Comme on le voit dans la trace d'erreur, la valeur du paramètre en entrée <code>$bar</code> a été remplacée par <code>Object(SensitiveParameterValue)</code>.</p> +<h4 id="toc-constantes-dans-les-traits-rfc">Constantes dans les Traits (<a href="https://wiki.php.net/rfc/constants_in_traits">RFC</a>)</h4> + +<p>Il est désormais possible d'inclure des constantes au sein d'un Trait.<br> +La syntaxe suivante est donc désormais valide :</p> + +<pre><code class="php"><span class="k">trait</span> <span class="nx">T</span> <span class="p">{</span> + <span class="k">public</span> <span class="k">const</span> <span class="no">CONSTANT</span> <span class="o">=</span> <span class="mi">42</span><span class="p">;</span> + + <span class="k">public</span> <span class="k">function</span> <span class="nf">doSomething</span><span class="p">()</span><span class="o">:</span> <span class="nx">void</span> <span class="p">{</span> + <span class="c1">// Fatal Error</span> + <span class="k">echo</span> <span class="nx">T</span><span class="o">::</span><span class="na">CONSTANT</span><span class="p">;</span> + + <span class="c1">// OK</span> + <span class="k">echo</span> <span class="nx">self</span><span class="o">::</span><span class="na">CONSTANT</span><span class="p">;</span> + <span class="k">echo</span> <span class="k">static</span><span class="o">::</span><span class="na">CONSTANT</span><span class="p">;</span> + <span class="k">echo</span> <span class="nv">$this</span><span class="o">::</span><span class="na">CONSTANT</span><span class="p">;</span> + <span class="p">}</span> +<span class="p">}</span></code></pre> +<h4 id="toc-retrait-du-support-de-libmysql-remove-support-for-libmysql-from-mysqli--rfc">Retrait du support de <em>libmysql</em> (<em>Remove support for libmysql from mysqli</em> : <a href="https://wiki.php.net/rfc/mysqli_support_for_libmysql">RFC</a>)</h4> + +<p>Le support de la bibliothèque <em>libmysql</em> a été retiré de PHP, pour ne conserver désormais que le support de <em>mysqlnd</em>. Si vous utilisez PHP avec MySQL (que ce soit avec l'extension PHP <em>mysqli</em> ou avec <em>PDO_mysql</em>), vous ne devriez même pas vous en rendre compte : <em>mysqlnd</em> est utilisée par défaut depuis… PHP 5.4 (sortie en 2012).</p> +<h4 id="toc-liste-complète-des-rfc">Liste complète des RFC</h4> + +<p>La liste complète des apports de cette nouvelle version est <a href="https://wiki.php.net/rfc#php_82">consultable ici</a>.</p> +<h3 id="toc-php-83">PHP 8.3</h3> + +<p>La prochaine version sera la 8.3, <a href="https://wiki.php.net/todo/php83">prévue (pour l'instant) pour novembre 2023</a>.<br> +La liste des nouvelles fonctionnalités n'est évidemment pas encore arrêtée, mais on peut d'ores et déjà <a href="https://wiki.php.net/rfc#php_83">la retrouver ici</a>.</p> +</div><div><a href="https://linuxfr.org/news/php-sort-en-version-8-2.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/127613/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/php-sort-en-version-8-2#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>windu.2b</name> + </author> + <author> + <name>Ellendhel</name> + </author> + <author> + <name>vmagnin</name> + </author> + <author> + <name>bobble bubble</name> + </author> + <author> + <name>Pierre Jarillon</name> + </author> + <author> + <name>Yves Bourguignon</name> + </author> + <author> + <name>Nils Ratusznik</name> + </author> + <author> + <name>palm123</name> + </author> + <category term="PHP"/> + <category term="php"/> + <wfw:commentRss>https://linuxfr.org/nodes/127613/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/41245</id> + <published>2022-10-27T08:49:35+02:00</published> + <updated>2022-10-29T22:11:29+02:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/karadav-un-serveur-webdav-leger-compatible-avec-les-applications-owncloud-et-nextcloud"/> + <title>KaraDAV, un serveur WebDAV léger, compatible avec les applications ownCloud et NextCloud</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>KaraDAV est un nouveau serveur de fichiers WebDAV simple, léger, rapide et très fonctionnel, sous licence <br> +AGPLv3.</p> + +<p>Il a plusieurs particularités :</p> + +<ul> +<li>compatible avec les clients mobile et desktop ownCloud et NextCloud</li> +<li>interface web avec <a href="//linuxfr.org/news/webdav-manager-un-client-webdav-ultra-leger-en-js">WebDAV Manager.js</a> +</li> +<li>édition de documents via un navigateur web, via Collabora ou OnlyOffice</li> +</ul> +</div><ul><li>lien náµ’Â 1 : <a title="https://github.com/kd2org/karadav/" hreflang="en" href="https://linuxfr.org/redirect/111224">KaraDAV</a></li><li>lien náµ’Â 2 : <a title="https://raw.githubusercontent.com/kd2org/karadav/main/doc/scr_index.jpg" hreflang="fr" href="https://linuxfr.org/redirect/111225">Capture d&#39;écran de l&#39;interface utilisateur</a></li><li>lien náµ’Â 3 : <a title="https://linuxfr.org/news/webdav-manager-un-client-webdav-ultra-leger-en-js" hreflang="fr" href="https://linuxfr.org/redirect/111226">WebDAV Manager, un client WebDAV ultra-léger en JS</a></li></ul><div><p>Je vous ai récemment présenté <a href="//linuxfr.org/news/webdav-manager-un-client-webdav-ultra-leger-en-js">WebDAV Manager</a>, un client WebDAV léger en JS permettant de gérer les fichiers depuis son navigateur, avec envoi de fichiers depuis le navigateur (par copier/coller, par glisser-déposer), la prévisualisation du Markdown lors de l'édition de fichier texte, l'affichage des images, vidéos, audio, texte et MarkDown, etc.</p> + +<p>Et bien voici maintenant le serveur WebDAV qui va avec.</p> + +<p>Ce serveur a été d'abord développé pour tester la bibliothèque WebDAV développée pour <a href="https://garradin.eu/">Garradin</a>, mais au fil du développement il est apparu qu'il pouvait avoir une utilité seul, pour se faire un stockage "cloud" auto-hébergé simple, léger, mais très fonctionnel.</p> + +<p>En effet ce serveur a comme particularité d'implémenter une partie de l'API serveur de NextCloud et ownCloud, permettant aux clients mobile et de bureau de NextCloud et ownCloud de fonctionner, comme s'ils avaient affaire à un serveur NC/OC habituel, sauf que celui-ci est bien plus léger :)</p> + +<p>La raison de l'implémentation de cette compatibilité est simple :</p> + +<ul> +<li>Sur Android il n'existe pas de client WebDAV libre et simple à utiliser</li> +<li>Sur PC, le client OC/NC propose la synchro à deux directions (les fichiers sont téléchargés sur l'ordinateur, on peut les modifier localement sans être connecté, et ils sont ensuite synchronisés quand on se reconnecte), aucun autre client WebDAV libre ne propose cette fonctionnalité (à ma connaissance). En plus cette fonctionnalité est aussi disponible en ligne de commande, permettant de faire une synchro "invisible" en arrière plan via une crontab par exemple.</li> +</ul> + +<p>L'autre particularité c'est qu'il implémente également aussi un serveur WOPI, permettant d'éditer les fichiers LibreOffice/MS Office directement dans le navigateur en utilisant par exemple Collabora ou OnlyOffice.</p> + +<p>Ainsi pour un usage personnel on retrouve la plupart des fonctionnalités offertes par NC/OC :</p> + +<ul> +<li>gestion de fichiers depuis un navigateur web ;</li> +<li>éditions de documents depuis un navigateur web ;</li> +<li>accès aux fichiers avec n'importe quel client WebDAV ;</li> +<li>synchronisation des fichiers en local.</li> +</ul> + +<p>Le tout dans très peu de code, et avec une grande rapidité :</p> + +<ul> +<li>KaraDAV est jusqu'à 22 fois plus rapide que NextCloud sur le transfert de fichiers ;</li> +<li>KaraDAV fait 250 Ko de code, contre plus de 500 Mo pour NextCloud ;</li> +<li>ne nécessite pas de serveur de base de données.</li> +</ul> + +<p>KaraDAV n'a bien sûr pas pour vocation de remplacer OC ou NC, qui offrent bien d'autres possibilités, mais propose simplement un serveur de fichiers WebDAV déjà très complet pour une utilisation personnelle ou pour une petite structure.</p> +</div><div><a href="https://linuxfr.org/news/karadav-un-serveur-webdav-leger-compatible-avec-les-applications-owncloud-et-nextcloud.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/129106/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/karadav-un-serveur-webdav-leger-compatible-avec-les-applications-owncloud-et-nextcloud#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>BohwaZ</name> + </author> + <author> + <name>Xavier Teyssier</name> + </author> + <author> + <name>palm123</name> + </author> + <author> + <name>Benoît Sibaud</name> + </author> + <category term="PHP"/> + <category term="webdav"/> + <category term="karadav"/> + <category term="php"/> + <category term="sqlite"/> + <category term="nextcloud"/> + <category term="owncloud"/> + <category term="cloud_personnel"/> + <wfw:commentRss>https://linuxfr.org/nodes/129106/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/40833</id> + <published>2022-02-11T19:56:51+01:00</published> + <updated>2022-02-11T19:56:51+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/laravel-9-est-sorti"/> + <title>Laravel 9 est sorti</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>Laravel, un framework PHP déjà évoqué dans ces colonnes, est sorti en version 9.<br> +Découvrons ensemble les nouveautés !</p> +</div><ul><li>lien náµ’Â 1 : <a title="https://laravel.com/" hreflang="en" href="https://linuxfr.org/redirect/109745">Laravel : site officiel</a></li><li>lien náµ’Â 2 : <a title="https://laravel-news.com/laravel-9-released" hreflang="en" href="https://linuxfr.org/redirect/109746">Laravel 9 : annonce officielle</a></li><li>lien náµ’Â 3 : <a title="https://laravel.com/docs/9.x/releases" hreflang="en" href="https://linuxfr.org/redirect/109928">Release Notes</a></li></ul><div><h2 class="sommaire">Sommaire</h2> +<ul class="toc"> +<li> +<ul> +<li> +<a href="#toc-quoi-de-neuf">Quoi de neuf ?</a><ul> +<li><a href="#toc-nouvelle-version-lts">Nouvelle version LTS</a></li> +<li><a href="#toc-version-de-php">Version de PHP</a></li> +<li><a href="#toc-migration-de-swiftmailer-%C3%A0-symfony-mailer">Migration de SwiftMailer à Symfony Mailer</a></li> +<li><a href="#toc-anonymous-stub-migrations-par-d%C3%A9faut"><em>Anonymous Stub Migrations</em> par défaut</a></li> +<li><a href="#toc-nouveau-design-pour-la-commande-routeslist">Nouveau design pour la commande <code>routes:list</code></a></li> +<li><a href="#toc-flysystem-3x">Flysystem 3.x</a></li> +<li><a href="#toc-nouvelle-fa%C3%A7on-de-d%C3%A9finir-des-accesseursmutateurs-aux-mod%C3%A8les">Nouvelle façon de définir des accesseurs/mutateurs aux modèles</a></li> +<li><a href="#toc-support-des-enums">Support des Enums</a></li> +<li><a href="#toc-affichage-de-la-couverture-de-code">Affichage de la couverture de code</a></li> +<li><a href="#toc-et-bien-dautres-choses-encore">Et bien d'autres choses encore</a></li> +</ul> +</li> +<li><a href="#toc-laracon-2022">Laracon 2022</a></li> +<li><a href="#toc-laravel-nova-4">Laravel Nova 4</a></li> +</ul> +</li> +</ul> +<p>Un an et demi après Laravel 8 et avec six mois de retard sur la date initialement prévue, dû aux changements <a href="//linuxfr.org/news/laravel-8-est-sorti#toc-calendrier-de-sortie">à plusieurs reprises du calendrier des sorties</a>, Laravel 9 est finalement sorti ce 08 février 2022.</p> + +<p>Pour marquer le coup, l'équipe de Laravel en a profité pour rafraîchir le site officiel.</p> +<h3 id="toc-quoi-de-neuf">Quoi de neuf ?</h3> +<h4 id="toc-nouvelle-version-lts">Nouvelle version LTS</h4> + +<p>Première info qui a son importance : il s'agit d'une version LTS, en remplacement de la précédente (Laravel 6, qui datait de septembre 2019). Cette sortie entraîne aussi l'arrêt des correctifs d'erreurs, mais pas encore des correctifs de sécurité, pour cette dernière (<a href="https://laravelversions.com/fr">cf. le calendrier officiel des versions, pour plus de détails</a>).</p> +<h4 id="toc-version-de-php">Version de PHP</h4> + +<p>Le premier impact notable est la nécessité d'utiliser PHP 8.0 <em>a minima</em>. Ceci est notamment dû au fait que Laravel 9 repose sur des briques de Symfony 6.0 (<a href="https://symfony.com/releases/6.0">sortie en novembre dernier</a>) et qui nécessite, vous l'aurez compris, PHP 8.<br> +À noter cependant qu'il faudra utiliser PHP 8.1, si vous comptez avoir recours aux <code>enums</code> (cf. le chapitre <a href="//linuxfr.org/redaction/news/laravel-9-est-sorti#toc-support-des-enums">Support des enums</a>)</p> +<h4 id="toc-migration-de-swiftmailer-à -symfony-mailer">Migration de SwiftMailer à Symfony Mailer</h4> + +<p>Toujours du fait de cette dépendance à (une partie de) Symfony 6.0, il faut désormais passer de SwiftMailer à Symfony Mailer, le premier ayant été déprécié par les développeurs de Symfony.<br> +C'est sans doute là le point de mise à jour le plus délicat de cette nouvelle version mais, comme à chaque fois, <a href="https://laravel.com/docs/9.x/upgrade">la documentation de Laravel explique point par point ce qu'il faut modifier/vérifier lors de la mise à jour.</a></p> + +<p>Pour ceux qui veulent en savoir plus sur les raisons de ce changement par Symfony, vous pouvez vous reporter à <a href="https://symfony.com/blog/the-end-of-swiftmailer">ce billet de blog</a>.</p> +<h4 id="toc-anonymous-stub-migrations-par-défaut"> +<em>Anonymous Stub Migrations</em> par défaut</h4> + +<p><a href="//linuxfr.org/news/laravel-8-est-sorti#toc-anonymous-migrations">On en parlait déjà dans une précédente dépêche</a> : il s'agit ici d'une nouveauté apparue dans <a href="https://laravel-news.com/laravel-anonymous-migrations">Laravel 8.37</a>, consistant à rendre anonyme les scripts de migration.<br> +Pour rappel, les scripts de migration sont un mécanisme de migration de la structure de la base de données, reposant sur des scripts horodatés.<br> +Jusqu'à présent, chaque script était une classe (héritant de la classe <code>Migration</code> fournie par Laravel) contenant les modifications à effectuer.<br> +Problème : cette classe doit avoir un nom unique (car tous les scripts de migration sont dans le même <em>namespace</em>). Ce qui n'est pas toujours pratique, quand le nombre de scripts est de plusieurs centaines.<br> +Le fait de rendre ces scripts anonymes résout le problème du conflit entre classes de même nom.</p> + +<p>On passe donc de ceci :</p> + +<pre><code class="php"><span class="k">use</span> <span class="nx">Illuminate\Database\Migrations\Migration</span><span class="p">;</span> +<span class="k">use</span> <span class="nx">Illuminate\Database\Schema\Blueprint</span><span class="p">;</span> +<span class="k">use</span> <span class="nx">Illuminate\Support\Facades\Schema</span><span class="p">;</span> + +<span class="k">class</span> <span class="nc">MaClasseAvecUnNomUniquePourNePasEntrerEnConflitAvecLes300AutresClassesDeMigration</span> <span class="k">extends</span> <span class="nx">Migration</span> <span class="p">{</span> + <span class="sd">/**</span> +<span class="sd"> * Run the migrations.</span> +<span class="sd"> *</span> +<span class="sd"> * @return void</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="k">function</span> <span class="nf">up</span><span class="p">()</span> + <span class="p">{</span> + <span class="nx">Schema</span><span class="o">::</span><span class="na">table</span><span class="p">(</span><span class="s1">'people'</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="nx">Blueprint</span> <span class="nv">$table</span><span class="p">)</span> <span class="p">{</span> + <span class="nv">$table</span><span class="o">-&gt;</span><span class="na">string</span><span class="p">(</span><span class="s1">'first_name'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">nullable</span><span class="p">();</span> + <span class="p">});</span> + <span class="p">}</span> +<span class="p">};</span></code></pre> + +<p>à cela :</p> + +<pre><code class="php"><span class="k">use</span> <span class="nx">Illuminate\Database\Migrations\Migration</span><span class="p">;</span> +<span class="k">use</span> <span class="nx">Illuminate\Database\Schema\Blueprint</span><span class="p">;</span> +<span class="k">use</span> <span class="nx">Illuminate\Support\Facades\Schema</span><span class="p">;</span> + +<span class="k">return</span> <span class="k">new</span> <span class="k">class</span> <span class="nc">extends</span> <span class="nx">Migration</span> <span class="p">{</span> + <span class="sd">/**</span> +<span class="sd"> * Run the migrations.</span> +<span class="sd"> *</span> +<span class="sd"> * @return void</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="k">function</span> <span class="nf">up</span><span class="p">()</span> + <span class="p">{</span> + <span class="nx">Schema</span><span class="o">::</span><span class="na">table</span><span class="p">(</span><span class="s1">'people'</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="nx">Blueprint</span> <span class="nv">$table</span><span class="p">)</span> <span class="p">{</span> + <span class="nv">$table</span><span class="o">-&gt;</span><span class="na">string</span><span class="p">(</span><span class="s1">'first_name'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">nullable</span><span class="p">();</span> + <span class="p">});</span> + <span class="p">}</span> +<span class="p">};</span></code></pre> + +<p>Laravel 8.37 a permis d'écrire des scripts avec des classes anonymes, Laravel 9 rend ce comportement par défaut.</p> +<h4 id="toc-nouveau-design-pour-la-commande-routeslist">Nouveau design pour la commande <code>routes:list</code> +</h4> + +<p>La commande <code>php artisan routes:list</code>, qui sert à lister toutes les URL auquel votre projet peut répondre (en indiquant pour chacune le verbe HTTP concerné, l'alias éventuel, le contrôleur qui sera exécuté, les <em>middlewares</em> invoqués, …) se refait une fraîcheur !</p> + +<p>Désormais, la sortie de cette commande passe de ceci : <img src="//img.linuxfr.org/img/68747470733a2f2f692e737461636b2e696d6775722e636f6d2f62365a44712e706e67/b6ZDq.png" alt="Old design for routes:list" title="Source : https://i.stack.imgur.com/b6ZDq.png"></p> + +<p>à cela : <img src="//img.linuxfr.org/img/68747470733a2f2f6c61726176656c6e6577732e73332e616d617a6f6e6177732e636f6d2f696d616765732f4649585755712d5873416b477a62632e6a706567/FIXWUq-XsAkGzbc.jpeg" alt="New Design for routes:list" title="Source : https://laravelnews.s3.amazonaws.com/images/FIXWUq-XsAkGzbc.jpeg"></p> + +<p>Coloration syntaxique des verbes HTTP et des paramètres dans l'URL, affichage désormais <em>responsive</em> (finis les tableaux plus grands que la largeur de la console, et qui débordent sur la ligne du dessous, rendant l'affichage difficilement lisible), informations affichées dépendant de paramètres passés à la commande (ex : les <em>middlewares</em> n'apparaissent plus, par défaut), …</p> +<h4 id="toc-flysystem-3x">Flysystem 3.x</h4> + +<p>Flystystem est une couche d'abstraction pour accéder à des systèmes de fichiers, locaux (sur disque ou en mémoire) ou distants (FTP, AWS S3, …).<br> +C'est notamment par lui que transitent les uploads depuis un formulaire, les envois/réceptions vers/depuis des sources extérieures (cloud, …).</p> +<h4 id="toc-nouvelle-façon-de-définir-des-accesseursmutateurs-aux-modèles">Nouvelle façon de définir des accesseurs/mutateurs aux modèles</h4> + +<p>Par défaut dans Laravel, les propriétés des classes-modèles correspondent aux champs de la table à laquelle est liée ladite classe. Mais il est bien évidemment possible d'ajouter de nouvelles propriétés, sans que celles-ci ne soient stockées en base.</p> + +<p>Ex :</p> + +<pre><code class="php"><span class="k">public</span> <span class="k">function</span> <span class="nf">getFullnameAttribute</span><span class="p">()</span> +<span class="p">{</span> + <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">firstname</span> <span class="o">.</span> <span class="s1">' '</span> <span class="o">.</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">lastname</span><span class="p">;</span> +<span class="p">}</span> + +<span class="k">public</span> <span class="k">function</span> <span class="nf">setFullameAttribute</span><span class="p">(</span><span class="nv">$fullname</span><span class="p">)</span> +<span class="p">{</span> + <span class="k">list</span><span class="p">(</span><span class="nv">$firstname</span><span class="p">,</span> <span class="nv">$lastname</span><span class="p">)</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">' '</span><span class="p">,</span> <span class="nv">$fullname</span><span class="p">);</span> + + <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">attributes</span><span class="p">[</span><span class="s1">'firstname'</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$firstname</span><span class="p">;</span> + <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">attributes</span><span class="p">[</span><span class="s1">'lastname'</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$lastname</span><span class="p">;</span> +<span class="p">}</span></code></pre> + +<p>Pour des raisons évidentes "d'auto-détection" des propriétés ajoutées, les noms des méthodes suivent une syntaxe imposée par Laravel : <code>getXxxAttribute</code> et <code>setXxxAttribute</code>.</p> + +<p>Laravel 9 propose désormais une nouvelle approche (tout en gardant l'ancienne toujours utilisable) :</p> + +<pre><code class="php"><span class="k">use</span> <span class="nx">Illuminate\Database\Eloquent\Casts\Attribute</span><span class="p">;</span> + +<span class="k">public</span> <span class="k">function</span> <span class="nf">fullname</span><span class="p">()</span><span class="o">:</span> <span class="nx">Attribute</span> +<span class="p">{</span> + <span class="k">return</span> <span class="k">new</span> <span class="nx">Attribute</span><span class="p">(</span> + <span class="nx">get</span><span class="o">:</span> <span class="nx">fn</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">firstname</span> <span class="o">.</span> <span class="s1">' '</span> <span class="o">.</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">lastname</span><span class="p">,</span> + <span class="nx">set</span><span class="o">:</span> <span class="nx">fn</span> <span class="p">(</span><span class="nv">$value</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">[</span> + <span class="s1">'firstname'</span> <span class="o">=&gt;</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">' '</span><span class="p">,</span> <span class="nv">$fullname</span><span class="p">)[</span><span class="mi">0</span><span class="p">],</span> + <span class="s1">'lastname'</span> <span class="o">=&gt;</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">' '</span><span class="p">,</span> <span class="nv">$fullname</span><span class="p">)[</span><span class="mi">1</span><span class="p">],</span> + <span class="p">],</span> + <span class="p">);</span> +<span class="p">}</span></code></pre> + +<p>À noter l'usage des paramètres nommés <code>get:</code> et <code>set:</code> qui sont une nouveauté de PHP 8.</p> +<h4 id="toc-support-des-enums">Support des Enums</h4> + +<p>PHP 8.1 ayant apporté le support des <code>enums</code>, il n'a pas fallu longtemps pour que Laravel en fasse autant !<br> +Il est donc désormais possible de caster une propriété d'un modèle pour qu'elle n'accepte que les valeurs supportées par un enum donné :</p> + +<pre><code class="php"><span class="k">use</span> <span class="nx">App\Enums\ServerStatus</span><span class="p">;</span> + +<span class="sd">/**</span> +<span class="sd"> * The attributes that should be cast.</span> +<span class="sd"> *</span> +<span class="sd"> * @var array</span> +<span class="sd"> */</span> +<span class="k">protected</span> <span class="nv">$casts</span> <span class="o">=</span> <span class="p">[</span> + <span class="s1">'status'</span> <span class="o">=&gt;</span> <span class="nx">ServerStatus</span><span class="o">::</span><span class="na">class</span><span class="p">,</span> +<span class="p">];</span></code></pre> + +<p>Ici, <code>ServerStatus</code> est un <code>enum</code> contenant un certain nombre de valeurs. La propriété <code>status</code> ne peut désormais accepter autre chose que ces valeurs.</p> + +<p>Autre possibilité : avoir une URL qui n'accepte que les valeurs d'un <code>enum</code> donné :</p> + +<pre><code class="php"><span class="nx">enum</span> <span class="nx">Category</span><span class="o">:</span> <span class="nx">string</span> +<span class="p">{</span> + <span class="k">case</span> <span class="nx">Fruits</span> <span class="o">=</span> <span class="s1">'fruits'</span><span class="p">;</span> + <span class="k">case</span> <span class="nx">People</span> <span class="o">=</span> <span class="s1">'people'</span><span class="p">;</span> +<span class="p">}</span> + +<span class="nx">Route</span><span class="o">::</span><span class="na">get</span><span class="p">(</span><span class="s1">'/categories/{category}'</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="nx">Category</span> <span class="nv">$category</span><span class="p">)</span> <span class="p">{</span> + <span class="k">return</span> <span class="nv">$category</span><span class="o">-&gt;</span><span class="na">value</span><span class="p">;</span> +<span class="p">});</span></code></pre> + +<p>Toute autre valeur que "fruits" ou "people" provoquera une erreur 404.</p> +<h4 id="toc-affichage-de-la-couverture-de-code">Affichage de la couverture de code</h4> + +<p>La commmande <code>php artisan test</code>, qui sert à lancer les tests unitaires/features d'un projet Laravel, a reçu un nouveau paramètre optionnel <code>--coverage</code> permettant d'afficher la couverture de code, sous forme de pourcentage.<br> +Il est même possible de définir un pourcentage minimum à atteindre, en-deçà duquel l'exécution des tests sera considérée comme ayant échoué.<br> +<img src="//img.linuxfr.org/img/68747470733a2f2f757365722d696d616765732e67697468756275736572636f6e74656e742e636f6d2f353435373233362f3134393938393835332d61323961373632392d326266612d346266332d626266372d6364626133333965633135372e706e67/149989853-a29a7629-2bfa-4bf3-bbf7-cdba339ec157.png" alt="Test Coverage Using Artisan test Command" title="Source : https://user-images.githubusercontent.com/5457236/149989853-a29a7629-2bfa-4bf3-bbf7-cdba339ec157.png"></p> +<h4 id="toc-et-bien-dautres-choses-encore">Et bien d'autres choses encore</h4> + +<p>La liste complète des améliorations est à retrouver sur la page "Release notes" indiquée en début de dépêche.</p> +<h3 id="toc-laracon-2022">Laracon 2022</h3> + +<p><a href="https://laracon.net/">La conférence annuelle sur Laravel commence ce 9 février</a>. Points particuliers : elle est intégralement en ligne (pour des raisons évidentes d'actualité sanitaire), mais surtout : les places sont gratuites ! Merci pour cela aux sponsors de Laravel qui l'ont financée intégralement.</p> +<h3 id="toc-laravel-nova-4">Laravel Nova 4</h3> + +<p>Nova est un package développé par l'équipe de Laravel permettant de créer et gérer un dashboard admin. Sortie en version 4 est prévu pour le mois prochain.<br> +À noter que, contrairement à Laravel, Nova est payant et propriétaire.</p> +</div><div><a href="https://linuxfr.org/news/laravel-9-est-sorti.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/126499/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/laravel-9-est-sorti#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>windu.2b</name> + </author> + <author> + <name>vmagnin</name> + </author> + <author> + <name>Xavier Teyssier</name> + </author> + <author> + <name>Benoît Sibaud</name> + </author> + <category term="PHP"/> + <category term="php"/> + <category term="laravel"/> + <wfw:commentRss>https://linuxfr.org/nodes/126499/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/40765</id> + <published>2021-12-02T16:01:01+01:00</published> + <updated>2021-12-02T18:39:44+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/la-version-8-1-de-php-et-creation-de-la-fondation-php"/> + <title>La version 8.1 de PHP et création de la fondation PHP</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>En fin d’année 2021 et sur la lancée habituelle PHP passe en version 8.1. Tout comme les autres versions, elle sera maintenue activement pendant deux années et elle recevra seulement des correctifs de sécurité une année de plus.</p> + +<p><img src="//img.linuxfr.org/img/68747470733a2f2f692e696d6775722e636f6d2f3769595a3759552e6a7067/7iYZ7YU.jpg" alt="Élephant PHP sur un ordinateur portable" title="source : Ben Griffiths via Unsplash https://unsplash.com/photos/2Rd-hwT2xQ0 | Source : https://i.imgur.com/7iYZ7YU.jpg"></p> +</div><ul><li>lien náµ’Â 1 : <a title="https://www.php.net/" hreflang="en" href="https://linuxfr.org/redirect/109460">Site officiel</a></li><li>lien náµ’Â 2 : <a title="https://externals.io/" hreflang="en" href="https://linuxfr.org/redirect/109461">Liste de diffusion</a></li><li>lien náµ’Â 3 : <a title="https://www.php.net/releases/8.1/en.php" hreflang="en" href="https://linuxfr.org/redirect/109462">Page officielle PHP 8.1</a></li></ul><div><h2 class="sommaire">Sommaire</h2> +<ul class="toc"> +<li> +<a href="#toc-quoi-de-neuf">Quoi de neuf</a><ul> +<li> +<a href="#toc-les-nouveaut%C3%A9s-majeures">Les nouveautés majeures</a><ul> +<li><a href="#toc-les-types-%C3%A9num%C3%A9r%C3%A9s">Les types énumérés</a></li> +<li><a href="#toc-propri%C3%A9t%C3%A9s-de-classe-en-lecture-seule">Propriétés de classe en lecture seule</a></li> +<li><a href="#toc-les-types-intersection-purs">Les types intersection purs</a></li> +</ul> +</li> +<li> +<a href="#toc-autres-nouveaut%C3%A9s">Autres nouveautés</a><ul> +<li><a href="#toc-du-code-asynchrone-avec-les-fibers">Du code asynchrone avec les Fibers</a></li> +<li><a href="#toc-new-dans-le-constructeur-et-des-constantes-finales"><code>new</code> dans le constructeur et des constantes finales</a></li> +<li><a href="#toc-des-performances-en-hausse">Des performances en hausse</a></li> +</ul> +</li> +<li><a href="#toc-pour-la-suite">Pour la suite</a></li> +</ul> +</li> +<li> +<a href="#toc-les-changements-au-niveau-de-la-communaut%C3%A9">Les changements au niveau de la communauté</a><ul> +<li><a href="#toc-migration-progressive-sur-github">Migration progressive sur Github</a></li> +<li><a href="#toc-cr%C3%A9ation-de-la-fondation-php">Création de la fondation PHP</a></li> +</ul> +</li> +</ul> +<h2 id="toc-quoi-de-neuf">Quoi de neuf</h2> +<h3 id="toc-les-nouveautés-majeures">Les nouveautés majeures</h3> +<h4 id="toc-les-types-énumérés">Les types énumérés</h4> + +<p>Jusqu’à présent cette structure n’était pas présente nativement dans le langage, elle était néanmoins implémentée dans diverses bibliothèques. C’est la bonne occasion de se débarrasser des classes remplies de constantes.</p> + +<pre><code class="php"><span class="o">&lt;?</span><span class="nx">php</span> +<span class="nx">enum</span> <span class="nx">IP</span> +<span class="p">{</span> + <span class="k">case</span> <span class="nx">V4</span><span class="p">;</span> + <span class="k">case</span> <span class="nx">V6</span><span class="p">;</span> +<span class="p">}</span> + +<span class="c1">// la méthode statique cases() est automatiquement implémentée</span> +<span class="nx">IP</span><span class="o">::</span><span class="na">cases</span><span class="p">();</span> <span class="c1">// [IP::V4, IP::V6]</span> + +<span class="nv">$versionOf</span> <span class="o">=</span> <span class="nx">fn</span><span class="p">(</span><span class="nx">string</span> <span class="nv">$address</span><span class="p">)</span><span class="o">:</span> <span class="o">?</span><span class="nx">IP</span> <span class="o">=&gt;</span> <span class="p">{</span> + <span class="nx">match</span><span class="p">(</span><span class="k">true</span><span class="p">){</span> + <span class="k">case</span> <span class="nx">isIpV4</span><span class="p">(</span><span class="nv">$address</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">IP</span><span class="o">::</span><span class="na">V4</span><span class="p">,</span> + <span class="k">case</span> <span class="nx">isIpV6</span><span class="p">(</span><span class="nv">$address</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">IP</span><span class="o">::</span><span class="na">V6</span><span class="p">,</span> + <span class="k">default</span> <span class="o">=&gt;</span> <span class="k">null</span> + <span class="p">}</span> +<span class="p">};</span> + +<span class="nv">$versionOf</span><span class="p">(</span><span class="s2">"192.168.0.1); // IP::V4</span></code></pre> +<h4 id="toc-propriétés-de-classe-en-lecture-seule">Propriétés de classe en lecture seule</h4> + +<p>Cette fonctionnalité, qui existe déjà dans d’autres langages (C# et TypeScript), fait son arrivée. Elle vous permettra d’avoir un objet dont les propriétés ne pourront plus être modifiées après l’instanciation. Ça va désormais être rapide pour créer des DTO.</p> + +<pre><code class="php"><span class="k">class</span> <span class="nc">QuelBeauDTO</span> +<span class="p">{</span> + <span class="k">public</span> <span class="k">function</span> <span class="fm">__construct</span><span class="p">(</span><span class="k">public</span> <span class="nx">readonly</span> <span class="nx">string</span> <span class="nv">$message</span><span class="p">){}</span> +<span class="p">}</span> + +<span class="nv">$dto</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">QuelBeauDTO</span><span class="p">(</span><span class="s2">"LinuxFR"</span><span class="p">);</span> + +<span class="k">echo</span><span class="p">(</span><span class="nv">$dto</span><span class="o">-&gt;</span><span class="na">message</span><span class="p">);</span> <span class="c1">// LinuxFR</span> + +<span class="nv">$dto</span><span class="o">-&gt;</span><span class="na">message</span> <span class="o">=</span> <span class="s2">"Vive les moules"</span><span class="p">;</span> <span class="c1">//Fatal error: Uncaught Error: Cannot modify readonly property QuelBeauDTO::$message</span></code></pre> +<h4 id="toc-les-types-intersection-purs">Les types intersection purs</h4> + +<p>Après les types unions lors de la version précédente, voici l’intersection. Une bonne solution pour favoriser la composition d’interface et améliorer la modularité de nos développements.</p> + +<pre><code class="php"><span class="k">interface</span> <span class="nx">A</span><span class="p">{</span> <span class="k">function</span> <span class="nf">a</span><span class="p">()</span><span class="o">:</span> <span class="nx">string</span><span class="p">;}</span> + +<span class="k">interface</span> <span class="nx">B</span><span class="p">{</span> <span class="k">function</span> <span class="nf">b</span><span class="p">()</span><span class="o">:</span> <span class="nx">string</span><span class="p">;}</span> + +<span class="k">class</span> <span class="nc">Coucou</span> <span class="k">implements</span> <span class="nx">A</span><span class="p">,</span> <span class="nx">B</span> +<span class="p">{</span> + <span class="k">function</span> <span class="fm">__construct</span><span class="p">(</span><span class="k">private</span> <span class="nx">readonly</span> <span class="nx">string</span> <span class="nv">$a</span><span class="p">,</span> <span class="k">private</span> <span class="nx">readonly</span> <span class="nx">string</span> <span class="nv">$b</span><span class="p">){}</span> + + <span class="k">function</span> <span class="nf">a</span><span class="p">()</span><span class="o">:</span> <span class="nx">string</span> + <span class="p">{</span> + <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">a</span><span class="p">;</span> + <span class="p">}</span> + + <span class="k">function</span> <span class="nf">b</span><span class="p">()</span><span class="o">:</span> <span class="nx">string</span> + <span class="p">{</span> + <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">b</span><span class="p">;</span> + <span class="p">}</span> +<span class="p">}</span> + +<span class="nv">$ab</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Coucou</span><span class="p">(</span><span class="s2">"coucou"</span><span class="p">,</span> <span class="s2">"toto"</span><span class="p">);</span> + +<span class="nv">$fn</span> <span class="o">=</span> <span class="nx">fn</span><span class="p">(</span><span class="nx">A</span><span class="o">&amp;</span><span class="nx">B</span> <span class="nv">$ab</span><span class="p">)</span><span class="o">:</span> <span class="nx">string</span> <span class="o">=&gt;</span> <span class="s2">"</span><span class="si">{</span><span class="nv">$ab</span><span class="o">-&gt;</span><span class="na">a</span><span class="p">()</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="nv">$ab</span><span class="o">-&gt;</span><span class="na">b</span><span class="p">()</span><span class="si">}</span><span class="s2">"</span><span class="p">;</span> + +<span class="k">echo</span><span class="p">(</span><span class="nv">$fn</span><span class="p">(</span><span class="nv">$ab</span><span class="p">));</span> <span class="c1">// coucou toto</span></code></pre> + +<p>La notion de pureté vient du fait que pour le moment il n’est pas possible d’avoir une signature du genre : <code>A&amp;B|C</code>. Une discussion houleuse s’est tenue quelques jours avant le gel des fonctionnalités sur la possibilité d’avoir des <code>null</code> et la syntaxe qui l’accompagnerait. Pour rappel, les types union ont intégré le langage en version 8.0.</p> +<h3 id="toc-autres-nouveautés">Autres nouveautés</h3> +<h4 id="toc-du-code-asynchrone-avec-les-fibers">Du code asynchrone avec les Fibers</h4> + +<p>Jusqu’à présent, la gestion du code asynchrone était gérée du côté des bibliothèques, les plus connues étant <a href="https://amphp.org/">Amp</a>, <a href="https://reactphp.org/">ReactPHP</a> et <a href="https://www.swoole.co.uk/">Swoole</a>. Chaque solution avait implémenté les logiques nécessaires à leur sauce. Avec l’arrivée des fibres dans le langage, les cartes sont rebattues et chacun devra apporter des modifications pour profiter de la partie native. D’ailleurs ReactPHP et Amp se sont associés pour écrire une couche d’abstraction nommée <a href="https://revolt.run/">Revolt</a>.</p> +<h4 id="toc-new-dans-le-constructeur-et-des-constantes-finales"> +<code>new</code> dans le constructeur et des constantes finales</h4> + +<p>Les constantes finales ne peuvent pas être redéfinies dans une classe enfant (mais qui utilise l’héritage ???) et il est possible d’intégrer des <code>new</code> directement dans le constructeur.</p> + +<pre><code class="php"><span class="k">class</span> <span class="nc">A</span> <span class="p">{</span> + <span class="k">private</span> <span class="k">final</span> <span class="k">const</span> <span class="no">A</span> <span class="o">=</span> <span class="s2">"toto"</span><span class="p">;</span> + + <span class="k">public</span> <span class="k">function</span> <span class="fm">__construct</span><span class="p">(</span><span class="k">private</span> <span class="nx">DatetimeImmutable</span> <span class="nv">$now</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">DateTimeImmutable</span><span class="p">()){};</span> +<span class="p">}</span> + +<span class="k">class</span> <span class="nc">B</span> <span class="nx">extend</span> <span class="nx">A</span><span class="p">{</span> + <span class="k">private</span> <span class="k">final</span> <span class="k">const</span> <span class="no">A</span> <span class="o">=</span> <span class="s2">"tata"</span><span class="p">;</span> <span class="c1">//Fatal error: B::A cannot override final constant A::A</span> +<span class="p">}</span></code></pre> +<h4 id="toc-des-performances-en-hausse">Des performances en hausse</h4> + +<p>À chaque version, des optimisations sont trouvées et il en résulte de meilleurs résultats sur différents comparatifs. Cette version ne déroge pas à la règle. <a href="https://github.com/kocsismate/php-version-benchmarks/blob/main/docs/results/2021_11_25_10_08_1_aws_arm64_c6g_4xlarge/result.md">Un récent comparatif</a> sur des temps de traitement d’une série de 250 requêtes trouve un temps de réponse diminué d’une vingtaine de pourcents pour une application Symfony ou Laravel et une poignée de pourcents pour un site Wordpress.</p> +<h3 id="toc-pour-la-suite">Pour la suite</h3> + +<p>Pour ceux qui tournent sur du PHP 7.4, il va falloir songer à passer en version 8.0 dans l’année. Pour rappel, une version est maintenue pendant trois ans (deux ans de maintenance active, un an de maintenance de sécurité). Pour cela, il faut baisser les seuils d’alerte au minimum, corriger ce qui provoque les bouts de code concernés par des alertes à la main ou automatiquement avec des outils du genre <a href="https://getrector.org">Rector</a>. </p> + +<p>À l’heure de la rédaction de ces lignes, peu de choses seront incluses dans la prochaine version, mais on peut déjà voir que cela ne sera toujours une somme de choses pour rendre <a href="https://wiki.php.net/rfc/shell_exec_result_code_param">le langage plus cohérent</a>, de suppression de possibilités pour écrire <a href="https://wiki.php.net/rfc/deprecate_dynamic_properties">des choses atroces</a>, de <a href="https://www.php.net/manual/en/function.array-is-list">simples utilitaires</a> pour ne pas réinventer la roue, etc.</p> +<h2 id="toc-les-changements-au-niveau-de-la-communauté">Les changements au niveau de la communauté</h2> + +<p>PHP est un langage communautaire, à ma connaissance, il n’y a pas d’entreprise qui emploie des personnes pour travailler à plein temps sur le langage. Le langage évolue donc au gré des volontés diverses et variées de proposer des nouvelles fonctionnalités et de les implémenter. Globalement, l’évolution et la maintenance du langage ne tient qu’à une poignée de motivé(e)s. Comme pour la plupart des projets communautaires, toute aide est la bienvenue que ce soit sous la forme de traduction, de documentation, de rapports de bug, pour rajouter du code c’est un poil plus compliqué, car il faut être familier avec le C à la sauce PHP !</p> +<h3 id="toc-migration-progressive-sur-github">Migration progressive sur Github</h3> + +<p>L’infrastructure vieillissante du projet arrivant au bout de sa vie et un <a href="https://externals.io/message/113981#114043">incident de sécurité</a> ce printemps ont poussé à stopper les contributions sur le service git du projet. Alors que le dépôt sur Github servait de miroir, il est devenu la source principale. La <a href="https://wiki.php.net/rfc/github_issues">gestion des bugs</a> va également se déplacer au même endroit.</p> +<h3 id="toc-création-de-la-fondation-php">Création de la fondation PHP</h3> + +<p>Jusqu’à présent il n’y avait aucune structure officielle chapeautant le projet et rare ont été les personnes payées pour développer le langage. Ces derniers temps ce nombre ne s’élevait qu’à deux, ce qui pour un langage aussi utilisé que PHP est surprenant, voire désolant. L’un des deux principaux développeurs du projet (Nikita Popov) tant au niveau du code, que des discussions autour des évolutions prévoit de réduire la voilure. Depuis trois ans, il était rémunéré par JetBrains pour travailler sur PHP. Cette fin d’engagement a poussé différentes personnes à finaliser la mise en place d’une fondation afin de supporter financièrement des contributeurs. Vous trouverez plus de détails dans <a href="https://blog.jetbrains.com/phpstorm/2021/11/the-php-foundation/">cette annonce</a>. C’est donc une très bonne nouvelle et il faut espérer que <a href="https://opencollective.com/phpfoundation">les dons des entreprises et des particuliers</a> permettront d’intégrer, de diversifier et consolider le socle des contributeurs.</p> +</div><div><a href="https://linuxfr.org/news/la-version-8-1-de-php-et-creation-de-la-fondation-php.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/126068/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/la-version-8-1-de-php-et-creation-de-la-fondation-php#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>Nonolapéro</name> + </author> + <author> + <name>xdelatour</name> + </author> + <author> + <name>Florent Zara</name> + </author> + <author> + <name>Xavier Teyssier</name> + </author> + <author> + <name>windu.2b</name> + </author> + <author> + <name>Benoît Sibaud</name> + </author> + <author> + <name>palm123</name> + </author> + <author> + <name>Pierre Jarillon</name> + </author> + <category term="PHP"/> + <category term="php"/> + <category term="don"/> + <wfw:commentRss>https://linuxfr.org/nodes/126068/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/40626</id> + <published>2021-12-01T21:07:35+01:00</published> + <updated>2021-12-01T21:07:35+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/pest-soit-des-tests-unitaires"/> + <title>PEST soit des tests unitaires</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>PEST est un nouveau framework en PHP, permettant de rédiger des tests unitaires.<br> +Basé sur le célèbre (pour ceux qui développent en PHP) PHUnit, PEST a pour lui d’être plus élégant et simple à utiliser, et apporte notamment une plus grande fluidité dans l’écriture des tests unitaires.<br> +Il a été créé par Nuno Maduro, membre de la core team de <a href="//linuxfr.org/tags/laravel/public">Laravel</a>, en <a href="https://github.com/sponsorware/docs">sponsorware</a>. Depuis le printemps 2020, il est publié sous <a href="https://github.com/pestphp/pest/blob/master/LICENSE.md">licence MIT</a>. Il ne possède aucune filiation avec Laravel, on peut tout à fait s’en servir sans.<br> +Petit tour d’horizon !</p> + +<p><em>(tous les exemples de code de cette dépêche proviennent de la documentation officielle de PEST)</em></p> +</div><ul><li>lien náµ’Â 1 : <a title="https://pestphp.com/" hreflang="en" href="https://linuxfr.org/redirect/109469">Site officiel</a></li><li>lien náµ’Â 2 : <a title="https://github.com/pestphp/pest" hreflang="en" href="https://linuxfr.org/redirect/109470">Dépôt officiel (github)</a></li><li>lien náµ’Â 3 : <a title="https://github.com/pestphp/pest/blob/master/LICENSE.md" hreflang="en" href="https://linuxfr.org/redirect/109471">Licence MIT</a></li><li>lien náµ’Â 4 : <a title="https://twitter.com/enunomaduro" hreflang="en" href="https://linuxfr.org/redirect/109472">Nuno Maduro créateur du projet</a></li><li>lien náµ’Â 5 : <a title="https://www.youtube.com/playlist?list=PLb4Xm6fDKP2o3F1uP9DM7MfTO7P0W_mmB" hreflang="en" href="https://linuxfr.org/redirect/109481">PEST in practice (série de vidéos)</a></li></ul><div><h2 class="sommaire">Sommaire</h2> +<ul class="toc"> +<li><a href="#toc-premiers-tests">Premiers tests</a></li> +<li> +<a href="#toc-expectations">Expectations</a><ul> +<li><a href="#toc-higher-order-tests">Higher Order Tests</a></li> +<li><a href="#toc-custom-expectations">Custom expectations</a></li> +</ul> +</li> +</ul> +<h2 id="toc-premiers-tests">Premiers tests</h2> + +<p>Pour commencer, voyons à quoi ressemble un test basique, avec PEST.</p> + +<pre><code class="php"><span class="o">&lt;?</span><span class="nx">php</span> + +<span class="nx">test</span><span class="p">(</span><span class="s1">'asserts true is true'</span><span class="p">,</span> <span class="k">function</span> <span class="p">()</span> <span class="p">{</span> + <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">assertTrue</span><span class="p">(</span><span class="k">true</span><span class="p">);</span> + + <span class="nx">expect</span><span class="p">(</span><span class="k">true</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">toBeTrue</span><span class="p">();</span> +<span class="p">});</span></code></pre> + +<p>Contrairement à PHPUnit, qui regroupe chaque test dans une méthode de classe, chaque test dans PEST consiste à appeler la fonction <code>test</code> en lui passant 2 paramètres : la description du test (texte libre) et une fonction anonyme (<em>Closure</em>) contenant le code du test proprement dit. Le tout dans un simple fichier PHP (pas de classe, pas de <em>namespace</em>, rien de tout ça n’est nécessaire).</p> + +<p>Comme PEST repose sur PHPUnit, on peut utiliser les méthodes <code>assertXXX</code> déjà existantes et connues de tous, à travers <code>$this</code> (qui est un objet de type <code>PHPUnit\Framework\TestCase</code>, ce qui montre que PEST est une surcouche à PHPUnit, avec du sucre syntaxique dedans).<br> +Mais on peut aussi utiliser les nouvelles méthodes <code>toBeXXX</code> mises à notre disposition par PEST, et dont on parlera plus loin.</p> + +<p>Si le test ci-dessus réussit, PEST affichera :</p> + +<pre><code class="php"><span class="nx">✓</span> <span class="nx">asserts</span> <span class="k">true</span> <span class="nx">is</span> <span class="k">true</span></code></pre> + +<p>À noter que la fonction <code>test</code> a une petite sÅ“ur : <code>it</code> (même signature). La seule différence est que cette dernière affichera ceci, si le test réussit :</p> + +<pre><code class="php"><span class="nx">✓</span> <span class="nx">it</span> <span class="nx">asserts</span> <span class="k">true</span> <span class="nx">is</span> <span class="k">true</span></code></pre> +<h2 id="toc-expectations">Expectations</h2> + +<p>Bien que PEST puisse s’utiliser comme PHPUnit (ce qui permet doucement de basculer d’un framework à l’autre), on peut bien évidemment aller plus loin, en tirant profit de sa spécificité : les expectations.<br> +Concrètement, cela consiste en une méthode <code>expect</code>, à qui on passe la variable à tester, et toute une série de méthodes fluides (<em>fluent interfaces</em>) qui vont chacune vérifier que la variable respecte telle ou telle règle.</p> + +<p>Reprenons l’exemple du début :</p> + +<pre><code class="php"><span class="o">&lt;?</span><span class="nx">php</span> + +<span class="nx">test</span><span class="p">(</span><span class="s1">'expect true to be true'</span><span class="p">,</span> <span class="k">function</span> <span class="p">()</span> <span class="p">{</span> + <span class="c1">// assertion</span> + <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">assertTrue</span><span class="p">(</span><span class="k">true</span><span class="p">);</span> + + <span class="c1">// expectation</span> + <span class="nx">expect</span><span class="p">(</span><span class="k">true</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">toBe</span><span class="p">(</span><span class="k">true</span><span class="p">);</span> +<span class="p">});</span></code></pre> + +<p>On voit que la méthode <code>toBe</code> vérifie que la valeur <code>true</code> (passée en paramètre de la fonction <code>expect</code>) est bien égale à <code>true</code>.</p> + +<p>Voyons maintenant un cas un peu plus poussé (et plus proche de ce qu’on peut être amené à écrire, dans la vraie vie) :</p> + +<pre><code class="php"><span class="nx">expect</span><span class="p">(</span><span class="nv">$user</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">toBeInstanceOf</span><span class="p">(</span><span class="nx">User</span><span class="o">::</span><span class="na">class</span><span class="p">);</span></code></pre> + +<p>Ici, la méthode <code>toBeInstanceOf</code> vérifie que la variable <code>$user</code> est bien de type <code>User</code>.</p> + +<p>On ne va pas lister ici la palanquée de méthodes <code>toBeXXX</code> qui existent : <a href="https://pestphp.com/docs/expectations#available-expectations">la documentation est là pour ça</a>, avec un exemple pour chacune d’elles.</p> + +<p>Rappelons toutefois qu’il est tout à fait possible de chaîner les appels de méthodes, pour tester plusieurs choses sur une même valeur.</p> + +<p>Exemple :</p> + +<pre><code class="php"><span class="nx">expect</span><span class="p">(</span><span class="s1">'{"name":"Nuno","credit":1000.00}'</span><span class="p">)</span> + <span class="o">-&gt;</span><span class="na">json</span><span class="p">()</span> + <span class="o">-&gt;</span><span class="na">toHaveCount</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span></code></pre> +<h3 id="toc-higher-order-tests">Higher Order Tests</h3> + +<p>Avec le chaînage des méthodes vient aussi une autre possibilité de PEST : pouvoir tester les valeurs au sein de la variable passée à la fonction <code>expect</code>. Ainsi, plutôt que de faire plusieurs appels à <code>expect</code> (ce qui reste tout à fait possible), comme suit :</p> + +<pre><code class="php"><span class="nx">expect</span><span class="p">(</span><span class="nv">$user</span><span class="o">-&gt;</span><span class="na">first_name</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">toEqual</span><span class="p">(</span><span class="s1">'Nuno'</span><span class="p">);</span> +<span class="nx">expect</span><span class="p">(</span><span class="nv">$user</span><span class="o">-&gt;</span><span class="na">last_name</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">toEqual</span><span class="p">(</span><span class="s1">'Maduro'</span><span class="p">);</span> +<span class="nx">expect</span><span class="p">(</span><span class="nv">$user</span><span class="o">-&gt;</span><span class="na">withTitle</span><span class="p">(</span><span class="s1">'Mr'</span><span class="p">))</span><span class="o">-&gt;</span><span class="na">toEqual</span><span class="p">(</span><span class="s1">'Mr Nuno Maduro'</span><span class="p">);</span></code></pre> + +<p>On peut tout à fait faire ceci :</p> + +<pre><code class="php"><span class="nx">expect</span><span class="p">(</span><span class="nv">$user</span><span class="p">)</span> + <span class="o">-&gt;</span><span class="na">first_name</span><span class="o">-&gt;</span><span class="na">toEqual</span><span class="p">(</span><span class="s1">'Nuno'</span><span class="p">)</span> + <span class="o">-&gt;</span><span class="na">last_name</span><span class="o">-&gt;</span><span class="na">toEqual</span><span class="p">(</span><span class="s1">'Maduro'</span><span class="p">)</span> + <span class="o">-&gt;</span><span class="na">withTitle</span><span class="p">(</span><span class="s1">'Mr'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">toEqual</span><span class="p">(</span><span class="s1">'Mr Nuno Maduro'</span><span class="p">);</span></code></pre> + +<p>Et là , on commence à toucher à ce qui rend PEST si attrayant : le chaînage est sans limite ! On peut tester toutes les données contenues à l’intérieur de la valeur passée en paramètre à <code>expect</code>, que ce soit les propriétés d’un objet, comme on vient de le voir, ou les différents éléments d’un tableau, comme ci-dessous :</p> + +<pre><code class="php"><span class="nx">expect</span><span class="p">([</span><span class="s1">'name'</span> <span class="o">=&gt;</span> <span class="s1">'Nuno'</span><span class="p">,</span> <span class="s1">'companies'</span> <span class="o">=&gt;</span> <span class="p">[</span><span class="s1">'Pest'</span><span class="p">,</span> <span class="s1">'Laravel'</span><span class="p">]])</span> + <span class="o">-&gt;</span><span class="na">name</span><span class="o">-&gt;</span><span class="na">toEqual</span><span class="p">(</span><span class="s1">'Nuno'</span><span class="p">)</span> + <span class="o">-&gt;</span><span class="na">companies</span><span class="o">-&gt;</span><span class="na">toHaveCount</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">each</span><span class="o">-&gt;</span><span class="na">toBeString</span></code></pre> + +<p>(notez l’usage de <code>each</code>, qui permet de boucler sur les sous-éléments du tableau)</p> + +<p>Comme dit précédemment, il n’y a pas de limite dans le chaînage, ni dans le parcours en profondeur d’un objet ou d’un tableau.<br> +Ainsi, il est tout à fait possible d’aller chercher les propriétés d’un objet, et de tester qu’elles répondent elles aussi à certains critères.</p> + +<p>Exemple :</p> + +<pre><code class="php"><span class="nx">expect</span><span class="p">(</span><span class="nv">$user</span><span class="p">)</span> + <span class="o">-&gt;</span><span class="na">companies</span><span class="o">-&gt;</span><span class="na">first</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">owner</span><span class="o">-&gt;</span><span class="na">toBeInstanceOf</span><span class="p">(</span><span class="nx">User</span><span class="o">::</span><span class="na">class</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">not</span><span class="o">-&gt;</span><span class="na">toEqual</span><span class="p">(</span><span class="nv">$user</span><span class="p">)</span> + <span class="o">-&gt;</span><span class="na">name</span><span class="o">-&gt;</span><span class="na">toEqual</span><span class="p">(</span><span class="s1">'Nuno'</span><span class="p">);</span></code></pre> + +<p>Dans cet exemple, on comprend que l’objet <code>$user</code> a 2 propriétés testées : <code>companies</code> (qui semble renvoyer une liste d’objets), dont on vérifie que le <code>owner</code> du premier élément est bien un objet de type <code>User</code>, mais n’est pas <code>$user</code>. Et <code>name</code>, dont on vérifie la valeur. Ici, <code>name</code> se rapporte à <code>$user</code>, et non à <code>companies</code> : PEST est capable de revenir à l’objet initialement traité (celui passé en paramètre à <code>expect</code>). Et ce, sans limite !</p> +<h3 id="toc-custom-expectations">Custom expectations</h3> + +<p>La liste des expectations a beau être très grande, et de nouvelles méthodes apparaissent chaque semaine, il y a toujours un moment où il manque celle dont on a besoin, pour couvrir son cas particulier.</p> + +<p>Fort heureusement, PEST permet l’ajout de nouvelles méthodes, grâce à la méthode <code>extend()</code>.</p> + +<p>Exemple :</p> + +<pre><code class="php"><span class="c1">// tests/Pest.php</span> +<span class="nx">expect</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">extend</span><span class="p">(</span><span class="s1">'toBeWithinRange'</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="nv">$min</span><span class="p">,</span> <span class="nv">$max</span><span class="p">)</span> <span class="p">{</span> + <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">toBeGreaterThanOrEqual</span><span class="p">(</span><span class="nv">$min</span><span class="p">)</span> + <span class="o">-&gt;</span><span class="na">toBeLessThanOrEqual</span><span class="p">(</span><span class="nv">$max</span><span class="p">);</span> +<span class="p">});</span> + +<span class="nx">test</span><span class="p">(</span><span class="s1">'numeric ranges'</span><span class="p">,</span> <span class="k">function</span> <span class="p">()</span> <span class="p">{</span> + <span class="nx">expect</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">toBeWithinRange</span><span class="p">(</span><span class="mi">90</span><span class="p">,</span> <span class="mi">110</span><span class="p">);</span> +<span class="p">});</span></code></pre> +</div><div><a href="https://linuxfr.org/news/pest-soit-des-tests-unitaires.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/125226/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/pest-soit-des-tests-unitaires#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>windu.2b</name> + </author> + <author> + <name>Ysabeau</name> + </author> + <author> + <name>barmic 🦦</name> + </author> + <author> + <name>Yves Bourguignon</name> + </author> + <author> + <name>BAud</name> + </author> + <category term="PHP"/> + <category term="php"/> + <category term="pest"/> + <category term="tests"/> + <category term="phpunit"/> + <wfw:commentRss>https://linuxfr.org/nodes/125226/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/40737</id> + <published>2021-11-07T10:00:39+01:00</published> + <updated>2021-11-08T17:40:01+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/phpstan-est-sorti-en-version-1-0"/> + <title>PHPStan est sorti en version 1.0</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>PHPStan, un outil d’analyse statique de code PHP, vient de sortir en version 1.0. Pour l’occasion, un nouveau niveau de criticité a été créé.</p> +</div><ul><li>lien náµ’Â 1 : <a title="https://phpstan.org/" hreflang="en" href="https://linuxfr.org/redirect/109357">Site officiel</a></li><li>lien náµ’Â 2 : <a title="https://github.com/phpstan/phpstan" hreflang="en" href="https://linuxfr.org/redirect/109358">Dépôt Github</a></li><li>lien náµ’Â 3 : <a title="https://phpstan.org/blog/phpstan-1-0-released" hreflang="en" href="https://linuxfr.org/redirect/109359">L&#39;annonce officielle</a></li><li>lien náµ’Â 4 : <a title="https://laravel-news.com/larastan-v1-released" hreflang="en" href="https://linuxfr.org/redirect/109360">Larastan passe aussi en version 1.0</a></li></ul><div><p>PHPStan est une bibliothèque en PHP permettant de faire de l’analyse statique de code PHP. Elle permet de détecter des erreurs dans du code, sans avoir besoin de l’exécuter (à la différence des outils de débogage ou de profiling, qui se basent sur une vraie exécution du code). Créé il y a 6 ans, PHPStan est devenu depuis un outil de référence pour ceux qui souhaitent surveiller la qualité de leur code.</p> + +<p>Pour rappel, les niveaux de criticité couvrent les cas suivants (<a href="https://phpstan.org/user-guide/rule-levels">tirés de la documentation officielle</a>) :</p> + +<ul> +<li>0 : vérifications basiques, classes ou fonctions inconnues, méthodes inconnues appelées par <code>$this</code>, nombre d’arguments passés pour ces méthodes ou fonctions incorrect, variables jamais définies</li> +<li>1 : variables potentiellement non définies, <a href="https://www.php.net/manual/fr/language.oop5.magic.php">méthodes magiques</a> et propriétés sur des classes avec <code>__call</code> et <code>__get</code> +</li> +<li>2 : méthodes inconnues vérifiées sur toutes les expressions (pas seulement sur <code>$this</code>), validation de PHPDocs</li> +<li>3 : types de retour, types assignés à des propriétés</li> +<li>4 : vérification basique de code inutilisé - <code>instanceof</code> toujours à « false » et autres vérifications de type, branches <code>else</code> inutilisées, code injoignable après un <code>return;</code>, etc.</li> +<li>5 : vérification du type des arguments passés aux méthodes et aux fonctions</li> +<li>6 : reporter les indices de type</li> +<li>7 : reporter les types d’union en partie erronées - Si vous appelez une méthode qui existe seulement pour certains types dans un type d’union le niveau 7 commence à vous en informer; autres situations potentiellement incorrectes</li> +<li>8 : reporter les méthodes d’appel et les propriétés d’accès sur des types nullable</li> +<li>9 : être strict sur le type <code>mixed</code> - la seule opération que vous pouvez faire ce type est de le passer vers un autre type <code>mixed</code> +</li> +</ul> + +<p>C’est ce niveau 9 qui a donc été ajouté, avec la version 1.0 : il permet de limiter l’usage du type <code>mixed</code> (un type indiquant que le retour d’une fonction peut être de différents types).</p> +<h3 id="toc-goodies-from-bleeding-edge">Goodies from Bleeding Edge</h3> + +<p>Pour fêter la sortie de cette première version stable, <a href="https://phpstan.org/merch">l’équipe propose quelques produits dérivés (t-shirts et badges)</a>.</p> +<h3 id="toc-larastan-aussi-est-en-version-10">Larastan aussi est en version 1.0</h3> + +<p><a href="https://github.com/nunomaduro/larastan">Larastan</a>, un wrapper autour de PHPStan spécifiquement développé pour le framework <a href="https://fr.m.wikipedia.org/wiki/Laravel">Laravel</a> passe lui aussi en version 1.0.</p> + +<p>Et vous, vous en êtes à quel niveau ?</p> +</div><div><a href="https://linuxfr.org/news/phpstan-est-sorti-en-version-1-0.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/125853/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/phpstan-est-sorti-en-version-1-0#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>windu.2b</name> + </author> + <author> + <name>Benoît Sibaud</name> + </author> + <author> + <name>claudex</name> + </author> + <author> + <name>Ysabeau</name> + </author> + <author> + <name>palm123</name> + </author> + <author> + <name>bobble bubble</name> + </author> + <author> + <name>tisaac</name> + </author> + <category term="PHP"/> + <category term="php"/> + <category term="phpstan"/> + <category term="analyse_statique"/> + <wfw:commentRss>https://linuxfr.org/nodes/125853/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/40234</id> + <published>2021-08-14T14:19:23+02:00</published> + <updated>2021-08-14T14:28:09+02:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/laravel-8-est-sorti"/> + <title>Laravel 8 est sorti</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>Laravel 8, la dernière version du framework PHP est sortie le 8 septembre 2020.</p> +</div><ul></ul><div><h2 class="sommaire">Sommaire</h2> +<ul class="toc"> +<li> +<ul> +<li><a href="#toc-calendrier-de-sortie">Calendrier de sortie</a></li> +<li><a href="#toc-models-directory">Models Directory</a></li> +<li><a href="#toc-model-factory-classes">Model Factory Classes</a></li> +<li><a href="#toc-laravel-jetstream">Laravel Jetstream</a></li> +<li> +<a href="#toc-migration-squashing">Migration Squashing</a><ul> +<li><a href="#toc-sole">Sole()</a></li> +</ul> +</li> +<li> +<a href="#toc-autres-nouveaut%C3%A9s-apparues-dans-les-versions-mineures">Autres nouveautés apparues dans les versions mineures</a><ul> +<li><a href="#toc-anonymous-migrations">Anonymous Migrations</a></li> +<li><a href="#toc-v%C3%A9rification-que-le-mot-de-passe-na-pas-fuit%C3%A9">Vérification que le mot de passe n'a pas fuité</a></li> +<li><a href="#toc-one-of-many">One of Many</a></li> +<li><a href="#toc-parallel-testing">Parallel testing</a></li> +<li><a href="#toc-disable-lazy-loading">Disable Lazy-loading</a></li> +</ul> +</li> +<li> +<a href="#toc-et-maintenant">Et maintenant ?</a><ul> +<li><a href="#toc-laravel-9-lts">Laravel 9 LTS</a></li> +<li><a href="#toc-laracon-2021">Laracon 2021</a></li> +</ul> +</li> +</ul> +</li> +</ul> +<p><a href="https://fr.wikipedia.org/wiki/Laravel">Laravel</a> est un framework PHP, qui existe depuis 2011 (<a href="https://laravel-news.com/laravel-is-10-years-old">il a fêté ses 10 ans en juin</a>). <a href="https://www.grafikart.fr/tutoriels/laravel-symfony-866">Parfois comparé</a> à <a href="https://fr.wikipedia.org/wiki/Symfony">Symfony</a> (qui date de 2005), avec qui <a href="https://symfony.com/projects/laravel">il partage certaines briques de code</a> tout en se voulant plus facile à configurer, il n'a cependant pas à rougir de ses possibilités. Que ce soit en interne, ou <em>via</em> les nombreuses extensions existantes.</p> + +<p>Cette nouvelle version continue le travail commencé avec la version 7, en enrichissant le framework de nouvelles possibilités et améliorations.</p> +<h3 id="toc-calendrier-de-sortie">Calendrier de sortie</h3> + +<p>À l'origine, cette dépêche devait parler de Laravel 9.0 LTS, prévue initialement pour mars 2021.<br> +Mais les développeurs du framework ont entre-temps jugé que Laravel était désormais suffisamment stable et abouti pour ne plus avoir besoin d'une sortie majeure tous les 6 mois. <a href="https://blog.laravel.com/updates-to-laravels-versioning-policy">Le rythme est donc désormais d'une sortie majeure tous les 12 mois, et une sortie mineure toutes les semaines</a>.</p> + +<p>Tout ceci reportait donc Laravel 9 à septembre 2021, entraînant la parution de certaines nouvelles fonctionnalités dans des versions mineures de Laravel 8, et la prolongation de la durée du support de Laravel 6 LTS.<br> +(cf. <a href="https://laravelversions.com/">le calendrier des versions officiellement supportées</a>)</p> + +<p>Il faudra finalement attendre janvier 2022, afin que cette nouvelle version LTS puisse reposer sur <a href="https://symfony.com/releases/6.0">Symfony 6.0, lui-même prévu pour novembre 2021</a>. Le calendrier des sorties suivantes (Laravel 10 et 11) est décalé en conséquence.</p> +<h3 id="toc-models-directory">Models Directory</h3> + +<p>Jusqu'à présent, les classes (héritant de) <code>Models</code> étaient rangées directement dans le répertoire <em>app</em>, contrairement à toutes les autres classes (<code>Controllers</code>, <code>Requests</code>, <code>Providers</code>, <code>Notifications</code>, <code>Rules</code>, …) qui ont toutes leur (sous-)répertoire attribué.<br> +Désormais, le répertoire <em>app/Models</em> existe. À noter que la commande <code>php artisan make:model XXX</code> (qui permet de générer un squelette de fichier PHP pour la classe-modèle <em>XXX</em>) tient compte de l'existence (ou non) de ce répertoire. Bien pratique si on veut conserver l'arborescence d'un projet déjà existant, sans avoir à déplacer les classes dans ce nouveau répertoire, au risque d'oublier de modifier le <em>namespace</em>, ou les imports de classes.</p> +<h3 id="toc-model-factory-classes">Model Factory Classes</h3> + +<p>Dans Laravel, les <em>factories</em> sont des générateurs d'objets (des instances de <code>Models</code>) avec des données de tests. Le but étant de pouvoir créer des objets reposant sur les classes-métiers du projet, afin de les utiliser au sein des tests unitaires.<br> +Désormais, les factories se basent sur une classe <code>Factory</code>, et suivent une structure beaucoup plus orientée POO.</p> + +<pre><code class="php"> <span class="c1">// Factory en Laravel 6 LTS</span> + <span class="nv">$factory</span><span class="o">-&gt;</span><span class="na">define</span><span class="p">(</span><span class="nx">User</span><span class="o">::</span><span class="na">class</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="nx">Faker</span> <span class="nv">$faker</span><span class="p">)</span> <span class="p">{</span> + <span class="k">return</span> <span class="p">[</span> + <span class="s1">'firstname'</span> <span class="o">=&gt;</span> <span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">,</span> + <span class="s1">'lastname'</span> <span class="o">=&gt;</span> <span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">,</span> + <span class="s1">'email'</span> <span class="o">=&gt;</span> <span class="nv">$faker</span><span class="o">-&gt;</span><span class="na">unique</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">safeEmail</span><span class="p">,</span> + <span class="s1">'email_verified_at'</span> <span class="o">=&gt;</span> <span class="nx">now</span><span class="p">(),</span> + <span class="s1">'password'</span> <span class="o">=&gt;</span> <span class="s1">'$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi'</span><span class="p">,</span> <span class="c1">// password</span> + <span class="s1">'remember_token'</span> <span class="o">=&gt;</span> <span class="nx">Str</span><span class="o">::</span><span class="na">random</span><span class="p">(</span><span class="mi">10</span><span class="p">),</span> + <span class="p">];</span> + <span class="p">});</span></code></pre> + +<pre><code class="php"> <span class="c1">// Factory en Laravel 8</span> + <span class="k">class</span> <span class="nc">UserFactory</span> <span class="k">extends</span> <span class="nx">Factory</span> + <span class="p">{</span> + <span class="sd">/**</span> +<span class="sd"> * The name of the factory's corresponding model.</span> +<span class="sd"> *</span> +<span class="sd"> * @var string</span> +<span class="sd"> */</span> + <span class="k">protected</span> <span class="nv">$model</span> <span class="o">=</span> <span class="nx">User</span><span class="o">::</span><span class="na">class</span><span class="p">;</span> + + <span class="sd">/**</span> +<span class="sd"> * Define the model's default state.</span> +<span class="sd"> *</span> +<span class="sd"> * @return array</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="k">function</span> <span class="nf">definition</span><span class="p">()</span> + <span class="p">{</span> + <span class="k">return</span> <span class="p">[</span> + <span class="s1">'firstname'</span> <span class="o">=&gt;</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">faker</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">(),</span> + <span class="s1">'lastname'</span> <span class="o">=&gt;</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">faker</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">(),</span> + <span class="s1">'email'</span> <span class="o">=&gt;</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">faker</span><span class="o">-&gt;</span><span class="na">unique</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">safeEmail</span><span class="p">(),</span> + <span class="s1">'email_verified_at'</span> <span class="o">=&gt;</span> <span class="nx">now</span><span class="p">(),</span> + <span class="s1">'password'</span> <span class="o">=&gt;</span> <span class="s1">'$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi'</span><span class="p">,</span> <span class="c1">// password</span> + <span class="s1">'remember_token'</span> <span class="o">=&gt;</span> <span class="nx">Str</span><span class="o">::</span><span class="na">random</span><span class="p">(</span><span class="mi">10</span><span class="p">),</span> + <span class="p">];</span> + <span class="p">}</span> + <span class="p">}</span></code></pre> +<h3 id="toc-laravel-jetstream">Laravel Jetstream</h3> + +<p>Jetstream est un kit de démarrage regroupant les fonctionnalités communes à tout nouveau projet : register/login, vérification d'email et authentification en deux étapes, gestion des sessions. Jetstream vient en remplacement de l'ancien système de register/login (templates HTML et contrôleurs) proposé par Laravel : <code>laravel-ui</code>.</p> +<h3 id="toc-migration-squashing">Migration Squashing</h3> + +<p>Laravel propose, de base, un mécanisme de migration des schémas de bases de données, permettant de créer (ou de mettre à jour) les tables. Plutôt que d'écrire des requêtes SQL, dont la grammaire peut dépendre du SGBDR utilisé, ce mécanisme repose intégralement sur des classes et méthodes fournies par le framework Laravel. Charge à lui ensuite d'appeler la bonne implémentation, en fonction du SGBDR destinataire (MySQL, PostgreSQL, SQLite et SQL Server sont les seuls officiellement supportés, actuellement).<br> +Chaque migration se compose d'un fichier (dont le nom est horodaté, ce qui permet de définir leur ordre d'exécution) indiquant les modifications à effectuer sur la base de données.</p> + +<p>Exemple :</p> + +<pre><code class="php"> <span class="k">class</span> <span class="nc">CreateUsersTable</span> <span class="k">extends</span> <span class="nx">Migration</span> + <span class="p">{</span> + <span class="sd">/**</span> +<span class="sd"> * Run the migrations.</span> +<span class="sd"> *</span> +<span class="sd"> * @return void</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="k">function</span> <span class="nf">up</span><span class="p">()</span> + <span class="p">{</span> + <span class="nx">Schema</span><span class="o">::</span><span class="na">create</span><span class="p">(</span><span class="s1">'users'</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="nx">Blueprint</span> <span class="nv">$table</span><span class="p">)</span> <span class="p">{</span> + <span class="nv">$table</span><span class="o">-&gt;</span><span class="na">increments</span><span class="p">(</span><span class="s1">'id'</span><span class="p">);</span> + <span class="nv">$table</span><span class="o">-&gt;</span><span class="na">unsignedInteger</span><span class="p">(</span><span class="s1">'gender_id'</span><span class="p">)</span> + <span class="o">-&gt;</span><span class="na">default</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> + <span class="nv">$table</span><span class="o">-&gt;</span><span class="na">string</span><span class="p">(</span><span class="s1">'firstname'</span><span class="p">);</span> + <span class="nv">$table</span><span class="o">-&gt;</span><span class="na">string</span><span class="p">(</span><span class="s1">'lastname'</span><span class="p">);</span> + <span class="nv">$table</span><span class="o">-&gt;</span><span class="na">string</span><span class="p">(</span><span class="s1">'email'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">unique</span><span class="p">();</span> + <span class="nv">$table</span><span class="o">-&gt;</span><span class="na">timestamp</span><span class="p">(</span><span class="s1">'email_verified_at'</span><span class="p">)</span> + <span class="o">-&gt;</span><span class="na">nullable</span><span class="p">();</span> + <span class="nv">$table</span><span class="o">-&gt;</span><span class="na">string</span><span class="p">(</span><span class="s1">'password'</span><span class="p">);</span> + <span class="nv">$table</span><span class="o">-&gt;</span><span class="na">timestamps</span><span class="p">();</span> <span class="c1">// Ajoute les champs 'created_at' et 'updated_at'</span> + <span class="nv">$table</span><span class="o">-&gt;</span><span class="na">softDeletes</span><span class="p">();</span> <span class="c1">// Ajoute le champ 'deleted_at'</span> + + <span class="c1">// On ajoute une FK vers la table 'genders', qui doit avoir été créée dans un script précédent</span> + <span class="nv">$table</span><span class="o">-&gt;</span><span class="na">foreign</span><span class="p">(</span><span class="s1">'gender_id'</span><span class="p">)</span> + <span class="o">-&gt;</span><span class="na">references</span><span class="p">(</span><span class="s1">'id'</span><span class="p">)</span> + <span class="o">-&gt;</span><span class="na">on</span><span class="p">(</span><span class="s1">'genders'</span><span class="p">);</span> + <span class="p">});</span> + <span class="p">}</span> + + <span class="sd">/**</span> +<span class="sd"> * Reverse the migrations.</span> +<span class="sd"> *</span> +<span class="sd"> * @return void</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="k">function</span> <span class="nf">down</span><span class="p">()</span> + <span class="p">{</span> + <span class="k">if</span> <span class="p">(</span><span class="nx">Schema</span><span class="o">::</span><span class="na">hasTable</span><span class="p">(</span><span class="s1">'users'</span><span class="p">))</span> <span class="p">{</span> + <span class="c1">// On supprime la FK, avant de supprimer la table</span> + <span class="nx">Schema</span><span class="o">::</span><span class="na">table</span><span class="p">(</span><span class="s1">'users'</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="nx">Blueprint</span> <span class="nv">$table</span><span class="p">)</span> <span class="p">{</span> + <span class="nv">$table</span><span class="o">-&gt;</span><span class="na">dropForeign</span><span class="p">(</span><span class="s1">'users_gender_id_foreign'</span><span class="p">);</span> + <span class="p">});</span> + + <span class="nx">Schema</span><span class="o">::</span><span class="na">drop</span><span class="p">(</span><span class="s1">'users'</span><span class="p">);</span> + <span class="p">}</span> + <span class="p">}</span> + + <span class="p">}</span></code></pre> + +<p>Ces scripts de migration sont donc l'équivalent d'un <code>versioning</code> de la structure de la base de données. Laravel permet d'ailleurs de revenir en arrière, grâce à la méthode <code>down</code> (avec le risque, évidemment, d'une perte de données si cette méthode supprime des champs/tables dans lesquels des données auront été insérées).</p> + +<p>Avec la nouvelle commande <code>php artisan schema:dump</code>, il est désormais possible de générer un seul (gros) fichier au format SQL, correspondant à la structure de la base de données. Désormais, si un tel fichier existe, Laravel l'exécutera en premier, puis exécutera les scripts de migration créés après (toujours en se basant sur l'horodatage dans les noms des fichiers). Utile lorsqu'on a un projet comptant plusieurs centaines de scripts de migration, et dont le temps d'exécution peut devenir rédhibitoire (ce qui peut vite avoir un impact non négligeable sur le temps d'exécution des tests, si la base de données est recréée avant chacun d'entre eux).<br> +À noter que cette commande ne fonctionne pour l'instant qu'avec MySQL et PostgreSQL.</p> +<h4 id="toc-sole">Sole()</h4> + +<p>La méthode <code>sole()</code>, apparue dans <a href="https://laravel-news.com/laravel-8-23-0">Laravel 8.23</a>, permet de renvoyer le seul et unique objet correspondant au(x) critère(s). Si aucun ou plusieurs objets correspondent, une exception est levée.<br> +Cela est utile dans le cas où on est sûr de n'obtenir qu'un seul objet, quand on filtre une collection suivant un critère (ex : les informations d'une facture quand son statut est <code>INITIALIZED</code>).<br> +Avant cela, il fallait forcément filtrer à nouveau la collection, pour n'obtenir que le 1er élément, quand bien même il n'y en avait qu'un.</p> + +<p>Exemple :</p> + +<pre><code class="php"> <span class="c1">// Laravel 6 LTS</span> + <span class="nv">$book</span> <span class="o">=</span> <span class="nx">Book</span><span class="o">::</span><span class="na">where</span><span class="p">(</span><span class="s1">'title'</span><span class="p">,</span> <span class="s1">'like'</span><span class="p">,</span> <span class="s1">'%War%'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">first</span><span class="p">();</span> <span class="c1">// Il faut préciser qu'on veut le premier élément, sinon on obtient une liste (de 1 élément, potentiellement)</span> + + <span class="c1">// Laravel 8</span> + <span class="nv">$book</span> <span class="o">=</span> <span class="nx">Book</span><span class="o">::</span><span class="na">where</span><span class="p">(</span><span class="s1">'title'</span><span class="p">,</span> <span class="s1">'like'</span><span class="p">,</span> <span class="s1">'%War%'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">sole</span><span class="p">();</span> <span class="c1">// Renvoie forcément un seul élément, ou lève une exception</span></code></pre> +<h3 id="toc-autres-nouveautés-apparues-dans-les-versions-mineures">Autres nouveautés apparues dans les versions mineures</h3> + +<p>La liste ci-dessous n'a pas vocation à être exhaustive, mais à montrer que le cycle désormais annuel n'a pas empêché l'apparition de nouvelles fonctionnalités. Elles sont listées dans l'ordre de leur apparition.</p> +<h4 id="toc-anonymous-migrations">Anonymous Migrations</h4> + +<p>Comme dit précédemment, Laravel a un mécanisme de migration de la structure de la base de données, reposant sur des scripts horodatés.<br> +Jusqu'à présent, chaque script est une classe (héritant de la classe <code>Migration</code> fournie par Laravel) contenant les modifications à effectuer.<br> +Problème : cette classe doit avoir un nom unique (car tous les scripts de migration sont dans le même <code>namespace</code>). Ce qui n'est pas toujours pratique, quand le nombre de scripts est de plusieurs centaines.<br> +<a href="https://laravel-news.com/laravel-anonymous-migrations">Depuis Laravel 8.37</a>, il est possible d'avoir une classe anonyme.</p> + +<p>Exemple :</p> + +<pre><code class="php"><span class="o">&lt;?</span><span class="nx">php</span> + +<span class="k">use</span> <span class="nx">Illuminate\Database\Migrations\Migration</span><span class="p">;</span> +<span class="k">use</span> <span class="nx">Illuminate\Database\Schema\Blueprint</span><span class="p">;</span> +<span class="k">use</span> <span class="nx">Illuminate\Support\Facades\Schema</span><span class="p">;</span> + +<span class="k">return</span> <span class="k">new</span> <span class="k">class</span> <span class="nc">extends</span> <span class="nx">Migration</span> <span class="p">{</span> + <span class="sd">/**</span> +<span class="sd"> * Run the migrations.</span> +<span class="sd"> *</span> +<span class="sd"> * @return void</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="k">function</span> <span class="nf">up</span><span class="p">()</span> + <span class="p">{</span> + <span class="nx">Schema</span><span class="o">::</span><span class="na">table</span><span class="p">(</span><span class="s1">'people'</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="nx">Blueprint</span> <span class="nv">$table</span><span class="p">)</span> <span class="p">{</span> + <span class="nv">$table</span><span class="o">-&gt;</span><span class="na">string</span><span class="p">(</span><span class="s1">'first_name'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">nullable</span><span class="p">();</span> + <span class="p">});</span> + <span class="p">}</span> + + <span class="sd">/**</span> +<span class="sd"> * Reverse the migrations.</span> +<span class="sd"> *</span> +<span class="sd"> * @return void</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="k">function</span> <span class="nf">down</span><span class="p">()</span> + <span class="p">{</span> + <span class="nx">Schema</span><span class="o">::</span><span class="na">table</span><span class="p">(</span><span class="s1">'people'</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="nx">Blueprint</span> <span class="nv">$table</span><span class="p">)</span> <span class="p">{</span> + <span class="nv">$table</span><span class="o">-&gt;</span><span class="na">dropColumn</span><span class="p">(</span><span class="s1">'first_name'</span><span class="p">);</span> + <span class="p">});</span> + <span class="p">}</span> +<span class="p">};</span></code></pre> +<h4 id="toc-vérification-que-le-mot-de-passe-na-pas-fuité">Vérification que le mot de passe n'a pas fuité</h4> + +<p><a href="https://laravel-news.com/password-validation-rule-object-in-laravel-8">Laravel 8.39</a> a ajouté une nouvelle règle de validation (appelées <code>validation rules</code>) : <code>uncompromised()</code>. Elle permet de vérifier que le mot de passe saisi par l'utilisateur (lors de son inscription, par ex.) ne fait pas partie des mots de passe ayant fuité, suite au piratage de sites Web à grand public. Cette vérification repose sur <a href="https://haveibeenpwned.com/API/v2">l'API du site HaveIBeenPwned.com</a></p> + +<p>Pour rappel, les <code>validation rules</code> sont <a href="https://laravel.com/docs/8.x/validation#available-validation-rules">un ensemble de règles de validation de champs de formulaires</a>.<br> +<a href="https://laravel.com/docs/8.x/validation#available-validation-rules">Laravel en fournit un grand nombre</a> (<code>required</code>, <code>exists</code>, <code>min</code>, <code>string</code>, …), mais il est tout à fait possible d'en créer de nouvelles.</p> +<h4 id="toc-one-of-many">One of Many</h4> + +<p>Laravel permet le mapping ORM grâce à des méthodes (<code>hasOne</code>, <code>belongsToMany</code>, …) dont héritent tous les modèles et qui permettent de renvoyer le ou les objets qui leur sont liés. Il suffit pour cela d'écrire une méthode dans la classe-modèle concernée.</p> + +<p>Exemple : </p> + +<pre><code class="php"><span class="o">&lt;?</span><span class="nx">php</span> + +<span class="k">namespace</span> <span class="nx">App\Models</span><span class="p">;</span> + +<span class="k">use</span> <span class="nx">Illuminate\Database\Eloquent\Model</span><span class="p">;</span> + +<span class="k">class</span> <span class="nc">User</span> <span class="k">extends</span> <span class="nx">Model</span> +<span class="p">{</span> + <span class="sd">/**</span> +<span class="sd"> * Un utilisateur peut avoir un téléphone (de type `Phone`) associé</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="k">function</span> <span class="nf">phone</span><span class="p">()</span> + <span class="p">{</span> + <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">hasOne</span><span class="p">(</span><span class="nx">Phone</span><span class="o">::</span><span class="na">class</span><span class="p">);</span> + <span class="p">}</span> +<span class="p">}</span></code></pre> + +<p>Par défaut, Laravel devine les clés primaires et étrangères, ainsi que les tables concernées. Mais on peut ajouter des paramètres à cette méthode, si les noms des champs ne respectent pas la structure par défaut de Laravel.</p> + +<p>Depuis <a href="https://laravel-news.com/one-of-many-eloquent-relationship">Laravel 8.42</a>, il est désormais possible de transformer une relation <code>one-to-many</code> en <code>one-to-one</code>, et ainsi de ne renvoyer qu'un élément.<br> +C'est notamment utile pour récupérer la première/dernière fois qu'un utilisateur s'est connecté, ou le prix actuel (le dernier enregistré en base) d'un produit.</p> + +<p>Exemple :</p> + +<pre><code class="php"><span class="sd">/**</span> +<span class="sd"> * Renvoie le dernier ordre passé par ce User.</span> +<span class="sd"> */</span> +<span class="k">public</span> <span class="k">function</span> <span class="nf">latestOrder</span><span class="p">()</span> +<span class="p">{</span> + <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">hasOne</span><span class="p">(</span><span class="nx">Order</span><span class="o">::</span><span class="na">class</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">latestOfMany</span><span class="p">();</span> +<span class="p">}</span></code></pre> +<h4 id="toc-parallel-testing">Parallel testing</h4> + +<p>Le report de Laravel 9 a entraîné la parution, en "avance" d'une amélioration très attendue : <a href="https://blog.laravel.com/laravel-parallel-testing-is-now-available">la possibilité de pouvoir enfin exécuter les tests en parallèle !</a><br> +Pour générer et exécuter des tests, Laravel utilise la librairie <a href="https://phpunit.de/">PHPUnit</a>, enrichie d'un ensemble de classes et méthodes permettant de tester des fonctionnalités propres à Laravel (exécution des scripts de migration pour construire et remplir la base de données avant d'exécuter les tests, appels d'URL pour des tests <em>features</em> de bout en bout, tests des retours JSON, …).<br> +Pour pouvoir exécuter les tests en parallèle, il fallait jusque-là passer par la librairie <a href="https://github.com/paratestphp/paratest">Paratest</a>. Désormais, Laravel intègre directement une solution basée sur Paratest.</p> +<h4 id="toc-disable-lazy-loading">Disable Lazy-loading</h4> + +<p>Grâce à Eloquent (son ORM intégré), Laravel permet facilement d'accéder aux relations d'un objet.</p> + +<p>Par exemple :</p> + +<pre><code class="php"><span class="c1">// UserController.php</span> +<span class="nv">$user</span> <span class="o">=</span> <span class="nx">User</span><span class="o">::</span><span class="na">find</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> + +<span class="c1">// topics.blade.php</span> +<span class="o">&lt;</span><span class="nx">h2</span><span class="o">&gt;</span><span class="nx">Topics</span><span class="o">&lt;/</span><span class="nx">h2</span><span class="o">&gt;</span> +<span class="o">@</span><span class="k">foreach</span><span class="p">(</span><span class="nv">$user</span><span class="o">-&gt;</span><span class="na">topics</span> <span class="k">as</span> <span class="nv">$topic</span><span class="p">)</span> + <span class="o">&lt;</span><span class="nx">h3</span><span class="o">&gt;</span><span class="p">{{</span> <span class="nv">$topic</span><span class="o">-&gt;</span><span class="na">title</span> <span class="p">}}</span><span class="o">&lt;/</span><span class="nx">h3</span><span class="o">&gt;</span> + <span class="o">@</span><span class="k">foreach</span><span class="p">(</span><span class="nv">$topic</span><span class="o">-&gt;</span><span class="na">comments</span> <span class="k">as</span> <span class="nv">$comment</span><span class="p">)</span> + <span class="o">&lt;</span><span class="nx">p</span><span class="o">&gt;</span> + <span class="p">{{</span> <span class="nv">$comment</span><span class="o">-&gt;</span><span class="na">body</span> <span class="p">}}</span> + <span class="o">&lt;/</span><span class="nx">p</span><span class="o">&gt;</span> + <span class="o">@</span><span class="k">endforeach</span> +<span class="o">@</span><span class="k">endforeach</span></code></pre> + +<p>Ce mécanisme, certes très pratique, a toutefois un inconvénient : mal utilisé, il provoque le problème dit "N+1 requêtes" (<em>N+1 queries problem</em>).<br> +En effet, pour que l'exemple ci-dessus s'exécute, il faut 1 requête pour récupérer l'objet <code>$user</code>, puis 1 requête pour chaque objet <code>$topic</code>. Et comme on le voit dans l'exemple, il est tout à fait possible d'invoquer les relations d'une relation, et ce sans limite. Ce qui augmente d'autant le nombre de requêtes SQL !<br> +Pour éviter cela, il est possible, dès la récupération de l'objet <code>$user</code>, de demander à ce que soient en même temps chargées ses relations (et leurs relations, et…).</p> + +<p>Le début de l'exemple ci-dessus devient alors :</p> + +<pre><code class="php"><span class="c1">// UserController.php</span> +<span class="nv">$user</span> <span class="o">=</span> <span class="nx">User</span><span class="o">::</span><span class="na">where</span><span class="p">(</span><span class="s1">'id'</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">with</span><span class="p">(</span><span class="s1">'topics'</span><span class="p">,</span> <span class="s1">'topics.comments'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">first</span><span class="p">();</span></code></pre> + +<p>Le nombre de requêtes chute alors, puisqu'il en faut toujours une seule pour charger <code>$user</code> (ça ne change pas), mais aussi une seule pour charger tous les <code>topics</code> appartenant à <code>$user</code>, et une autre pour charger tous les <code>comments</code> de tous les <code>topics</code> appartenant à <code>$user</code>. On passe donc de M*N + 1 requêtes, à 3 !</p> + +<p>Problème résolu, alors ? Pas tout à fait. Si la méthode <code>with()</code> résout bien le problème, encore faut-il l'utiliser !<br> +Et c'est là qu'intervient <a href="https://laravel-news.com/disable-eloquent-lazy-loading-during-development">la nouveauté en question</a>, consistant à désactiver le lazy-loading, pour forcer Laravel à lever une exception, et ainsi détecter les endroits dans le code ne recourant pas encore à la méthode <code>with()</code>.<br> +À noter que ce mécanisme de désactivation du lazy-loading est global. C'est donc la totalité du projet qui est susceptible de lever des exceptions. Il est donc préférable de faire ça en local d'abord (mais si vous êtes du genre à débugguer en production, allez-y !)</p> +<h3 id="toc-et-maintenant">Et maintenant ?</h3> +<h4 id="toc-laravel-9-lts">Laravel 9 LTS</h4> + +<p>Comme dit plus haut, Laravel 9 LTS a été reporté. Mais des premières infos sur ce que contiendra cette version ont déjà été annoncées :<br> +- Support de PHP 8.0 minimum ;<br> +- Utilisation de Symfony 6.0, pour les briques logicielles qui en proviennent ;<br> +- <code>Anonymous Stub Migrations</code> : désormais, ce comportement sera par défaut (cf. plus haut, pour plus d'infos sur ce qu'est cette fonctionnalité) ;<br> +- …</p> +<h4 id="toc-laracon-2021">Laracon 2021</h4> + +<p>Laracon, la conférence annuelle autour de Laravel, <a href="https://laracon.net/">aura lieu le 1er septembre 2021</a>.</p> +</div><div><a href="https://linuxfr.org/news/laravel-8-est-sorti.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/122771/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/laravel-8-est-sorti#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>windu.2b</name> + </author> + <author> + <name>Anonyme</name> + </author> + <author> + <name>Benoît Sibaud</name> + </author> + <author> + <name>yal</name> + </author> + <author> + <name>palm123</name> + </author> + <category term="PHP"/> + <category term="laravel"/> + <category term="php"/> + <wfw:commentRss>https://linuxfr.org/nodes/122771/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/40437</id> + <published>2021-04-26T10:43:40+02:00</published> + <updated>2021-04-26T10:43:40+02:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/prestashop-diffuse-chaque-mois-les-avancees-du-projet-sur-youtube"/> + <title>PrestaShop diffuse chaque mois les avancées du projet sur YouTube</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>Depuis janvier 2021, le logiciel libre <a href="https://www.prestashop.com/">PrestaShop</a>, sous licence <a href="https://fr.wikipedia.org/wiki/Open_Software_License">Open Software</a>, a commencé à faire… de la visioconférence.</p> + +<p>Chaque mois, l’équipe de mainteneurs héberge <a href="https://build.prestashop.com/news/first-public-oss-demo/">une session de visioconférence</a> sur YouTube dans laquelle sont présentées en anglais les dernières nouvelles concernant le projet (changements structurels, nouvelle versions) ainsi que les derniers travaux réalisés.</p> + +<p>Ces sessions vidéo récurrentes sont appelées « Démonstrations publiques open source de PrestaShop », peuvent être vues en temps réel puis sont disponibles en replay sur la chaîne <a href="https://www.youtube.com/channel/UCchgBHHhl5Vu7HgjrzpvVQQ">YouTube</a>.</p> + +<p>Les sessions ont lieu chaque dernier mercredi du mois. La session d’avril aura lieu le <a href="https://www.youtube.com/watch?v=VKb39T_6WHU">28 Avril à 14h</a>.</p> +</div><ul><li>lien náµ’Â 1 : <a title="https://www.prestashop.com/fr" hreflang="fr" href="https://linuxfr.org/redirect/108307">PrestaShop</a></li><li>lien náµ’Â 2 : <a title="https://www.youtube.com/channel/UCchgBHHhl5Vu7HgjrzpvVQQ" hreflang="en" href="https://linuxfr.org/redirect/108308">Chaîne YouTube des mainteneurs</a></li><li>lien náµ’Â 3 : <a title="https://build.prestashop.com/news/first-public-oss-demo/" hreflang="en" href="https://linuxfr.org/redirect/108309">Présentation des Démonstrations publiques open source</a></li><li>lien náµ’Â 4 : <a title="https://build.prestashop.com/news/public-oss-demo-3/" hreflang="en" href="https://linuxfr.org/redirect/108310">Résumé de la session de Mars</a></li></ul><div></div><div><a href="https://linuxfr.org/news/prestashop-diffuse-chaque-mois-les-avancees-du-projet-sur-youtube.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/124052/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/prestashop-diffuse-chaque-mois-les-avancees-du-projet-sur-youtube#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>Mathieu Ferment</name> + </author> + <author> + <name>Ysabeau</name> + </author> + <author> + <name>palm123</name> + </author> + <author> + <name>Pierre Jarillon</name> + </author> + <category term="PHP"/> + <category term="php"/> + <category term="prestashop"/> + <wfw:commentRss>https://linuxfr.org/nodes/124052/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/40240</id> + <published>2021-01-06T09:02:53+01:00</published> + <updated>2021-01-06T09:02:53+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/sortie-de-snuffleupagus-0-7-0-los-elefantes"/> + <title>Sortie de Snuffleupagus 0.7.0 - Los Elefantes </title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p><img src="//img.linuxfr.org/img/68747470733a2f2f6475737472692e6f72672f622f696d616765732f73702e706e67/sp.png" alt="Logo du projet" title="Source : https://dustri.org/b/images/sp.png"></p> + +<p>Snuffleupagus est un module pour PHP, version 7+ et maintenant 8+, qui a pour but d’augmenter drastiquement la difficulté des attaques contre les sites Web. Cela s’obtient, entre autres, via la désactivation de fonctions et de classes, et en fournissant un système de correctifs virtuels, permettant à l’administrateur de corriger des vulnérabilités spécifiques sans modifier le code PHP.</p> + +<p>La version 0.7.0 sortie aujourd’hui, est un excellent prétexte pour reparler de ce projet sur LinuxFr.org</p> +</div><ul><li>lien náµ’Â 1 : <a title="https://linuxfr.org/news/snuffleupagus-version-0-3-0-dentalium-elephantinum" hreflang="fr" href="https://linuxfr.org/redirect/107641">Dépêche précédente sur Snuffleupagus version-0-3-0</a></li><li>lien náµ’Â 2 : <a title="https://dustri.org/b/snuffleupagus-070-los-elefantes.html" hreflang="en" href="https://linuxfr.org/redirect/107642">Billet de blog d&#39;annonce de la nouvelle version</a></li><li>lien náµ’Â 3 : <a title="https://snuffleupagus.readthedocs.io/" hreflang="en" href="https://linuxfr.org/redirect/107643">Site officiel</a></li><li>lien náµ’Â 4 : <a title="https://twitter.com/sp_php" hreflang="en" href="https://linuxfr.org/redirect/107647">Compte twitter du projet</a></li><li>lien náµ’Â 5 : <a title="https://github.com/jvoisin/snuffleupagus" hreflang="en" href="https://linuxfr.org/redirect/107648">Dépôt github</a></li></ul><div><p>La principale nouveauté de cette version est le support de <a href="https://www.php.net/releases/8.0/fr.php">PHP 8</a>, qui bien que n’ayant pas été très difficile fût fastidieuse. En effet, PHP a changé la capitalisation de certains de ses messages d’erreurs, ainsi que les paramètres par défaut de logging, cassant un grand nombre de tests unitaires. Quitte à moderniser le code, autant faire les choses à fond, en utilisant PCRE2 autant que possible tout en maintenant la compatibilité avec PCRE1 pour les <em>vieilles</em> versions de PHP. En effet, Snuffleupagus supporte toutes les versions de PHP7, y compris les versions en fin de vie, qui continuent d’exister dans certaines distributions linux bénéficiaire de support long.</p> + +<p>C’est également l’occasion de corriger un bogue passé inaperçu jusqu’ici : le <a href="https://www.php.net/manual/fr/migration70.new-features.php">mode de typage strict</a> apporté par Snuffleupagus n’était pas désactivable. Ce souci a été mis en lumière grâce à un bug dans <a href="https://github.com/composer/composer/pull/9498">composer</a>, qui a au passage été corrigé. La bonne nouvelle, c’est que ce bogue n’a pas dû embêter grand monde pour ne jamais avoir été rencontré avant : soit personne n’utilise Snuffleupagus, soit les gens l’utilisant ont des bases de codes suffisamment propres pour ne pas comporter de fautes de types !</p> + +<p>D’autres fonctionnalités mineures ont également été ajoutées, comme la possibilité de « sauter » des fonctions avec l’opérateur <code>&gt;</code>: par exemple, la règle <code>sp.disable_function("bla&gt;blop").drop()</code> terminera l’exécution si la fonction <code>blop</code> a dans ses parents la fonction <code>bla</code>. Ce qui devrait permettre d’écrire facilement des règles pour se prémunir des attaques basées sur de la désérialisation, en interdisant à des fonctions dangereuses de s’exécuter si <code>unserialize</code> est dans leurs fonctions parentes.</p> + +<p>Afin d’obtenir toujours plus de visibilité, les requêtes sauvegardées lorsqu’une règle de filtrage est déclenchée contiennent maintenant l’ensemble de l’arbre d’appel des fonctions, permettant de comprendre le cheminement qui a mené à la règle.</p> + +<p>Tout ça c’est intéressant, mais est-ce que Snuffleupagus fonctionne ? Il semblerait que oui : un des auteurs publie <a href="https://dustri.org/b/snuffleupagus-versus-recent-high-profile-vulnerabilities.html">chaque</a> <a href="https://dustri.org/b/snuffleupagus-versus-recent-high-profile-vulnerabilities-again.html">année</a> une rétrospective des résultats du logiciel contre les vulnérabilités les plus critiques. Force est de constater que la plupart des failles sont soit rendues inexploitables, soit le deviennent moins trivialement.</p> + +<p>Quid de la suite ? Bien que le projet ait été abandonné par la société l’ayant open-sourcé (<a href="https://www.nbs-system.com/">NBS-System</a>), un des auteurs principaux continue de maintenir et de faire évoluer le projet, qui continue son bonhomme de chemin, gagnant en fonctionnalités tout en perdant des bugs.</p> +</div><div><a href="https://linuxfr.org/news/sortie-de-snuffleupagus-0-7-0-los-elefantes.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/122799/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/sortie-de-snuffleupagus-0-7-0-los-elefantes#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>jvoisin</name> + </author> + <author> + <name>Xavier Teyssier</name> + </author> + <author> + <name>Ysabeau</name> + </author> + <author> + <name>palm123</name> + </author> + <author> + <name>Anonyme</name> + </author> + <author> + <name>tisaac</name> + </author> + <author> + <name>Pierre Jarillon</name> + </author> + <category term="PHP"/> + <category term="php"/> + <category term="php8"/> + <category term="web"/> + <category term="php7"/> + <category term="sécurité"/> + <category term="suhosin"/> + <wfw:commentRss>https://linuxfr.org/nodes/122799/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/40208</id> + <published>2020-12-17T09:44:32+01:00</published> + <updated>2020-12-17T12:50:08+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/sortie-de-prestashop-1-7-7-0"/> + <title>Sortie de PrestaShop 1.7.7.0</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>Après presque un an de développement, PrestaShop vient de sortir la version 1.7.7 de son système de gestion de contenu (CMS) de commerce en ligne.</p> + +<p><img src="//img.linuxfr.org/img/68747470733a2f2f6173736574732e70726573746173686f70322e636f6d2f73697465732f64656661756c742f66696c65732f696d675f72696768745f6865616465725f6f7074696d697a65645f315f355f312e706e67/img_right_header_optimized_1_5_1.png" alt="Créer une boutique en ligne" title="Source : https://assets.prestashop2.com/sites/default/files/img_right_header_optimized_1_5_1.png"></p> + +<p>Cette version est principalement tournée vers des améliorations pour les utilisateurs marchands ; les pages du Back Office dédiées à l’administration des commandes ont été refaites entièrement et repensées pour faciliter la tâche au marchand.</p> + +<p>D’autres fonctionnalités ont été également livrées : la création et la gestion de devises non officielles, une recherche textuelle plus intelligente,etc., ainsi qu’un gros lot de corrections de bogues (160) et la compatibilité avec <a href="https://fr.wikipedia.org/wiki/PHP">PHP</a> 7.3 (il était temps !).</p> + +<p>La liste complète des nouveautés est disponible dans les <a href="https://build.prestashop.com/news/prestashop-1-7-7-0-available/">notes de publication</a> (en anglais).</p> + +<p>La communauté PrestaShop est très active, aussi bien sur le dépôt <a href="https://github.com/PrestaShop/PrestaShop/">GitHub</a>, qui sert également au suivi des bogues, que sur le <a href="https://www.prestashop.com/forums/">forum</a> ou le canal <a href="https://github.com/PrestaShop/open-source/blob/master/slack/readme.md">Slack</a>. N’hésitez pas à venir échanger avec nos communautés de marchands ou de développeurs !</p> +</div><ul><li>lien náµ’Â 1 : <a title="https://www.prestashop.com/fr" hreflang="fr" href="https://linuxfr.org/redirect/107523">PrestaShop</a></li><li>lien náµ’Â 2 : <a title="https://build.prestashop.com/news/prestashop-1-7-7-0-available/" hreflang="en" href="https://linuxfr.org/redirect/107524">Notes de publication de la version 1.7.7.0</a></li><li>lien náµ’Â 3 : <a title="https://www.prestashop.com/fr/telecharger" hreflang="fr" href="https://linuxfr.org/redirect/107525">Téléchargement</a></li></ul><div></div><div><a href="https://linuxfr.org/news/sortie-de-prestashop-1-7-7-0.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/122593/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/sortie-de-prestashop-1-7-7-0#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>Mathieu Ferment</name> + </author> + <author> + <name>Xavier Teyssier</name> + </author> + <author> + <name>Davy Defaud</name> + </author> + <author> + <name>Ysabeau</name> + </author> + <author> + <name>palm123</name> + </author> + <category term="PHP"/> + <category term="php"/> + <category term="cms"/> + <category term="symfony"/> + <category term="prestashop"/> + <wfw:commentRss>https://linuxfr.org/nodes/122593/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/40069</id> + <published>2020-11-28T20:11:28+01:00</published> + <updated>2020-11-29T16:23:33+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/les-nouvelles-fonctionnalites-de-php-8"/> + <title>Les nouvelles fonctionnalités de PHP 8</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>La version 8 de PHP est sortie le 26 novembre 2020, nous allons donc voir ensemble les nouvelles fonctionnalités qui ont été intégrées dans cette version.</p> + +<p>Pour ne pas faire trop long, on se limitera aux choses nouvelles par rapport à PHP 7.4, et on regardera les nouvelles fonctionnalités principales, pour une liste exhaustive consultez le journal des modifications officiel.</p> +</div><ul><li>lien náµ’Â 1 : <a title="https://stitcher.io/blog/new-in-php-8" hreflang="en" href="https://linuxfr.org/redirect/107365">Article anglophone plus complet sur les nouveautés</a></li><li>lien náµ’Â 2 : <a title="https://www.php.net/releases/8.0/en.php" hreflang="en" href="https://linuxfr.org/redirect/107368">Annonce officielle</a></li><li>lien náµ’Â 3 : <a title="https://www.php.net/ChangeLog-8.php" hreflang="en" href="https://linuxfr.org/redirect/107369">Journal des modifications détaillé</a></li><li>lien náµ’Â 4 : <a title="https://www.php.net/manual/en/migration80.php" hreflang="en" href="https://linuxfr.org/redirect/107370">Guide de migration</a></li></ul><div><h2 class="sommaire">Sommaire</h2> +<ul class="toc"> +<li> +<a href="#toc-nouvelles-fonctionnalit%C3%A9s">Nouvelles fonctionnalités</a><ul> +<li> +<a href="#toc-syntaxe">Syntaxe</a><ul> +<li><a href="#toc-les-unions-de-types">Les unions de types</a></li> +<li><a href="#toc-type-mixed">Type « mixed »</a></li> +<li><a href="#toc-type-de-retour-static">Type de retour « static »</a></li> +<li><a href="#toc-les-attributs">Les attributs</a></li> +<li><a href="#toc-les-param%C3%A8tres-nomm%C3%A9s">Les paramètres nommés</a></li> +<li><a href="#toc-la-promotion-de-param%C3%A8tres-constructeurs">La promotion de paramètres constructeurs</a></li> +<li><a href="#toc-op%C3%A9rateur-nullsafe">Opérateur « nullsafe »</a></li> +<li><a href="#toc-motclef-match">Mot‑clef « match »</a></li> +<li><a href="#toc-nouvelles-classes-et-interfaces">Nouvelles classes et interfaces</a></li> +<li><a href="#toc-autres-nouveaut%C3%A9s">Autres nouveautés</a></li> +</ul> +</li> +<li> +<a href="#toc-biblioth%C3%A8que-standard">Bibliothèque standard</a><ul> +<li><a href="#toc-printf">printf()</a></li> +<li><a href="#toc-proc_open">proc_open()</a></li> +<li><a href="#toc-fonctions-de-tri">Fonctions de tri</a></li> +<li><a href="#toc-nouvelles-fonctions-sur-les-cha%C3%AEnes-de-caract%C3%A8res">Nouvelles fonctions sur les chaînes de caractères</a></li> +<li><a href="#toc-op%C3%A9rations-sur-les-tableaux">Opérations sur les tableaux</a></li> +</ul> +</li> +<li> +<a href="#toc-extensions">Extensions</a><ul> +<li><a href="#toc-hash">Hash</a></li> +<li><a href="#toc-openssl">OpenSSL</a></li> +</ul> +</li> +<li> +<a href="#toc-performances">Performances</a><ul> +<li><a href="#toc-jit">JIT</a></li> +</ul> +</li> +</ul> +</li> +</ul> +<h2 id="toc-nouvelles-fonctionnalités">Nouvelles fonctionnalités</h2> +<h3 id="toc-syntaxe">Syntaxe</h3> +<h4 id="toc-les-unions-de-types">Les unions de types</h4> + +<p>PHP continue sa route vers un langage fortement typé, en ajoutant le support des unions de types dans les spécificateurs de type de paramètres, de variables ou de retour de fonction.</p> + +<p>L’exemple de la <a href="https://wiki.php.net/rfc/union_types_v2">RFC</a> :</p> + +<pre><code class="php"><span class="k">class</span> <span class="nc">Number</span> <span class="p">{</span> + <span class="k">private</span> <span class="nx">int</span><span class="o">|</span><span class="nx">float</span> <span class="nv">$number</span><span class="p">;</span> + + <span class="k">public</span> <span class="k">function</span> <span class="nf">setNumber</span><span class="p">(</span><span class="nx">int</span><span class="o">|</span><span class="nx">float</span> <span class="nv">$number</span><span class="p">)</span><span class="o">:</span> <span class="nx">void</span> <span class="p">{</span> + <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">number</span> <span class="o">=</span> <span class="nv">$number</span><span class="p">;</span> + <span class="p">}</span> + + <span class="k">public</span> <span class="k">function</span> <span class="nf">getNumber</span><span class="p">()</span><span class="o">:</span> <span class="nx">int</span><span class="o">|</span><span class="nx">float</span> <span class="p">{</span> + <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">number</span><span class="p">;</span> + <span class="p">}</span> +<span class="p">}</span></code></pre> + +<p>Cela permet de mettre des informations de type à des endroits où l’on ne pouvait pas en mettre, lorsque plusieurs types différents sont acceptés ou retournés.</p> +<h4 id="toc-type-mixed">Type « mixed »</h4> + +<p>Toujours à propos des types, le type <code>mixed</code> a été ajouté (<em>cf.</em> <a href="https://wiki.php.net/rfc/mixed_type_v2">RFC</a>). Il indique qu’une variable peut être de n’importe quel type pris en charge par PHP.</p> + +<p>Ça peut sembler idiot puisque ça revient au même que de ne pas mettre d’indication de type, mais ça permet au développeur de l’indiquer explicitement, et il existe de nombreux cas de figure où il est tout à fait normal d’accepter tous les types (pour une fonction de sérialisation, par exemple). Cela peut aussi servir à indiquer qu’une fonction doit retourner quelque chose, c’est donc le contraire de <code>:void</code> qui indique l’absence de retour.</p> + +<p>Aussi le mot-clé <code>mixed</code> était déjà largement utilisé dans la documentation de PHP.</p> +<h4 id="toc-type-de-retour-static">Type de retour « static »</h4> + +<p>Puisqu’on parle de typage, il est maintenant possible d’indiquer « <code>static</code> » comme type de retour pour une méthode. Cela signifie qu’elle renvoie une instance de la classe sur laquelle la méthode est appelée. À noter qu’il existait déjà le type de retour « <code>self</code> » pour indiquer qu’une méthode renvoie une instance de la classe à laquelle elle appartient, ce qui n’est pas la même chose. Voir la notion PHP de « <em><a href="https://www.php.net/manual/fr/language.oop5.late-static-bindings.php">late static binding</a></em> » [<a href="https://wiki.php.net/rfc/static_return_type">RFC</a>].</p> + +<p>Exemple :</p> + +<pre><code class="php"><span class="k">class</span> <span class="nc">Test</span> <span class="p">{</span> + <span class="k">public</span> <span class="k">function</span> <span class="nf">create</span><span class="p">()</span><span class="o">:</span> <span class="k">static</span> <span class="p">{</span> + <span class="k">return</span> <span class="k">new</span> <span class="k">static</span><span class="p">();</span> + <span class="p">}</span> +<span class="p">}</span></code></pre> +<h4 id="toc-les-attributs">Les attributs</h4> + +<p>Largement la plus grosse source de débats internes pour cette version, les attributs ont fait leur apparition.</p> + +<p>Un attribut, parfois appelé annotation dans d’autres langages, est une métadonnée qui peut être ajoutée sur une fonction, une classe, un paramètre, une propriété… Cette métadonnée est ensuite disponible par réflexion.</p> + +<p>Après être passée par <code>&lt;&lt;Attribute&gt;&gt;</code> et <code>@@Attribute</code>, c’est finalement la syntaxe <code>#[Attribute]</code> qui a été choisie au bout de quatre RFC, syntaxe déjà utilisée par Rust. La notation <code>@Attribute</code> utilisée dans beaucoup d’autres langages n’était pas disponible, puisque l’opérateur <code>@</code> existe déjà en PHP et sert à ignorer les erreurs.</p> + +<p>RFC :</p> + +<ul> +<li> +<em><a href="https://wiki.php.net/rfc/attributes">attributes</a></em> ;</li> +<li> +<em><a href="https://wiki.php.net/rfc/attribute_amendments">attribute amendments</a></em> ;</li> +<li> +<em><a href="https://wiki.php.net/rfc/shorter_attribute_syntax">shorter attribute syntax</a></em> ;</li> +<li> +<em><a href="https://wiki.php.net/rfc/shorter_attribute_syntax_change">shorter attribute syntax change</a></em>.</li> +</ul> +<h4 id="toc-les-paramètres-nommés">Les paramètres nommés</h4> + +<p>Un autre gros morceau de cette version est la prise en charge des paramètres nommés, ce qui signifie qu’il est possible d’indiquer la valeur d’un paramètre de fonction par son nom plutôt que par sa position.</p> + +<p>Exemples tirés de la RFC :</p> + +<pre><code class="php"><span class="nb">htmlspecialchars</span><span class="p">(</span><span class="nv">$string</span><span class="p">,</span> <span class="nx">double_encode</span><span class="o">:</span> <span class="k">false</span><span class="p">);</span> + +<span class="c1">// Au lieu de</span> +<span class="nb">htmlspecialchars</span><span class="p">(</span><span class="nv">$string</span><span class="p">,</span> <span class="nx">ENT_COMPAT</span> <span class="o">|</span> <span class="nx">ENT_HTML401</span><span class="p">,</span> <span class="s1">'UTF-8'</span><span class="p">,</span> <span class="k">false</span><span class="p">);</span> + +<span class="nb">array_fill</span><span class="p">(</span><span class="nx">start_index</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">num</span><span class="o">:</span> <span class="mi">100</span><span class="p">,</span> <span class="nx">value</span><span class="o">:</span> <span class="mi">50</span><span class="p">);</span> + +<span class="c1">// Au lieu de</span> +<span class="nb">array_fill</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">50</span><span class="p">);</span> +<span class="c1">// L’ordre n’est plus important, cette version est équivalente</span> +<span class="nb">array_fill</span><span class="p">(</span><span class="nx">value</span><span class="o">:</span> <span class="mi">50</span><span class="p">,</span> <span class="nx">num</span><span class="o">:</span> <span class="mi">100</span><span class="p">,</span> <span class="nx">start_index</span><span class="o">:</span> <span class="mi">0</span><span class="p">);</span></code></pre> + +<p>Ce changement signifie que les noms des paramètres font maintenant partie de la signature des fonctions, et que renommer un paramètre de fonction peut casser du code qui utilise la fonction. Pour cette raison un gros travail d’amélioration et d’uniformisation des noms de paramètres a été fait pour PHP 8, et dans les versions suivantes un renommage sera considéré comme cassant la compatibilité descendante [<a href="https://wiki.php.net/rfc/named_params">RFC</a>].</p> +<h4 id="toc-la-promotion-de-paramètres-constructeurs">La promotion de paramètres constructeurs</h4> + +<p>Dans le but de simplifier l’écriture de classes simples servant simplement de schéma pour des objets contenant des données, et pour encourager leur utilisation plutôt que celle de tableaux, il est maintenant possible de déclarer les propriétés d’une classe directement dans les paramètres du constructeur, afin de ne pas avoir à les écrire deux fois [<a href="https://wiki.php.net/rfc/constructor_promotion">RFC</a>].</p> + +<p>Exemple :</p> + +<pre><code class="php"><span class="c1">// Avant</span> +<span class="k">class</span> <span class="nc">Point</span> <span class="p">{</span> + <span class="k">public</span> <span class="nx">float</span> <span class="nv">$x</span><span class="p">;</span> + <span class="k">public</span> <span class="nx">float</span> <span class="nv">$y</span><span class="p">;</span> + <span class="k">public</span> <span class="nx">float</span> <span class="nv">$z</span><span class="p">;</span> + + <span class="k">public</span> <span class="k">function</span> <span class="fm">__construct</span><span class="p">(</span> + <span class="nx">float</span> <span class="nv">$x</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="nx">float</span> <span class="nv">$y</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="nx">float</span> <span class="nv">$z</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="p">)</span> <span class="p">{</span> + <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">x</span> <span class="o">=</span> <span class="nv">$x</span><span class="p">;</span> + <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">y</span> <span class="o">=</span> <span class="nv">$y</span><span class="p">;</span> + <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">z</span> <span class="o">=</span> <span class="nv">$z</span><span class="p">;</span> + <span class="p">}</span> +<span class="p">}</span> + +<span class="c1">// En PHP&gt;=8.0</span> +<span class="k">class</span> <span class="nc">Point</span> <span class="p">{</span> + <span class="k">public</span> <span class="k">function</span> <span class="fm">__construct</span><span class="p">(</span> + <span class="k">public</span> <span class="nx">float</span> <span class="nv">$x</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="k">public</span> <span class="nx">float</span> <span class="nv">$y</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="k">public</span> <span class="nx">float</span> <span class="nv">$z</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="p">)</span> <span class="p">{}</span> +<span class="p">}</span></code></pre> + +<p>À noter que cette nouveauté se marie particulièrement bien avec les paramètres nommés :</p> + +<pre><code class="php"><span class="k">class</span> <span class="nc">Circle</span> <span class="p">{</span> + <span class="k">public</span> <span class="k">function</span> <span class="fm">__construct</span><span class="p">(</span> + <span class="k">public</span> <span class="nx">float</span> <span class="nv">$x</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="k">public</span> <span class="nx">float</span> <span class="nv">$y</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="k">public</span> <span class="nx">float</span> <span class="nv">$z</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span> + <span class="k">public</span> <span class="nx">float</span> <span class="nv">$r</span> <span class="o">=</span> <span class="mf">1.0</span><span class="p">,</span> + <span class="k">public</span> <span class="nx">string</span> <span class="nv">$name</span> <span class="o">=</span> <span class="s1">''</span><span class="p">,</span> + <span class="k">public</span> <span class="nx">string</span> <span class="nv">$color</span> <span class="o">=</span> <span class="s1">'black'</span><span class="p">,</span> + <span class="p">)</span> <span class="p">{}</span> +<span class="p">}</span> + +<span class="nv">$c1</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Circle</span><span class="p">(</span><span class="nx">x</span><span class="o">:</span><span class="mi">12</span><span class="p">,</span> <span class="nx">y</span><span class="o">:</span><span class="mi">13</span><span class="p">,</span> <span class="nx">r</span><span class="o">:</span><span class="mi">5</span><span class="p">,</span> <span class="nx">name</span><span class="o">:</span><span class="s1">'C1'</span><span class="p">);</span></code></pre> +<h4 id="toc-opérateur-nullsafe">Opérateur « nullsafe »</h4> + +<p>Un nouvel opérateur <code>?-&gt;</code> a été ajouté [<a href="https://wiki.php.net/rfc/nullsafe_operator">RFC</a>]. Il permet d’appeler une fonction ou de récupérer une propriété de l’objet contenu dans la variable sans déclencher d’erreur si la variable est nulle. Cela permet par exemple de chaîner les appels de fonctions en autorisant une valeur nulle à plusieurs endroits de la chaîne.</p> + +<p>Exemple :</p> + +<pre><code class="php"><span class="c1">// Le code suivant</span> +<span class="nv">$country</span> <span class="o">=</span> <span class="k">null</span><span class="p">;</span> + +<span class="k">if</span> <span class="p">(</span><span class="nv">$session</span> <span class="o">!==</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span> + <span class="nv">$user</span> <span class="o">=</span> <span class="nv">$session</span><span class="o">-&gt;</span><span class="na">user</span><span class="p">;</span> + + <span class="k">if</span> <span class="p">(</span><span class="nv">$user</span> <span class="o">!==</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span> + <span class="nv">$address</span> <span class="o">=</span> <span class="nv">$user</span><span class="o">-&gt;</span><span class="na">getAddress</span><span class="p">();</span> + + <span class="k">if</span> <span class="p">(</span><span class="nv">$address</span> <span class="o">!==</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span> + <span class="nv">$country</span> <span class="o">=</span> <span class="nv">$address</span><span class="o">-&gt;</span><span class="na">country</span><span class="p">;</span> + <span class="p">}</span> + <span class="p">}</span> +<span class="p">}</span> + +<span class="c1">// Peut maintenant être écrit</span> +<span class="nv">$country</span> <span class="o">=</span> <span class="nv">$session</span><span class="o">?-&gt;</span><span class="na">user</span><span class="o">?-&gt;</span><span class="na">getAddress</span><span class="p">()</span><span class="o">?-&gt;</span><span class="na">country</span><span class="p">;</span></code></pre> +<h4 id="toc-motclef-match">Mot‑clef « match »</h4> + +<p>Le mot‑clef <code>match</code> a été ajouté comme alternative au <code>switch</code> lorsque l’on cherche à retourner une valeur depuis chaque branche.</p> + +<p>Exemple :</p> + +<pre><code class="php"><span class="c1">// Avec switch</span> +<span class="k">switch</span> <span class="p">(</span><span class="nv">$mot</span><span class="p">)</span> <span class="p">{</span> + <span class="k">case</span> <span class="s1">'un'</span><span class="o">:</span> + <span class="nv">$nombre</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> + <span class="k">break</span><span class="p">;</span> + <span class="k">case</span> <span class="s1">'deux'</span><span class="o">:</span> + <span class="nv">$nombre</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span> + <span class="k">break</span><span class="p">;</span> + <span class="k">case</span> <span class="s1">'trois'</span><span class="o">:</span> + <span class="nv">$nombre</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span> + <span class="k">break</span><span class="p">;</span> + <span class="k">default</span><span class="o">:</span> + <span class="k">throw</span> <span class="k">new</span> <span class="nx">Exception</span> <span class="p">(</span><span class="s1">'Mot invalide'</span><span class="p">);</span> + <span class="k">break</span><span class="p">;</span> +<span class="p">}</span> + +<span class="c1">// Avec match</span> +<span class="nv">$nombre</span> <span class="o">=</span> <span class="nx">match</span> <span class="p">(</span><span class="nv">$mot</span><span class="p">)</span> <span class="p">{</span> + <span class="s1">'un'</span> <span class="o">=&gt;</span> <span class="mi">1</span><span class="p">,</span> + <span class="s1">'deux'</span> <span class="o">=&gt;</span> <span class="mi">2</span><span class="p">,</span> + <span class="s1">'trois'</span> <span class="o">=&gt;</span> <span class="mi">3</span><span class="p">,</span> + <span class="k">default</span> <span class="o">=&gt;</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">Exception</span> <span class="p">(</span><span class="s1">'Mot invalide'</span><span class="p">),</span> +<span class="p">};</span></code></pre> + +<p>Lisez attentivement la <a href="https://wiki.php.net/rfc/match_expression_v2">RFC</a> pour la liste des subtiles différences avec <code>switch</code>.</p> +<h4 id="toc-nouvelles-classes-et-interfaces">Nouvelles classes et interfaces</h4> + +<p>La classe <code>WeakMap</code> a été ajoutée. Elle permet de gérer des correspondances avec des objets en clefs, qui n’empêchent pas ces objets d’être détruits par le ramasse‑miettes. Quand un objet est détruit, la valeur qui lui est associée est simplement retirée de la <code>WeakMap</code> [<a href="https://wiki.php.net/rfc/weak_maps">RFC</a>].</p> + +<p>Une nouvelle classe <code>ValueError</code> est lancée quand une méthode reçoit un paramètre du bon type mais avec une valeur inappropriée, pour différencier du cas des <code>TypeError</code>, qui apparaissent quand le paramètre n’a pas le bon type.</p> + +<p>Une nouvelle interface <code>Stringable</code> permet de reconnaître les objets qui peuvent être transtypés en <code>string</code>.<br> +Elle est automatiquement implémentée par les classes qui définissent la méthode magique <code>__toString()</code>.<br> +Cela permet, avec l’union des types, d’utiliser le groupe <code>string|Stringable</code> pour typer un paramètre qui accepte soit une chaîne de caractères, soit n’importe quel objet qui peut se transtyper en chaîne de caractères [<a href="https://wiki.php.net/rfc/stringable">RFC</a>].</p> +<h4 id="toc-autres-nouveautés">Autres nouveautés</h4> + +<ul> +<li>il est maintenant possible d’obtenir le nom de la classe d’un objet en utilisant <code>$object::class</code>, le résultat est le même que <code>get_class($object)</code> [<a href="https://wiki.php.net/rfc/class_name_literal_on_object">RFC</a>] ;</li> +<li> +<code>new</code> et <code>instanceof</code> peuvent maintenant être utilisés avec des expressions arbitraires, sous la forme <code>new (expression)(...$args)</code> et <code>$obj instanceof (expression)</code> [<a href="https://wiki.php.net/rfc/variable_syntax_tweaks">RFC</a>] ;</li> +<li>des changements ont été faits pour rendre la syntaxe des variables plus cohérentes, par exemple il est maintenant autorisé d’écrire <code>Foo::BAR::$baz</code> [<a href="https://wiki.php.net/rfc/variable_syntax_tweaks">RFC</a>] ;</li> +<li>les <a href="https://fr.wikipedia.org/wiki/Trait_(programmation)"><em>traits</em></a> peuvent maintenant définir des méthodes privées [<a href="https://wiki.php.net/rfc/abstract_trait_method_validation">RFC</a>] ;</li> +<li> +<code>throw</code> peut désormais être utilisé comme une expression [<a href="https://wiki.php.net/rfc/throw_expression">RFC</a>] ;</li> +<li>une virgule supplémentaire est autorisée à la fin des listes de paramètres, pour faciliter les choses quand on écrit un paramètre par ligne (notamment pour mieux versionner dans ces cas‑là ) [<a href="https://wiki.php.net/rfc/trailing_comma_in_parameter_list">RFC</a>] ;</li> +<li>il est maintenant possible d’écrire <code>catch (Exception)</code> pour capturer une exception sans la stocker dans une variable [<a href="https://wiki.php.net/rfc/non-capturing_catches">RFC</a>] ;</li> +<li>les méthodes privées déclarées sur une classe parente ne contraignent plus la signature des méthodes sur la classe fille (à l’exception des constructeurs finals privés) [<a href="https://wiki.php.net/rfc/inheritance_private_methods">RFC</a>] ;</li> +<li> +<p>un nombre variable de paramètres de méthode peut maintenant être remplacé par un paramètre variadique lors de l’héritage, tant que les types sont compatibles ; ceci est par exemple possible :</p> + +<pre><code class="php"><span class="k">class</span> <span class="nc">A</span> <span class="p">{</span> + <span class="k">public</span> <span class="k">function</span> <span class="nf">method</span><span class="p">(</span><span class="nx">int</span> <span class="nv">$many</span><span class="p">,</span> <span class="nx">string</span> <span class="nv">$parameters</span><span class="p">,</span> <span class="nv">$here</span><span class="p">)</span> <span class="p">{}</span> +<span class="p">}</span> +<span class="k">class</span> <span class="nc">B</span> <span class="k">extends</span> <span class="nx">A</span> <span class="p">{</span> + <span class="k">public</span> <span class="k">function</span> <span class="nf">method</span><span class="p">(</span><span class="o">...</span><span class="nv">$everything</span><span class="p">)</span> <span class="p">{}</span> +<span class="p">}</span></code></pre> +</li> +</ul> +<h3 id="toc-bibliothèque-standard">Bibliothèque standard</h3> +<h4 id="toc-printf">printf()</h4> + +<p>Les fonctions de la famille <code>printf()</code> supportent maintenant les spécificateurs de format <code>%h</code> et <code>%H</code>. Ils font pareil que <code>%g</code> et <code>%G</code> mais utilisent toujours le point comme séparateur des décimales au lieu de se fier à la régionalisation (<em>locale</em>) configurée via <code>LC_NUMERIC</code>.</p> + +<p>Il est également maintenant possible d’utiliser <code>*</code> comme largeur de champ ou précision de flottant, auquel cas la largeur/précision est passée comme argument à la fonction. Passer <code>-1</code> comme précision pour <code>%g</code>, <code>%G</code>, <code>%h</code> et <code>%H</code> permet de reproduire le comportement par défaut de PHP pour les flottants :</p> + +<pre><code class="php"><span class="nb">printf</span><span class="p">(</span><span class="s2">"%.*H"</span><span class="p">,</span> <span class="p">(</span><span class="nx">int</span><span class="p">)</span> <span class="nb">ini_get</span><span class="p">(</span><span class="s2">"precision"</span><span class="p">),</span> <span class="nv">$float</span><span class="p">);</span> +<span class="nb">printf</span><span class="p">(</span><span class="s2">"%.*H"</span><span class="p">,</span> <span class="p">(</span><span class="nx">int</span><span class="p">)</span> <span class="nb">ini_get</span><span class="p">(</span><span class="s2">"serialize_precision"</span><span class="p">),</span> <span class="nv">$float</span><span class="p">);</span></code></pre> +<h4 id="toc-proc_open">proc_open()</h4> + +<p>La fonction <code>proc_open()</code> gère maintenant des descripteurs de pseudo‑terminal (PTY) ; l’exemple suivant attache <em>stdin</em>, <em>stdout</em> et <em>stderr</em> au même PTY :</p> + +<pre><code class="php"><span class="nv">$proc</span> <span class="o">=</span> <span class="nb">proc_open</span><span class="p">(</span><span class="nv">$command</span><span class="p">,</span> <span class="p">[[</span><span class="s1">'pty'</span><span class="p">],</span> <span class="p">[</span><span class="s1">'pty'</span><span class="p">],</span> <span class="p">[</span><span class="s1">'pty'</span><span class="p">]],</span> <span class="nv">$pipes</span><span class="p">);</span></code></pre> + +<p><code>proc_open()</code> gère maintenant les <em><a href="https://fr.wikipedia.org/wiki/Berkeley_sockets">sockets</a></em>. L’exemple suivant attache des sockets distincts pour <em>stdin</em>, <em>stdout</em> et <em>stderr</em> :</p> + +<pre><code class="php"><span class="nv">$proc</span> <span class="o">=</span> <span class="nb">proc_open</span><span class="p">(</span><span class="nv">$command</span><span class="p">,</span> <span class="p">[[</span><span class="s1">'socket'</span><span class="p">],</span> <span class="p">[</span><span class="s1">'socket'</span><span class="p">],</span> <span class="p">[</span><span class="s1">'socket'</span><span class="p">]],</span> <span class="nv">$pipes</span><span class="p">);</span></code></pre> + +<p>Contrairement aux tubes (<em>pipes</em>), les <em>sockets</em> n’ont pas de problèmes de blocage d’entrées‑sorties sous Windows. Cependant, tous les programmes ne fonctionnent pas forcément correctement avec des <em>sockets</em>.</p> +<h4 id="toc-fonctions-de-tri">Fonctions de tri</h4> + +<p>Les différentes fonctions de tri sont maintenant stables, ce qui signifie que les éléments qui sont égaux selon la fonction de comparaison conservent maintenant leur ordre relatif d’avant le tri. Il y a un léger coût en performances mais cela peut éviter les mauvaises surprises [<a href="https://wiki.php.net/rfc/stable_sorting">RFC</a>].</p> +<h4 id="toc-nouvelles-fonctions-sur-les-chaînes-de-caractères">Nouvelles fonctions sur les chaînes de caractères</h4> + +<p>Les fonctions <code>str_contains()</code>, <code>str_starts_with()</code> et <code>str_ends_with()</code> ont été ajoutées, permettant de déterminer respectivement si une chaîne de caractères contient, commence par et finit par une autre chaîne. Ce sont des opérations très courantes, et s’il n’était pas difficile de les implémenter en PHP, le fait qu’il y ait plusieurs façons de faire pouvait perturber les développeurs.</p> + +<p>RFC :</p> + +<ul> +<li> +<em><a href="https://wiki.php.net/rfc/str_contains">str_contains()</a></em> ;</li> +<li> +<em><a href="https://wiki.php.net/rfc/add_str_starts_with_and_ends_with_functions">add str_starts_with() and str_ends_with() functions</a></em>.</li> +</ul> +<h4 id="toc-opérations-sur-les-tableaux">Opérations sur les tableaux</h4> + +<p>Les fonctions <code>array_diff()</code>, <code>array_intersect()</code> et leurs variations peuvent maintenant être utilisées avec un seul tableau en paramètre. Cela facilite leur utilisation avec l’opérateur <code>...</code> :</p> + +<pre><code class="php"><span class="c1">// Fonctionne même si $excludes est vide</span> +<span class="nb">array_diff</span><span class="p">(</span><span class="nv">$array</span><span class="p">,</span> <span class="o">...</span><span class="nv">$excludes</span><span class="p">);</span> + +<span class="c1">// Fonctionne même si $arrays contient un seul tableau</span> +<span class="nb">array_intersect</span><span class="p">(</span><span class="o">...</span><span class="nv">$arrays</span><span class="p">);</span></code></pre> +<h3 id="toc-extensions">Extensions</h3> +<h4 id="toc-hash">Hash</h4> + +<p>Les objets HashContext peuvent maintenant être sérialisés.</p> +<h4 id="toc-openssl">OpenSSL</h4> + +<p>Ajout du prise en charge de la RFC 5652, « <em>Cryptographic Message Syntax</em> (CMS) », avec des fonctions pour chiffrement, déchiffrement, signature, vérification et lecture. L’API est similaire à celle pour PKCS#7 avec l’ajout de nouvelles constantes : <code>OPENSSL_ENCODING_DER</code>, <code>OPENSSL_ENCODING_SMIME</code> et <code>OPENSSL_ENCODING_PEM</code>.</p> +<h3 id="toc-performances">Performances</h3> +<h4 id="toc-jit">JIT</h4> + +<p>Un compilateur à la volée (JIT — <em>Just In Time</em>) a été ajouté dans PHP afin de permettre, dans certains cas, d’augmenter les performances. La fonctionnalité est désactivée par défaut et n’apporte pas grand’chose dans le cadre d’application Web classiques. En revanche, pour des usages plus gourmands en calcul, par exemple un calcul de fractal qui a été utilisé pour les démos, le compilateur à la volée apporte un gain de performance très important. L’idée est donc de rendre PHP plus viable pour des usages pour lesquels il était trop lent auparavant.</p> +</div><div><a href="https://linuxfr.org/news/les-nouvelles-fonctionnalites-de-php-8.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/121816/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/les-nouvelles-fonctionnalites-de-php-8#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>MCMic</name> + </author> + <author> + <name>Julien Jorge</name> + </author> + <author> + <name>Davy Defaud</name> + </author> + <author> + <name>Christophe "CHiPs" PETIT</name> + </author> + <author> + <name>Julien Boudry</name> + </author> + <author> + <name>BenMorel</name> + </author> + <author> + <name>Ysabeau</name> + </author> + <author> + <name>Nils Ratusznik</name> + </author> + <author> + <name>theojouedubanjo</name> + </author> + <author> + <name>dourouc05</name> + </author> + <author> + <name>palm123</name> + </author> + <author> + <name>ted</name> + </author> + <category term="PHP"/> + <category term="php8"/> + <category term="php"/> + <category term="programmation"/> + <wfw:commentRss>https://linuxfr.org/nodes/121816/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/40149</id> + <published>2020-11-17T16:12:59+01:00</published> + <updated>2020-11-17T17:01:47+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/prestashop-ouvre-sa-gouvernance-open-source-aux-contributeurs-externes"/> + <title>PrestaShop ouvre sa gouvernance open source aux contributeurs externes</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>En septembre 2020, le logiciel libre <a href="https://www.prestashop.com/">PrestaShop</a>, sous licence <a href="https://fr.wikipedia.org/wiki/Open_Software_License">Open Software</a>, a ouvert la possibilité pour des contributeurs de postuler au rôle de mainteneur. Les règles pour postuler à ce rôle sont décrites dans la <a href="https://devdocs.prestashop.com/1.7/project/maintainers-guide/how-to-become-a-maintainer/">documentation du projet</a>. Pour mémoire, PrestaShop est un système de gestion de contenu français pour le commerce en ligne.</p> + +<p>N’importe qui peut postuler publiquement, et un vote des mainteneurs actuels décide de l’acceptation ou du rejet de cette candidature.</p> + +<p>Depuis cette date, quatre candidatures ont été exprimées et <a href="https://build.prestashop.com/news/coreweekly-43-2020/">deux d’entre elles</a> ont été acceptées. Ces deux nouveaux mainteneurs communautaires disposent des mêmes droits sur l’organisation que les mainteneurs salariés, dont le plus important est probablement celui de valider et fusionner des demandes d’intégration (<em>pull requests</em>) sur les dépôts Git de PrestaShop, <a href="https://github.com/PrestaShop">hébergés sur GitHub</a>.</p> +</div><ul><li>lien náµ’Â 1 : <a title="https://www.prestashop.com/fr" hreflang="fr" href="https://linuxfr.org/redirect/107311">PrestaShop</a></li><li>lien náµ’Â 2 : <a title="https://devdocs.prestashop.com/1.7/project/maintainers-guide/how-to-become-a-maintainer/" hreflang="en" href="https://linuxfr.org/redirect/107312">Comment devenir mainteneur — documentation PrestaShop</a></li><li>lien náµ’Â 3 : <a title="https://build.prestashop.com/news/coreweekly-38-2020/" hreflang="en" href="https://linuxfr.org/redirect/107313">Annonce de l’ouverture du rôle de mainteneur — Blog des développeurs de PrestaShop</a></li></ul><div></div><div><a href="https://linuxfr.org/news/prestashop-ouvre-sa-gouvernance-open-source-aux-contributeurs-externes.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/122254/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/prestashop-ouvre-sa-gouvernance-open-source-aux-contributeurs-externes#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>Mathieu Ferment</name> + </author> + <author> + <name>Davy Defaud</name> + </author> + <author> + <name>Xavier Teyssier</name> + </author> + <author> + <name>Ysabeau</name> + </author> + <category term="PHP"/> + <category term="php"/> + <category term="gouvernance"/> + <category term="open_source"/> + <wfw:commentRss>https://linuxfr.org/nodes/122254/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/39656</id> + <published>2020-04-16T15:51:13+02:00</published> + <updated>2020-04-16T17:49:44+02:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/condorcet-php-gestion-des-elections-alternatives"/> + <title>Condorcet PHP — Gestion des élections alternatives</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>Condorcet PHP est une bibliothèque logicielle libre (licence MIT) écrite en PHP et/ou un programme en ligne de commande. Il permet de gérer une élection, de l’enregistrement des votes, jusqu’au calcul des résultats par des algorithmes de votes dits « alternatifs », la plupart d’entre eux étant liés aux critères de Condorcet.</p> + +<p>Il dispose d’une API riche permettant une gestion intelligente et avancée des bulletins et des résultats, incluant des outils statistiques, de sécurité ainsi qu’une prise en compte des problématiques de cache et performances. Condorcet reste très simple à utiliser pour un besoin standard grâce à des méthodes et commandes explicites de haut niveau, ainsi qu’à de multiples formats utilisables.<br> +Son architecture modulaire permet d’étendre ou de personnaliser ses usages et algorithmes. Condorcet peut aussi s’interfacer avec des bases de données, supprimant toutes limites tant au nombre de votes gérés, promettant des performances linéaires en temps de calcul et stables en mémoire, parfaitement praticables avec un petit ordinateur domestique, même pour les plus improbables démesures.</p> + +<p>Initialement conçu en 2014 comme un très simple et monolithique code répondant à un besoin unique ; puis en tant que petit projet étudiant à l’ambition croissante, et fut de nombreuses fois réécrit au fil des gains de compétence de son développeur principal et de la maturation du projet. </p> +</div><ul><li>lien náµ’Â 1 : <a title="https://github.com/julien-boudry/Condorcet" hreflang="en" href="https://linuxfr.org/redirect/105616">Dépôt GitHub</a></li><li>lien náµ’Â 2 : <a title="https://hub.docker.com/r/julienboudry/condorcet" hreflang="en" href="https://linuxfr.org/redirect/105617">Dépôt Docker</a></li><li>lien náµ’Â 3 : <a title="https://github.com/julien-boudry/Condorcet/wiki" hreflang="en" href="https://linuxfr.org/redirect/105618">Wiki</a></li></ul><div><h2 class="sommaire">Sommaire</h2> +<ul class="toc"> +<li> +<a href="#toc-m%C3%A9thodes-de-votes-classiques--alternatives">Méthodes de votes classiques &amp; alternatives</a><ul> +<li><a href="#toc-syst%C3%A8mes-%C3%A9lectoraux-classiques">Systèmes électoraux classiques</a></li> +<li> +<a href="#toc-m%C3%A9thodes-de-condorcet--autres-syst%C3%A8mes-%C3%A9lectoraux">Méthodes de Condorcet &amp; autres systèmes électoraux</a><ul> +<li><a href="#toc-le-crit%C3%A8re-de-condorcet">Le critère de Condorcet</a></li> +<li><a href="#toc-les-m%C3%A9thodes-dites-de-condorcet">Les méthodes dites de Condorcet</a></li> +<li><a href="#toc-autres-m%C3%A9thodes--utilisations">Autres méthodes &amp; Utilisations</a></li> +</ul> +</li> +</ul> +</li> +<li> +<a href="#toc-fonctionnalit%C3%A9s-principales-de-condorcet-php">Fonctionnalités principales de Condorcet PHP</a><ul> +<li><a href="#toc-g%C3%A9rer-une-%C3%A9lection">Gérer une élection</a></li> +<li> +<a href="#toc-g%C3%A9n%C3%A9rer-les-r%C3%A9sultats">Générer les résultats</a><ul> +<li><a href="#toc-interactions">Interactions</a></li> +<li><a href="#toc-m%C3%A9thodes-disponibles">Méthodes disponibles</a></li> +</ul> +</li> +<li><a href="#toc-gestion-des-grandes-%C3%A9lections--des-milliards-de-votes-sur-un-mat%C3%A9riel-domestique-modeste">Gestion des grandes élections : des milliards de votes sur un matériel domestique modeste</a></li> +</ul> +</li> +<li> +<a href="#toc-code--architecture">Code &amp; Architecture</a><ul> +<li><a href="#toc-api-biblioth%C3%A8que-php">API (bibliothèque PHP)</a></li> +<li><a href="#toc-abstraction-et-programmation-orient%C3%A9e-objet">Abstraction et programmation orientée objet</a></li> +<li><a href="#toc-architecture-modulaire">Architecture modulaire</a></li> +<li><a href="#toc-performances">Performances</a></li> +<li><a href="#toc-langage-php-qualit%C3%A9-de-code-documentation-envergure">Langage PHP, qualité de code, documentation, envergure</a></li> +</ul> +</li> +<li> +<a href="#toc-continuation--d%C3%A9veloppements-">Continuation &amp; développements </a><ul> +<li><a href="#toc-ex%C3%A9cutable-en-ligne-de-commande">Exécutable en ligne de commande</a></li> +<li> +<a href="#toc-docker-ex%C3%A9cutables-paquets-interface-graphique">Docker, exécutables, paquets, interface graphique</a><ul> +<li><a href="#toc-image-docker">Image Docker</a></li> +<li><a href="#toc-ex%C3%A9cutable">Exécutable</a></li> +<li><a href="#toc-paquets-de-distributions-linux">Paquets de distributions Linux</a></li> +<li><a href="#toc-interface-graphique">Interface graphique</a></li> +</ul> +</li> +<li><a href="#toc-documentation-et-lisibilit%C3%A9-du-code">Documentation et lisibilité du code</a></li> +<li><a href="#toc-autres-m%C3%A9thodes-de-votes">Autres méthodes de votes</a></li> +<li><a href="#toc-perspectives-dactivit%C3%A9s">Perspectives d’activités</a></li> +</ul> +</li> +</ul> +<h2 id="toc-méthodes-de-votes-classiques--alternatives">Méthodes de votes classiques &amp; alternatives</h2> +<h3 id="toc-systèmes-électoraux-classiques">Systèmes électoraux classiques</h3> + +<p>L’écrasante majorité des systèmes électoraux actuels, qu’ils soient de natures institutionnelles, publiques ou privées, sont fondés sur des systèmes majoritaires et uninominaux. Vous ne choisissez qu’un seul candidat, ne transmettez aucune information sur la conviction ou la contextualisation de votre choix, et éliminez les autres candidats de votre vote.<br> +Ces systèmes ont le mérite de forcer à un certain engagement. Ils sont faciles à organiser et à expliquer, quoique le plus souvent structurés en deux tours.</p> + +<p>Mais ils souffrent aussi de défauts importants :</p> + +<ul> +<li>ils encouragent des votes stratégiques, par regroupements tactiques (présumés), plutôt que des votes de convictions ;</li> +<li>ils éliminent de la décision des courants minoritaires, qui se retrouvent en marge, même dans un système à plusieurs tours ;</li> +<li>ils ne favorisent de fait aucun consensus. La légitimité du vainqueur est donc souvent contestable car comble du scrutin majoritaire classique, celui remportant une élection n’est que rarement en mesure de justifier d’une approbation majoritaire non-contrainte (sans même parler d’abstention). C’est donc plutôt l’élimination de son concurrent du second tour qui produit un gagnant.</li> +</ul> + +<p><strong>Exemple :</strong></p> + +<p>Les systèmes électoraux classiques peuvent aussi aboutir à des décisions aberrantes, bien éloignées de l’intérêt commun.<br> +Nous allons prendre un exemple simple, celui de la construction d’un hôpital, que nous considérerons comme unique sur une région. La population de chaque ville va soutenir unanimement l’implémentation de celui-ci sur son propre territoire, selon ses intérêts propres. Nous convoquons pour ce faire les cités de quelques animés célèbres.</p> + +<p><img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6172746973616e61742d667572696575782e6e65742f7075626c69632f636f6e646f726365742d6578616d706c652d34322e504e47/condorcet-example-42.PNG" alt="Exemple géographique" title="Source : https://www.artisanat-furieux.net/public/condorcet-example-42.PNG"></p> + +<p><strong>Table des votes :</strong><br> +<em>(pour des raisons de simplifications et de démonstration, nous supposons que chaque habitant vote selon ses intérêts logiques propres, tous les habitants d’une même ville votent donc pareillement)</em></p> + +<table> +<thead> +<tr> +<th>New New York (42% des électeurs)</th> +<th>Springfield (9% des électeurs)</th> +<th>Lanwdale (27% des électeurs)</th> +<th>South Park (22% des électeurs)</th> +</tr> +</thead> +<tbody> +<tr> +<td>1. New New York</td> +<td>1. Springfield</td> +<td>1. Lanwdale</td> +<td>1. South Park</td> +</tr> +<tr> +<td>2. Springfield</td> +<td>2. New New York</td> +<td>2. South Park</td> +<td>2. Lawndale</td> +</tr> +<tr> +<td>3. Lawndale</td> +<td>3. Lawndale</td> +<td>3. Springfield</td> +<td>3. Springfield</td> +</tr> +<tr> +<td>4. South Park</td> +<td>4. South Park</td> +<td>4. New New York</td> +<td>4. New New York</td> +</tr> +</tbody> +</table> + +<p><strong>Que se passe-t-il avec une élection majoritaire à deux tours ?</strong></p> + +<p>Dans une élection classique (on ne garde que les têtes de séries de chaque bulletin) : New New York affrontera Lawndale au second tour, soit deux intérêts diamétralement opposés, New New York gagnera l’élection, laissant 49% de la population à 200 km ou plus de l’hôpital.<br> +Pourtant, si Springfield était choisie : 78% de la population vivrait à 130 km ou moins et jamais à plus de 170 km, 51% de la population y aurait accès dans un rayon de 100 km maximum.</p> +<h3 id="toc-méthodes-de-condorcet--autres-systèmes-électoraux">Méthodes de Condorcet &amp; autres systèmes électoraux</h3> + +<p>Il existe de nombreux autres systèmes électoraux possibles. Souvent plus complexes à appréhender au premier abord, car faisant intervenir des techniques mathématiques et des dépouillements plus complexes. Leurs pratiques, du point de vue d’un électeur restent toutefois très simples.<br> +On va ici s’intéresser aux systèmes dits de Condorcet, car respectant le mode de vote et le critère de la méthode de Condorcet. Ces méthodes sont pour la plupart implémentées dans Condorcet PHP.</p> + +<p>Toutes partagent la même méthode électorale : un seul tour, chaque électeur vote tout ou partie des candidats par ordre de préférence, avec égalités permises ou non selon les variantes.</p> +<h4 id="toc-le-critère-de-condorcet">Le critère de Condorcet</h4> + +<p>Ce critère doit bien son nom au <a href="https://fr.wikipedia.org/wiki/Nicolas_de_Condorcet">Marquis de Condorcet</a>, qui l’a établi ou du moins formalisé et popularisé en premier. Ce critère fonde la première méthode de Condorcet. Simplissime, elle ne peut prédire qu’un vainqueur et qu’un perdant absolu, sans classement intermédiaire <em>(sauf à tenter de recalculer en supprimant les candidats élus)</em>.</p> + +<p>Dans ce système de vote, est gagnant absolu le candidat qui, comparé à tous les autres, est systématiquement vainqueur. C’est ce que l’on appelle le duel de paires. À l’inverse, le perdant absolu est celui qui perd tous ses duels.</p> + +<p>Concrètement, lors du dépouillement, on va simuler tous les duels de paires possibles. Et pour chaque bulletin, attribuer au sein de chaque duel un point au candidat vainqueur dans chacun d’entre eux. Si un candidat est vainqueur pour chaque duel, ou au contraire perdant pour chaque duel, il est alors le gagnant/perdant de Condorcet.</p> + +<p><strong>Si l’on reprend l’exemple géographique précédent, voici la somme des duels de paires :</strong> </p> + +<table> +<thead> +<tr> +<th></th> +<th>New New York &gt; adv.</th> +<th>Springfield &gt; adv.</th> +<th>Lanwdale &gt; adv.</th> +<th>South Park &gt; adv.</th> +</tr> +</thead> +<tbody> +<tr> +<td>New New York &lt; adv.</td> +<td>-</td> +<td><strong>58</strong></td> +<td>49</td> +<td>49</td> +</tr> +<tr> +<td>Springfield &lt; adv.</td> +<td>42</td> +<td>-</td> +<td>49</td> +<td>49</td> +</tr> +<tr> +<td>Lanwdale &lt; adv.</td> +<td><strong>51</strong></td> +<td><strong>51</strong></td> +<td>-</td> +<td>22</td> +</tr> +<tr> +<td>South Park &lt; adv.</td> +<td><strong>51</strong></td> +<td><strong>51</strong></td> +<td><strong>78</strong></td> +<td>-</td> +</tr> +</tbody> +</table> + +<p><em>(Modalités et variantes : 100 votants, obligation de classer tous les candidats, classement exæquos interdits dans les bulletins. La majorité est donc forcément à 51 pour chaque duel de pair. Condorcet PHP gère d’autres variantes, cet exemple est donc très simple.)</em> </p> + +<p>Springfield gagne l’élection en tant que vainqueur de Condorcet, car il gagne tous ses duels, alors même qu’il dispose du plus faible nombre de partisans de premier rang. Et peut alors enrichir sa centrale nucléaire d’un hôpital attenant. South Park finit logiquement perdant de Condorcet, ne remportant aucun duel. La méthode originelle de Condorcet ne propose pas de classements intermédiaires. </p> + +<p><strong>Paradoxe de Condorcet :</strong></p> + +<p>Cette méthode, quoique relativement simple, n’est pas parfaite, car elle échoue régulièrement à désigner un vainqueur. C’est ce que l’on appelle le paradoxe de Condorcet. En voici un exemple :</p> + +<ul> +<li>le candidat A est majoritairement préféré au candidat B</li> +<li>le candidat B est majoritairement préféré au candidat C</li> +<li>le candidat C est majoritairement préféré au candidat A</li> +</ul> + +<p>On observe qu’aucun candidat ne remporte l’ensemble de ses duels de paires, celle-ci forme des références circulaires : aucun n’est éligible au critère de Condorcet. L’élection n’a pas de solution. Ce paradoxe peut aussi concerner le perdant de Condorcet.</p> +<h4 id="toc-les-méthodes-dites-de-condorcet">Les méthodes dites de Condorcet</h4> + +<p>De nombreux mathématiciens et théoriciens du vote ont proposé leurs propres méthodes étendant celle de Condorcet. Leurs objectifs furent de résoudre le paradoxe de Condorcet, fournir un classement complet <em>(avec d’éventuels matchs nuls, quoique peu probables dans de grosses élections)</em>. Tout en prouvant une compatibilité totale ou partielle de leurs résultats avec celle du vénérable Marquis lorsque cette dernière ne rencontre pas de paradoxes.</p> + +<p>Les façons de voter restent rigoureusement identiques et conservent le même processus de dépouillement pour la quasi-totalité d’entre elles (toujours former des comptes par duels de paires). <br> +Ces méthodes sont cependant bien plus compliquées à calculer et seraient pour la plupart même illusoires sans un processus informatique. Les résultats pré compilés, sous forme de duels de paires résolus, sont encore réalisables à l’échelle humaine <em>(quoique fastidieusement, avec un nombre de candidats restreints)</em> ; mais les calculs finaux font alors appel à des techniques plus poussées, des analyses graphiques (Schulze, Tideman…), des permutations (Kemeny – Young, Dodgson…) ou encore des statistiques (Dodgson approximations, Minimax…).</p> + +<p>L’avantage de ces méthodes avancées réside en ce qu’elles tendent à réduire le risque d’égalité sur tous les rangs (aussi bien au rang du vainqueur qu’aux rangs intermédiaires), d’autant plus quand le nombre d’électeurs augmente ; des égalités sur certains rangs peuvent survenir, ce que ne permet pas la méthode originelle de Condorcet ; et elles réduisent considérablement le risque d’absence de solution, le rendant hautement improbable (de façon exponentielle quand le nombre d’électeurs augmente).<br> +Mais leurs particularismes divers sont aussi particulièrement intéressants pour contrebalancer tout risque de manipulation électorale, rendant inefficientes d’éventuelles consignes électorales qui auraient pour but d’influencer l’algorithme. Le fonctionnement originel de Condorcet étant déjà par nature propre à réduire ce problème (un candidat classé dernier dans un bulletin ne vaut pas moins qu’un candidat classé deuxième dans le contexte d’un duel de pair), mais ces méthodes y ajoutent de nombreuses techniques rendant en pratique peu plausible une stratégie électorale. (voir <a href="https://en.wikipedia.org/wiki/Voting_criteria">Critère de votes</a>)</p> + +<p>Les méthodes de vote les plus estimées, car robustes et abouties (mais pas les plus simples), aussi bien du point de vue des résultats que de la résistance aux manipulations, sont celles dites de Schulze ou de Tideman <em>(aussi appelée Ranked Pairs)</em>.</p> +<h4 id="toc-autres-méthodes--utilisations">Autres méthodes &amp; Utilisations</h4> + +<p>Il existe d’autres méthodes ne respectant pas le critère de Condorcet. La plus connue étant le vote alternatif, utilisé dans certaines élections locales en Australie ou aux États-Unis ; la méthode Borda est elle utilisée comme système électoral principal dans les îles Nauru en Micronésie. <br> +Elles sont aussi implémentées dans Condorcet PHP.</p> + +<p>Étrangement, les méthodes de Condorcet, sont pour leurs parts plutôt cantonnées à la sphère privée et associative ; la cause en est peut-être la faible intelligibilité de leurs algorithmes pour le grand public (NdM: et la difficulté à dépouiller ces méthodes avec des bulletins papier, ce qui les limitent souvent à du vote électronique). On note leur utilisation par exemple chez la Wikimedia Fondation, chez Debian, par le Parti Pirate et bien d’autres structures.<br> +On en a aussi trace sur certains <a href="https://classik.forumactif.com/t7244p400-ecoute-comparee-mahler-2e-symphonie-la-suite">forums musicaux</a>.</p> +<h2 id="toc-fonctionnalités-principales-de-condorcet-php">Fonctionnalités principales de Condorcet PHP</h2> +<h3 id="toc-gérer-une-élection">Gérer une élection</h3> + +<p>Condorcet PHP est conçu pour un usage haut niveau articulé autour de la gestion d’une élection. Il fournit ainsi de prime abord tout un ensemble de méthodes permettant de la paramétrer et de la contrôler. Il accepte de multiples formats en entrée, dont un format de vote explicite créé pour l’occasion.</p> + +<p>Parmi les praticités notables : un système de filtres permet de taguer et de filtrer les votes que l’on veut appliquer à la génération d’un résultat. Ceci permet des simulations redondées ; toujours dans l’idée de faciliter les simulations, les performances et le nombre de manipulations.</p> + +<p>Les objets Candidats, Votes et Résultats sont aussi soumis à des sommes de contrôle cryptographiques et versionnés, afin de garantir leurs intégrités et leurs historiques. Des contraintes peuvent être spécifiées à propos de l’admissibilité des votes.</p> + +<p>Un système d’évaluation simple et interne permet d’obtenir des informations sur les temps de traitement, limités à la génération des résultats, sans recours à des wrappers.</p> +<h3 id="toc-générer-les-résultats">Générer les résultats</h3> +<h4 id="toc-interactions">Interactions</h4> + +<p>Condorcet PHP implémente de nombreuses méthodes de vote. Il fournit des statistiques appropriées pour chaque méthode en commençant par les gagnants/perdants respectant ou non les critères de Condorcet, la présence ou non d’un paradoxe, et les étapes de calcul propres à chacune.<br> +Ou encore de l’impossibilité de trouver un résultat pour certaines d’entre elles dans certains cas (Kemeny–Young…) ; des protections contre les limites de performances possibles sur certaines méthodes lorsque le nombre de candidats devient trop important (Ranked-Pairs, Kemeny–Young…) ; ainsi que de nombreuses variantes et paramètres spécifiques à chacune d’elles.</p> +<h4 id="toc-méthodes-disponibles">Méthodes disponibles</h4> + +<ul> +<li> +<strong>Condorcet Vanilla</strong> </li> +<li> +<strong>Borda count</strong> + +<ul> +<li><strong><a href="https://github.com/julien-boudry/Condorcet/blob/master/VOTING_METHODS.md#borda-count">Borda System</a></strong></li> +<li><strong><a href="https://github.com/julien-boudry/Condorcet/blob/master/VOTING_METHODS.md#dowdall-system-nauru">Dowdall system (Nauru)</a></strong></li> +</ul> +</li> +<li><strong><a href="https://github.com/julien-boudry/Condorcet/blob/master/VOTING_METHODS.md#copeland">Copeland</a></strong></li> +<li> +<strong>Dodgson Approximations</strong> + +<ul> +<li><strong><a href="https://github.com/julien-boudry/Condorcet/blob/master/VOTING_METHODS.md#dodgson-quick">Dodgson Quick</a></strong></li> +<li><strong><a href="https://github.com/julien-boudry/Condorcet/blob/master/VOTING_METHODS.md#dodgson-tideman-approximation">Dodgson Tideman approximation</a></strong></li> +</ul> +</li> +<li><strong><a href="https://github.com/julien-boudry/Condorcet/blob/master/VOTING_METHODS.md#first-past-the-post">First-past-the-post</a></strong></li> +<li> +<strong><a href="https://github.com/julien-boudry/Condorcet/blob/master/VOTING_METHODS.md#instant-runoff-alternative-vote">Instant-runoff</a></strong> <em>(Alternative Vote / Preferential Voting)</em> +</li> +<li><strong><a href="https://github.com/julien-boudry/Condorcet/blob/master/VOTING_METHODS.md#kemenyyoung">Kemeny–Young</a></strong></li> +<li> +<strong>Minimax Family</strong> + +<ul> +<li><strong><a href="https://github.com/julien-boudry/Condorcet/blob/master/VOTING_METHODS.md#minimax-winning">Minimax Winning</a></strong></li> +<li><strong><a href="https://github.com/julien-boudry/Condorcet/blob/master/VOTING_METHODS.md#minimax-margin">Minimax Margin</a></strong></li> +<li><strong><a href="https://github.com/julien-boudry/Condorcet/blob/master/VOTING_METHODS.md#minimax-opposition">Minimax Opposition</a></strong></li> +</ul> +</li> +<li> +<strong>Ranked Pairs Family</strong> <em>(Tideman method)</em> + +<ul> +<li><strong><a href="https://github.com/julien-boudry/Condorcet/blob/master/VOTING_METHODS.md#ranked-pairs-margin">Ranked Pairs Margin</a></strong></li> +<li><strong><a href="https://github.com/julien-boudry/Condorcet/blob/master/VOTING_METHODS.md#ranked-pairs-winning">Ranked Pairs Winning</a></strong></li> +</ul> +</li> +<li> +<strong>Schulze Method</strong> + +<ul> +<li> +<strong><a href="https://github.com/julien-boudry/Condorcet/blob/master/VOTING_METHODS.md#schulze-winning">Schulze Winning</a></strong> <em>(recommandé)</em> +</li> +<li><strong><a href="https://github.com/julien-boudry/Condorcet/blob/master/VOTING_METHODS.md#schulze-margin">Schulze Margin</a></strong></li> +<li><strong><a href="https://github.com/julien-boudry/Condorcet/blob/master/VOTING_METHODS.md#schulze-ratio">Schulze Ratio</a></strong></li> +</ul> +</li> +</ul> +<h3 id="toc-gestion-des-grandes-élections--des-milliards-de-votes-sur-un-matériel-domestique-modeste">Gestion des grandes élections : des milliards de votes sur un matériel domestique modeste</h3> + +<p>Condorcet PHP permet de gérer efficacement des dizaines de milliers de votes, voire des centaines de milliers en augmentant simplement la mémoire vive PHP autorisée dans votre environnement d’exécution (pré configuré en illimité dans la distribution Docker). Ses performances sont conçues pour être linéaires.</p> + +<p>Toutefois, la mémoire vive peut ne pas suffire. Si vous visez plusieurs millions de votes (ou quelques milliards), le recours à un stockage externe, transitoire, peut s’avérer nécessaire.<br> +Condorcet permet de déléguer cette tâche à une base de données externe via le développement d’un pilote spécifique à enregistrer au sein de son architecture modulaire. </p> + +<p>Il est fourni nativement un pilote PHP-PDO, permettant de configurer facilement cette tâche avec les bases de données les plus courantes comme PostgreSQL, Mysql ou encore SQLite. La documentation fournit par ailleurs des exemples d’usage pour SQLite, Condorcet s’occupant alors de tout, jusqu’à la création de la base elle-même. Toutefois, selon le moteur de base de données utilisé et sa bonne configuration (index…), les performances peuvent-être moins linéaires.<br> +Toutefois, si 99% des usages n’ont pas besoin de cette configuration avancée, son utilisation devrait permettre de répondre aux derniers cas, faisant de Condorcet PHP un véritable outil généraliste.</p> + +<p>Le développement de cette fonctionnalité ayant nécessité une importante complexification et abstraction du code global, il est plutôt conseillé d’en faire un usage simple, certains appels API avancés (et accessoires) pouvant écrouler les performances ou créer des bugs encore mal connus. À ce jour, le cas d’usage réel connu de gros collèges électoraux parmi nos utilisateurs est actuellement de 0.</p> +<h2 id="toc-code--architecture">Code &amp; Architecture</h2> + +<p><em>Cette section peut comporter des explications plus subjectives, de la part du développeur principal aussi rédacteur du présent article. La première personne peut y être employée.</em></p> +<h3 id="toc-api-bibliothèque-php">API (bibliothèque PHP)</h3> + +<p>L’objectif a toujours été de proposer une API simple, de haut niveau, permettant de gérer une élection et ses résultats de façon limpide.<br> +Les méthodes d’API sont organisées en plusieurs phases :<br> +1. Enregistrement des candidats<br> +2. Enregistrement des votes<br> +3. Exploitation des résultats.<br> +Des aller-retour dynamiques et optimisés sont possibles entre les phases 3 et 2.</p> + +<p>L’API est très riche, dépassant la centaine de méthodes publiques d’interaction ou de paramétrage. Même si quelques-unes suffisent en principe à gérer une élection simple couvrant 95% des usages. On trouve donc des méthodes haut niveau, qui côtoient optionnellement des choses plus spécifiques et fines.</p> + +<p>Plusieurs approches sont possibles et peuvent-être utilisées de façon simultanée. Les entrées peuvent aussi bien être des objets que des chaînes des caractères normalisées (format Condorcet, Json…), ce qui rend très simple une interaction ponctuelle et non-industrielle avec la bibliothèque.<br> +De fait, beaucoup de magie opère en arrière-plan afin de corriger et de traduire les entrées utilisateur (suppression des espaces avant/après, gestion des majuscules, conversions en objets ou d’objets à objets, absence d’erreurs en cas de validité partielle).<br> +Cette souplesse pouvait cependant être problématique dans le cadre où la validité des données ingérées doit constituer un point d’attention particulier. Aussi les dernières évolutions d’API tendent à remettre de la rigueur en découpant certaines méthodes par usages plus explicites (notamment par types d’entrée / sortie), reposant moins sur des présomptions ou des paramétrages par défaut. Les erreurs sont aussi de plus en plus strictes, acceptant dans moins de cas une entrée partiellement valable. Bien sûr, de nombreuses fonctions de contrôles sont disponibles afin de valider les votes enregistrés et d’accéder aux détails des calculs.</p> +<h3 id="toc-abstraction-et-programmation-orientée-objet">Abstraction et programmation orientée objet</h3> + +<p>En interne, tout est objet ; l’API permettant d’interagir directement sous forme d’objet tout en proposant d’autres modes d’entrées / sorties.<br> +L’usage pointu de références et d’appels inter-objets via une API interne font que les objets ont leur vie propre (un électeur peut changer d’avis en conservant le même objet), les objets peuvent ainsi exister dans l’espace utilisateur et agir directement sur les élections auxquelles ils participeraient.<br> +Un objet <em>Vote</em> peut aussi participer à plusieurs élections en simultané, ce qui ouvre la voie à des applications intéressantes de simulation électorale avec un code utilisateur simple (et à un moindre usage mémoire).</p> + +<p>La limite de l’exercice est alors de chatouiller les capacités du ramasse-miettes de PHP <em>(Garbage Collector)</em>, qui a tendance à peu goûter aux références circulaires complexes, notamment lors de l’usage de destructeurs. Ce qui pour certains usages très particuliers et complexes, peut demander quelques précautions (appels manuels au collecteur de cycles par l’utilisateur) malgré tous les efforts pour prévenir ces cas rares résultants d’usages complexes et exigeants. Cela n’affecte cependant pas les résultats, et ça ne s’avère problématique que d’un point de vue usage mémoire dans le cadre de scripts parents longs.</p> +<h3 id="toc-architecture-modulaire">Architecture modulaire</h3> + +<p>L’ensemble étant organisé de façon très modulaire, il est facile d’étendre la plupart des classes, ce qui est particulièrement utile pour les classes Élection, Candidat et Vote.</p> + +<p>Mais Condorcet prévoit dans son API même l’inclusion de certains modules, basés sur des API plus bas niveau. C’est notamment ainsi que sont gérés les différents algorithmes correspondants à chaque méthode de vote, il est donc très facile de développer votre propre méthode de vote sous forme de module utilisant les API et interfaces bas niveau de Condorcet - sous votre propre espace de nom - et de demander dynamiquement son inclusion dans Condorcet.</p> + +<p>Condorcet PHP dispose aussi d’un mécanisme d’injection de code pour des modules de contrôle de la validité des votes, permettant d’ignorer ceux ne respectant par certains critères ; un module est par exemple nativement fourni afin d’interdire les égalités dans les votes <em>(désactivé par défaut)</em> ; l’on peut imaginer d’autres contraintes permettant par exemple de valider que X candidats minimum soient évalués par le votant.</p> +<h3 id="toc-performances">Performances</h3> + +<p>Les performances sont relativement optimisées, surtout de façon à être linéaires et malignes là où c’est possible, sans sacrifier à la logique du code, à ses fonctionnalités, fiabilités ou sécurités par de trop d’optimisations.<br> +On retrouve donc un système de cache interne, de mise à jour itérative des résultats (par sur tout, mais à minima sur la table des duels de paires) lors des ajouts, suppressions ou mises à jour de votes. Certaines précautions ont dû être prises en termes d’usage mémoire, afin de gérer les énormes élections aussi bien que celles d’un comité de quartier, notamment l’usage d’itérateurs ou de couches d’abstraction de stockage des votes plutôt que de bêtes tableaux.</p> +<h3 id="toc-langage-php-qualité-de-code-documentation-envergure">Langage PHP, qualité de code, documentation, envergure</h3> + +<p>Condorcet PHP est un projet personnel, ne connaissant qu’un seul développeur actif et un public utilisateur restreint et largement inconnu. Il y a donc peu de contraintes, la motivation de développement se portant volontiers sur l’usage des dernières fonctionnalités du langage. PHP s’étant par ailleurs largement métamorphosé ces dernières années. Ainsi, les versions successives de Condorcet n’ont toujours été compatibles qu’avec les versions les plus récentes, introduisant et testant les dernières avancées disponibles.</p> + +<p>Actuellement, Condorcet dernière mouture, n’est disponible que pour PHP 7.4. Il use avidement des dernières évolutions, notamment en ce qui concerne le typage strict des méthodes et des propriétés. Cette introduction ayant aussi eu pour effet positif de repenser largement l’API, l’objectif étant de se servir de cette contrainte volontaire pour tout typer, permettant une très large revue de code et de nettes améliorations structurantes.<br> +Un support sur demande (ainsi que quelques tests CI) est toutefois assuré pour les anciennes versions.<br> +Le projet a longtemps été développé de façon improvisée et artisanale. Il fut radicalement réécrit plusieurs fois au fur et à mesure de sa prise d’ambition et de la montée en compétence de son développeur principal.</p> + +<p>Il aura fallu se faire violence pour qu’une documentation des méthodes et un manuel complet finissent par sortir de terre. Ils sont assez exhaustifs, à minima sur l’API publique.</p> + +<p>Les tests ont aussi fait leur apparition, et l’on atteint désormais un ratio de près de 50/50 entre code applicatif et code de test. Ils sont encore assez largement fonctionnels plus que strictement unitaires, mais très retors et disposant d’une couverture de code à 98%. Les tests s’attardent particulièrement sur la validité des résultats, et puisent allégrement dans les exemples simples et complexes fournis dans les papiers décrivant chaque méthode de vote.</p> + +<p>Condorcet PHP c’est 340 ko de code brut (avant compilation), pour 6000 lignes maintenues hors tests et exemples, reparties en 42 classes (oui 42) et près de 500 fonctions. Rajoutons-y 220 ko de documentation en texte brut.</p> + +<p>La philosophie de Condorcet PHP fut de s’affranchir de toutes dépendances, par défi personnel d’abord, mais aussi suivant la volonté de maîtriser parfaitement tout d’un code devant gérer des résultats électoraux. L’application en ligne de commande passe elle cependant par la Console Symfony. Et l’environnement de développement ne se prive pas de dépendances variées, bien évidemment.</p> + +<p>Cela rend l’utilisation de Condorcet au travers de Composer tout à fait optionnelle, bien que recommandée. Son propre auto-loader (PSR-4) est disponible en option.</p> +<h2 id="toc-continuation--développements-">Continuation &amp; développements </h2> + +<p><em>Cette section peut comporter des explications plus subjectives, de la part du développeur principal aussi rédacteur du présent article. La première personne peut y être employée.</em></p> +<h3 id="toc-exécutable-en-ligne-de-commande">Exécutable en ligne de commande</h3> + +<p>Depuis la version 2.1 parue en décembre 2019, Condorcet PHP propose une version utilisable en ligne de commande. Ce qui constitue possiblement un véritable changement dans l’usage, l’outil devenant beaucoup plus accessible aux utilisateurs finaux sans connaissances en PHP et/ou n’ayant pas la volonté d’implémenter son API malgré sa simplicité.</p> + +<p>L’application en ligne de commande est plus limitée, mais couvre cependant bien l’ensemble des usages imaginables, y compris la gestion de très grosses élections via l’activation du stockage SQLite. Aucune fonctionnalité nouvelle n’y est donc anticipée… peut-être quelques raffinements, un peu plus de documentation, quelques tests supplémentaires.</p> +<h3 id="toc-docker-exécutables-paquets-interface-graphique">Docker, exécutables, paquets, interface graphique</h3> +<h4 id="toc-image-docker">Image Docker</h4> + +<p>Autre nouveauté récente, dans la continuité de l’idée de permettre un usage de Condorcet directement par l’utilisateur final et non un produit réservé aux développeurs : l’introduction d’une distribution Docker officielle. Cela permet d’interagir très facilement et rapidement en ligne de commande. Toutefois, même si cela va dans le bon sens, Docker n’est pas parfaitement accessible non plus auprès du premier venu.</p> +<h4 id="toc-exécutable">Exécutable</h4> + +<p>Une idée intéressante serait de pouvoir produire pour Windows un exécutable binaire, lançant automatiquement l’interface en ligne de commande. Cela en est resté à l’étape de projet, et aucun test ou évaluation sérieuse n’a encore été mené quant aux solutions techniques qui pourraient aider à y parvenir.</p> +<h4 id="toc-paquets-de-distributions-linux">Paquets de distributions Linux</h4> + +<p>Il serait assez facile d’entretenir des paquets permettant d’accéder à la version en ligne de commande auprès de distributions Linux. Toutefois, n’en ayant là encore pas la compétence actuellement, cette idée est encore en attente.</p> +<h4 id="toc-interface-graphique">Interface graphique</h4> + +<p>La solution d’accessibilité reine serait bien évidement de fournir une interface graphique et une distribution prête à l’emploi.<br> +Pour poste de travail traditionnel ou applications mobiles, je n’en ai pas la compétence et ne désire par l’acquérir aujourd’hui. Toutefois, tout projet en ce sens est le bienvenu, et bénéficierait de mon support chaleureux.</p> + +<p>Une interface graphique existe toutefois déjà , elle est maintenue par moi-même : <a href="https://www.condorcet.vote">www.condorcet.vote</a><br> +Toutefois, je n’ai que peu de motivation à l’entretenir. C’était plus un projet de démonstration qu’un véritable service viable ; il n’offre pas toutes les possibilités de la bibliothèque Condorcet PHP sous-jacente, ni une stabilité irréprochable en l’état.</p> +<h3 id="toc-documentation-et-lisibilité-du-code">Documentation et lisibilité du code</h3> + +<p>Des efforts constants sont portés sur la documentation. La priorité absolue résidant dans le manuel et le <em>Readme</em>, puis dans les méthodes de l’API publique. La documentation est générée suivant l’usage d’un projet séparé sur mesure et dédiée (mais un peu exotique). Malheureusement, les méthodes internes sont encore très mal documentées. Et le code interne lui-même dispose de bien peu, bien trop peu, de commentaires.</p> + +<p>L’adoption des normes <a href="https://www.php-fig.org/psr/">PSR-5</a> et <a href="https://www.php-fig.org/psr/">PSR-19</a> pourraient constituer un axe de refonte et de migration. L’adoption de celles-ci semblant au point mort, elles motivent donc assez peu à rationaliser tout cela.<br> +Le projet Condorcet PHP n’ayant jamais récolté le moindre don, le maintien de la rébarbative documentation et des tests qualités relève de l’héroïsme et de l’abnégation la plus pure.</p> +<h3 id="toc-autres-méthodes-de-votes">Autres méthodes de votes</h3> + +<p>Condorcet PHP ne gère pour l’instant aucune méthode de vote à sortie proportionnelle, dites « STV » (<a href="https://fr.wikipedia.org/wiki/Scrutin_%C3%A0_vote_unique_transf%C3%A9rable">Scrutin à vote unique transférable</a>) qui sont parfois homonymes à celles ici présentées (de par le nom de leurs auteurs). Celles gérées aujourd’hui sont celles qui fournissant un classement sans scores par candidats <em>(ou du moins, non destiné à un quelconque usage proportionnel)</em>.<br> +C’est une évolution future possible, qui pourrait s’intégrer dans l’architecture actuelle sans difficultés majeures. Par contre, leur complexité algorithmique, et le peu d’exemple de pseudo-codes et de documentation disponibles rendent actuellement leurs implémentations compliquées vis-à -vis de mes propres compétences.</p> + +<p>Cependant, la quasi-totalité des méthodes standards dites de Condorcet sont aujourd’hui d’ores et déjà implémentées, ainsi que quelques méthodes d’autres familles, les plus courantes, comme le <a href="https://fr.wikipedia.org/wiki/Vote_alternatif">vote alternatif</a>.</p> +<h3 id="toc-perspectives-dactivités">Perspectives d’activités</h3> + +<p>Le support reste assuré avec plaisir, et je serai heureux d’apprendre tout cas d’utilisation.<br> +Le reste est plus aléatoire, et soumis à d’éventuelles pulsions soudaines.</p> + +<p>Merci de votre lecture, c’est une longue dépêche !</p> +</div><div><a href="https://linuxfr.org/news/condorcet-php-gestion-des-elections-alternatives.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/119220/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/condorcet-php-gestion-des-elections-alternatives#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>julien.boudry</name> + </author> + <author> + <name>Benoît Sibaud</name> + </author> + <author> + <name>theojouedubanjo</name> + </author> + <author> + <name>Ysabeau</name> + </author> + <author> + <name>Davy Defaud</name> + </author> + <author> + <name>Pierre Jarillon</name> + </author> + <author> + <name>dourouc05</name> + </author> + <author> + <name>Claude SIMON</name> + </author> + <category term="PHP"/> + <category term="élections"/> + <category term="vote_électronique"/> + <category term="condorcet"/> + <category term="système_de_vote"/> + <category term="vote_par_internet"/> + <wfw:commentRss>https://linuxfr.org/nodes/119220/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/39655</id> + <published>2020-01-24T11:55:05+01:00</published> + <updated>2020-01-24T12:00:35+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/prestashop-version-1-7-6-3"/> + <title>PrestaShop version 1.7.6.3</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>Prestashop est un système de gestion de contenu (CMS) libre français de commerce en ligne, développé en PHP + MySQL et placé sous licence <a href="https://opensource.org/licenses/OSL-3.0">OSL v3</a>.</p> + +<p>Les points forts de PrestaShop sont la simplicité, la légèreté et la rapidité d’exécution. PrestaShop 1.7 contient plus de 600 fonctionnalités et a contribué à la création et au succès de plus de 300 000 boutiques à travers le monde. La dernière version majeure de Prestashop (la version 1.7) est sortie en 2016.</p> + +<p>Prestashop a remporté en 2010 et 2011 le prix <em>Open Source Awards</em> et, <a href="//linuxfr.org/news/retour-sur-l-edition-2019-du-paris-open-source-summit">en 2019, le prix des Acteurs du Libre</a> dans la catégorie développement international, pour sa stratégie de développement qui a permis de mettre en place une communauté d’un million de personnes actives dans le monde. Prestashop est numéro un des logiciels de commerce en ligne en Europe et en Amérique du Sud. Le logiciel est disponible dans plus de soixante langues, y compris des langues s’écrivant de droite à gauche, telles que le persan et l’arabe.</p> + +<p>Ce mardi, les équipes de PrestaShop ont publié la version 1.7.6.3 qui apporte de nombreuses corrections, dont :</p> + +<ul> +<li>la correction de messages d’erreur confus lorsque des paramètres trop longs étaient saisis en <em>back‑office</em> ;</li> +<li>les courriels n’étaient pas correctement traduits si une langue différente de l’anglais était choisie lors de l’installation ;</li> +<li>le service Web ne renvoyait pas les informations traduites pour les devises ;</li> +<li>il n’était pas possible d’exporter plus de cinquante clients depuis la liste des clients en <em>back‑office</em> ;</li> +<li>dans certaines conditions, il n’était plus possible de modifier le prix d’un produit.</li> +</ul> + +<p>La liste complète des corrections est disponible dans les <a href="https://build.prestashop.com/news/prestashop-1-7-6-3-maintenance-release/">notes de publication</a> (en anglais).</p> + +<p>La communauté PrestaShop est très active, aussi bien sur le dépôt <a href="https://github.com/PrestaShop/PrestaShop/">GitHub</a>, qui sert également au suivi des bogues, que sur le <a href="https://www.prestashop.com/forums">forum</a> ou le canal <a href="https://gitter.im/PrestaShop/General">Gitter</a>.<br> +N’hésitez pas à venir échanger avec nos communautés de marchands ou de développeurs !</p> +</div><ul><li>lien náµ’Â 1 : <a title="https://www.prestashop.com/fr" hreflang="fr" href="https://linuxfr.org/redirect/105613">PrestaShop</a></li><li>lien náµ’Â 2 : <a title="https://www.prestashop.com/fr/telecharger" hreflang="fr" href="https://linuxfr.org/redirect/105614">Téléchargement</a></li><li>lien náµ’Â 3 : <a title="https://build.prestashop.com/news/prestashop-1-7-6-3-maintenance-release/" hreflang="en" href="https://linuxfr.org/redirect/105615">Notes de publication de la version 1.7.6.3</a></li></ul><div></div><div><a href="https://linuxfr.org/news/prestashop-version-1-7-6-3.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/119214/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/prestashop-version-1-7-6-3#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>Mathieu Ferment</name> + </author> + <author> + <name>Davy Defaud</name> + </author> + <author> + <name>palm123</name> + </author> + <category term="PHP"/> + <category term="php"/> + <category term="symfony"/> + <category term="cms"/> + <category term="prestashop"/> + <wfw:commentRss>https://linuxfr.org/nodes/119214/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/39489</id> + <published>2019-11-29T04:33:49+01:00</published> + <updated>2019-11-29T11:56:07+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/php-7-4"/> + <title>PHP 7.4</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>Il y a bien longtemps qu’une nouvelle version de PHP n’avait pas été commentée ici. En fait, depuis la sortie de la version 7.0 qui s’est faite dans la douleur après l’abandon de la version 6. Le langage sort désormais avec une nouvelle version chaque fin d’année. La rétrocompatibilité est un point qui n’est pas négligé d’une version à l’autre, d’où une évolution plutôt lente.<br> +La majorité des logiciels peut migrer sans trop d’appréhension. Depuis plusieurs versions, l’amélioration des performances est un point essentiel du fait de la concurrence avec HHVM, développé par Facebook. Au final, cette version, qui est la dernière de la branche 7, apporte un système de type plus fort, plus de performance et fait en sorte de diminuer le code cérémonial, aka <em>boilerplate</em>.</p> +</div><ul><li>lien náµ’Â 1 : <a title="https://stitcher.io/blog/new-in-php-74" hreflang="en" href="https://linuxfr.org/redirect/105049">Une revue d’une grande partie des nouveautés</a></li><li>lien náµ’Â 2 : <a title="https://www.php.net/" hreflang="en" href="https://linuxfr.org/redirect/105050">Site officiel de PHP</a></li><li>lien náµ’Â 3 : <a title="https://afup.org/talks/3120-tout-pour-se-preparer-a-php-7-4" hreflang="fr" href="https://linuxfr.org/redirect/105250">Tout pour se préparer à PHP 7.4 (conférence forum PHP 2019)</a></li><li>lien náµ’Â 4 : <a title="https://wiki.php.net/rfc#php_74" hreflang="en" href="https://linuxfr.org/redirect/105302">Liste des RFC de la version</a></li><li>lien náµ’Â 5 : <a title="https://afup.org/talks/3015-php-8-et-just-in-time-compilation" hreflang="fr" href="https://linuxfr.org/redirect/105317">PHP 8 et le JIT (conférence forum PHP 2019)</a></li></ul><div><h2 class="sommaire">Sommaire</h2> +<ul class="toc"> +<li> +<a href="#toc-r%C3%A9duction-de-la-verbosit%C3%A9-du-langage">Réduction de la verbosité du langage</a><ul> +<li><a href="#toc-null-coalescing-assignment-operator">Null coalescing assignment operator</a></li> +<li><a href="#toc-fonctions-fl%C3%A9ch%C3%A9es">Fonctions fléchées</a></li> +</ul> +</li> +<li> +<a href="#toc-%C3%89volution-de-la-syntaxe">Évolution de la syntaxe</a><ul> +<li><a href="#toc-s%C3%A9parateur-dunit%C3%A9">Séparateur d’unité</a></li> +<li><a href="#toc-les-op%C3%A9rateurs-ternaires-imbriqu%C3%A9s-ne-sont-plus-associ%C3%A9s-par-lagauche">Les opérateurs ternaires imbriqués ne sont plus associés par la gauche</a></li> +</ul> +</li> +<li><a href="#toc-un-typage-pluspr%C3%A9sent">Un typage plus présent</a></li> +<li> +<a href="#toc-am%C3%A9liorations-des-performances">Améliorations des performances</a><ul> +<li><a href="#toc-foreign-function-interface">Foreign Function Interface</a></li> +<li><a href="#toc-pr%C3%A9chargement">Préchargement</a></li> +</ul> +</li> +<li> +<a href="#toc-la-suite">La suite ?</a><ul> +<li><a href="#toc-p-bringing-peace-to-thegalaxy">P++, Bringing Peace to the Galaxy</a></li> +<li><a href="#toc-php8">PHP 8</a></li> +<li><a href="#toc-2029">2029</a></li> +</ul> +</li> +</ul> +<p>La version PHP 7.4 apporte de nombreuses fonctionnalités et en supprime une :</p> + +<ul> +<li> +<a href="https://wiki.php.net/rfc/null_coalesce_equal_operator"><em>null coalescing assignment operator</em></a>, proposé par Midori Kocak ;</li> +<li> +<a href="https://wiki.php.net/rfc/arrow_functions_v2">fonctions fléchées 2.0</a>, proposées par Nikita Popov, Levi Morrison et Bob Weinand (<a href="https://github.com/php/php-src/pull/3941" title="Pull Request">PR</a>) ;</li> +<li> +<a href="https://wiki.php.net/rfc/typed_properties_v2">propriétés typées 2.0</a>, proposées par Nikita Popovet et Bob Weinand (<a href="https://github.com/php/php-src/pull/3734" title="Pull Request">PR</a>) ;</li> +<li> +<a href="https://wiki.php.net/rfc/preload">préchargement</a>, proposé par Dmitry Stogov ;</li> +<li> +<a href="https://wiki.php.net/rfc/improve-openssl-random-pseudo-bytes">amélioration d’<code>openssl_random_pseudo_bytes()</code></a>, proposée par Sammy Kaye Powers (<a href="https://github.com/php/php-src/pull/3649" title="Pull Request">PR</a>) ;</li> +<li> +<a href="https://wiki.php.net/rfc/weakrefs">références faibles</a> (<em>weak references</em>), proposées par <em>krakjoe</em> ;</li> +<li> +<a href="https://wiki.php.net/rfc/permanent_hash_ext">extension de hachage toujours disponible</a>, proposée par Kalle Sommer Nielsen ;</li> +<li> +<a href="https://wiki.php.net/rfc/ffi">FFI</a> (<em>Foreign Function Interface</em>), proposé par Dmitry Stogov ;</li> +<li> +<a href="https://wiki.php.net/rfc/password_registry">registre de hachage de mot de passe</a>, proposé par Sara Golemon (<a href="https://github.com/php/php-src/pull/3609" title="Pull Request">PR</a>) ;;</li> +<li> +<a href="https://wiki.php.net/rfc/mb_str_split">ajout de <code>mb_str_split()</code></a> pour couper une chaîne de caractères sur plusieurs octets, proposé par Rumi Legal (<a href="https://github.com/php/php-src/pull/3715">P</a> <a href="https://github.com/php/php-src/pull/3808">R</a>) ;</li> +<li> +<a href="https://wiki.php.net/rfc/reference_reflection">réflectivité pour les références</a> proposée par Nikita Popov (<a href="https://github.com/php/php-src/pull/3550" title="Pull Request">PR</a>) ;</li> +<li> +<a href="https://wiki.php.net/rfc/custom_object_serialization">nouveau mécanisme de sérialisation</a>, proposé par Nikita Popov (<a href="https://github.com/php/php-src/pull/3761">PR</a>) ;</li> +<li> +<a href="https://wiki.php.net/rfc/jit">fin de la prise en charge du format</a> <a href="https://fr.wikipedia.org/wiki/Web_Distributed_Data_eXchange">WDDX</a>, proposée par Dmitry Stogov et Zeev Suraski (<a href="http://git.php.net/?p=php-src.git;a=commit;h=6bbb18a0b6bef11222caaa55c00abdbcbb55d54b">51 fichiers supprimés</a>).</li> +</ul> +<h2 id="toc-réduction-de-la-verbosité-du-langage">Réduction de la verbosité du langage</h2> +<h3 id="toc-null-coalescing-assignment-operator">Null coalescing assignment operator</h3> + +<p>Cette nouveauté évite de dupliquer le nom de la variable de part et d’autre de l’opérateur d’affectation. Par exemple, les deux lignes suivantes ont le même comportement :</p> + +<pre><code class="php"><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">request</span><span class="o">-&gt;</span><span class="na">data</span><span class="p">[</span><span class="s1">'comments'</span><span class="p">][</span><span class="s1">'user_id'</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">request</span><span class="o">-&gt;</span><span class="na">data</span><span class="p">[</span><span class="s1">'comments'</span><span class="p">][</span><span class="s1">'user_id'</span><span class="p">]</span> <span class="o">??</span> <span class="s1">'value'</span><span class="p">;</span> + +<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">request</span><span class="o">-&gt;</span><span class="na">data</span><span class="p">[</span><span class="s1">'comments'</span><span class="p">][</span><span class="s1">'user_id'</span><span class="p">]</span> <span class="o">??=</span> <span class="s1">'value'</span><span class="p">;</span></code></pre> +<h3 id="toc-fonctions-fléchées">Fonctions fléchées</h3> + +<p>Cette nouveauté a été définie dans cette <a href="https://wiki.php.net/rfc/arrow_functions_v2">RFC</a>. Elle vise, entre autres, à rendre l’usage du côté fonctionnel du langage plus agréable. Oui, oui, PHP a <a href="https://apiumhub.com/tech-blog-barcelona/functional-php/">quelques marges d’amélioration</a> à ce niveau‑là  !</p> + +<p>Ici, il sera plus agréable de remplacer les bons vieux <code>foreach()</code> pour traiter les tableaux par des <code>array_map()</code> ou des <code>array_filter()</code>. Globalement ça s’inspire des fonctions fléchées du JavaScript.</p> + +<pre><code class="php"><span class="nv">$double</span> <span class="o">=</span> <span class="nb">array_map</span><span class="p">(</span><span class="nx">fn</span><span class="p">(</span><span class="nv">$e</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="mi">2</span> <span class="o">*</span> <span class="nv">$e</span><span class="p">,</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]);</span> + +<span class="nv">$utilisateursMineurs</span> <span class="o">=</span> <span class="nb">array_filter</span><span class="p">(</span><span class="nv">$users</span><span class="p">,</span> <span class="nx">fn</span><span class="p">(</span><span class="nx">User</span> <span class="nv">$user</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nv">$user</span><span class="o">-&gt;</span><span class="na">age</span> <span class="o">&lt;</span> <span class="mi">18</span><span class="p">);</span></code></pre> + +<p>Nous pouvons noter la cohérence du langage entre les deux fonctionnalités, l’ordre d’appel entre le tableau et la méthode de retour n’est pas le même.</p> +<h2 id="toc-Évolution-de-la-syntaxe">Évolution de la syntaxe</h2> +<h3 id="toc-séparateur-dunité">Séparateur d’unité</h3> + +<p>Il est possible d’ajouter un séparateur d’unité pour les nombres afin de les rendre plus lisibles. Par exemple, <code>$milliard = 1000000000</code> pourra s’écrire <code>$milliard = 1_000_000_000</code>. En revanche, attention à l’utilisation, il y a des risques de ne pas affecter la bonne valeur.</p> +<h3 id="toc-les-opérateurs-ternaires-imbriqués-ne-sont-plus-associés-par-lagauche">Les opérateurs ternaires imbriqués ne sont plus associés par la gauche</h3> + +<p>PHP était un des rares langages à proposer une associativité des ternaires par la gauche. Et pour éviter aux développeurs de se prendre les pieds dans le tapis, elle disparaît. Le mieux étant tout de même d’éviter les ternaires imbriqués.</p> +<h2 id="toc-un-typage-plusprésent">Un typage plus présent</h2> + +<p>Depuis la version 7.0, le typage est de plus en plus présent au sein du langage. Il est possible de typer les arguments et le type de retour d’une méthode. Dorénavant, il sera aussi possible de spécifier le type des attributs d’une classe.</p> + +<pre><code class="php"><span class="k">class</span> <span class="nc">Sportif</span> +<span class="p">{</span> + <span class="k">private</span> <span class="nx">Sport</span> <span class="nv">$sport</span> <span class="o">=</span> <span class="s1">'cyclimse'</span><span class="p">;</span> + <span class="k">private</span> <span class="nx">Humain</span> <span class="nv">$humain</span><span class="p">;</span> + + <span class="k">public</span> <span class="k">function</span> <span class="fm">__construct</span><span class="p">(</span><span class="nx">Humain</span> <span class="nv">$humain</span><span class="p">,</span> <span class="nx">Sport</span> <span class="nv">$sport</span><span class="p">)</span> + <span class="p">{</span> + <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">humain</span> <span class="o">=</span> <span class="nv">$humain</span><span class="p">;</span> + <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">sport</span> <span class="o">=</span> <span class="nv">$sport</span><span class="p">;</span> + <span class="p">}</span> + + <span class="k">public</span> <span class="k">function</span> <span class="nf">entrainer</span><span class="p">()</span><span class="o">:</span><span class="nx">void</span> + <span class="p">{</span> + <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">humain</span><span class="o">-&gt;</span><span class="na">ajouteEntrainement</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">sport</span><span class="p">);</span> + <span class="p">}</span></code></pre> + +<p>Ces ajouts sur les types facilitent la compréhension du code. En revanche, sans contrainte, PHP a un typage dynamique, donc le code suivant n’a pas forcément un résultat intuitif :</p> + +<pre><code class="php"><span class="nv">$somme</span> <span class="o">=</span> <span class="k">function</span> <span class="p">(</span><span class="nx">int</span> <span class="nv">$a</span><span class="p">,</span> <span class="nx">int</span> <span class="nv">$b</span><span class="p">)</span><span class="o">:</span> <span class="nx">int</span> <span class="p">{</span><span class="k">return</span> <span class="nv">$a</span> <span class="o">+</span> <span class="nv">$b</span><span class="p">;</span> <span class="p">};</span> +<span class="k">echo</span> <span class="nv">$somme</span><span class="p">(</span><span class="s2">"1"</span><span class="p">,</span> <span class="mf">2.1</span><span class="p">);</span> <span class="c1">// affiche 3</span></code></pre> + +<p>En forçant une évaluation stricte des types en plaçant <code>declare(strict_types=1);</code> en début de fichier, le code déclenche une erreur sur le typage. Ainsi, le développeur est forcé à prêter plus attention aux arguments passés aux méthodes.</p> + +<p>En PHP 8, s’ajouteront les <a href="https://wiki.php.net/rfc/union_types_v2">types unions</a>, et espérons qu’ils seront accompagnés par des énumérations.</p> +<h2 id="toc-améliorations-des-performances">Améliorations des performances</h2> + +<p>Comme à chaque fois depuis la version 7.0, les performances natives du langage s’améliorent. Il est actuellement un des langages interprétés les plus rapides. Il faut néanmoins relativiser, car un langage qui va vite c’est une chose, mais si du temps est perdu à attendre le retour d’une requête en base de données ou, pire, depuis le réseau, les gains côté PHP ne sont pas très utiles. C’est d’ailleurs une des raisons pour lesquelles le JIT ne sera pas activé par défaut en PHP 8.</p> +<h3 id="toc-foreign-function-interface">Foreign Function Interface</h3> + +<p>L’idée est ici de pouvoir appeler un programme en C depuis un script PHP, un peu à l’idée de ce qu’il est possible de faire en Python en écrivant du CPython.</p> + +<p>Il sera possible d’écrire des choses du genre (<a href="https://github.com/dstogov/php-ffi">source</a>) :</p> + +<pre><code class="php"><span class="nv">$libc</span> <span class="o">=</span> <span class="nx">FFI</span><span class="o">::</span><span class="na">cdef</span><span class="p">(</span><span class="s2">"</span> +<span class="s2"> int printf(const char *format, ...);</span> +<span class="s2"> const char * getenv(const char *);</span> +<span class="s2"> unsigned int time(unsigned int *);</span> + +<span class="s2"> typedef unsigned int time_t;</span> +<span class="s2"> typedef unsigned int suseconds_t;</span> + +<span class="s2"> struct timeval {</span> +<span class="s2"> time_t tv_sec;</span> +<span class="s2"> suseconds_t tv_usec;</span> +<span class="s2"> };</span> + +<span class="s2"> struct timezone {</span> +<span class="s2"> int tz_minuteswest;</span> +<span class="s2"> int tz_dsttime;</span> +<span class="s2"> };</span> + +<span class="s2"> int gettimeofday(struct timeval *tv, struct timezone *tz);</span> +<span class="s2">"</span><span class="p">,</span> <span class="s2">"libc.so.6"</span><span class="p">);</span> + +<span class="nv">$libc</span><span class="o">-&gt;</span><span class="na">printf</span><span class="p">(</span><span class="s2">"Hello World from %s!</span><span class="se">\n</span><span class="s2">"</span><span class="p">,</span> <span class="s2">"PHP"</span><span class="p">);</span> +<span class="nb">var_dump</span><span class="p">(</span><span class="nv">$libc</span><span class="o">-&gt;</span><span class="na">getenv</span><span class="p">(</span><span class="s2">"PATH"</span><span class="p">));</span> +<span class="nb">var_dump</span><span class="p">(</span><span class="nv">$libc</span><span class="o">-&gt;</span><span class="na">time</span><span class="p">(</span><span class="k">null</span><span class="p">));</span> + +<span class="nv">$tv</span> <span class="o">=</span> <span class="nv">$libc</span><span class="o">-&gt;</span><span class="na">new</span><span class="p">(</span><span class="s2">"struct timeval"</span><span class="p">);</span> +<span class="nv">$tz</span> <span class="o">=</span> <span class="nv">$libc</span><span class="o">-&gt;</span><span class="na">new</span><span class="p">(</span><span class="s2">"struct timezone"</span><span class="p">);</span> +<span class="nv">$libc</span><span class="o">-&gt;</span><span class="na">gettimeofday</span><span class="p">(</span><span class="nx">FFI</span><span class="o">::</span><span class="na">addr</span><span class="p">(</span><span class="nv">$tv</span><span class="p">),</span> <span class="nx">FFI</span><span class="o">::</span><span class="na">addr</span><span class="p">(</span><span class="nv">$tz</span><span class="p">));</span> +<span class="nb">var_dump</span><span class="p">(</span><span class="nv">$tv</span><span class="o">-&gt;</span><span class="na">tv_sec</span><span class="p">,</span> <span class="nv">$tv</span><span class="o">-&gt;</span><span class="na">tv_usec</span><span class="p">,</span> <span class="nv">$tz</span><span class="p">);</span></code></pre> + +<p>Cette fonctionnalité ouvre la possibilité d’effectuer des traitements qui habituellement ne se font pas en PHP. D’ailleurs, voici un <a href="https://github.com/vdechenaux/PhpWebcam">exemple d’utilisation</a>.</p> +<h3 id="toc-préchargement">Préchargement</h3> + +<p>L’idée est de charger des fichiers afin que PHP crée un « binaire ». En contre‑partie, la mise à  jour du binaire devra attendre un prochain démarrage et le temps de démarrage sera un peu plus long. Ce préchargement est donc intéressant pour les fichiers qui évoluent rarement, globalement ceux du cadriciel. En fonction des projets, il peut être intéressant de ne précharger que les fichiers les plus utilisés, comme le montre <a href="https://github.com/composer/composer/issues/7777#issuecomment-440268416">ce commentaire</a>.</p> +<h2 id="toc-la-suite">La suite ?</h2> +<h3 id="toc-p-bringing-peace-to-thegalaxy">P++, Bringing Peace to the Galaxy</h3> + +<p>En août 2019, la communauté s’était posé la question sur la création d’une variante du PHP : <a href="https://wiki.php.net/pplusplus/faq">P++</a> (c’est un nom temporaire et on peut aussi lire PHP++). L’idée était de nettoyer le langage de ses aspects pas toujours cohérents, mais conservés pour des raisons de compatibilité. Un peu comme pour le langage <a href="https://fr.wikipedia.org/wiki/Raku_(langage_de_programmation)">Raku</a> créé initialement pour rendre le langage <a href="https://fr.wikipedia.org/wiki/Perl_(langage)">Perl</a> plus accessible. Le moteur d’exécution de PHP pourrait alors interpréter indifféremment un PHP <em>Classic</em> <code>&lt;?php ?&gt;</code> et un P++ <code>&lt;?p++ ?&gt;</code>. Benjamin Eberlei <a href="https://beberlei.de/2019/08/14/pplusplus_is_a_bad_idea.html">propose</a> d’utiliser <code>&lt;?php declare(std=20); ?&gt;</code>.</p> + +<p>Un <a href="https://www.strawpoll.me/18448151">sondage ouvert à  tous</a> montre que 60 % des répondants souhaitent un PHP 8 rétrocompatible, et un petit 20 % pour passer à  P++. Les mainteneurs se sont aussi exprimés lors d’un <a href="https://wiki.php.net/rfc/p-plus-plus#vote">sondage plus formel</a>, et P++ ne verra pas le jour, car trop d’énergie à investir sur deux langages, la fragmentation de la communauté PHP…</p> +<h3 id="toc-php8">PHP 8</h3> + +<p>En fin d’année prochaine, PHP 8 devrait débarquer avec quelques gros changements. Le plus important est, peut‑être, la <a href="https://fr.wikipedia.org/wiki/Compilation_%C3%A0_la_vol%C3%A9e">compilation à  la volée</a> (<em>JIT</em>) <a href="https://wiki.php.net/rfc/jit">proposée par Dmitry Stogov</a>.</p> + +<p>En 2011, Facebook annonçait des performances incroyables avec <a href="https://en.wikipedia.org/wiki/HHVM">HHVM</a>, son implémentation d’un moteur d’exécution PHP exploitant la compilation à la volée. Mais cette technique pour optimiser l’exécution de PHP n’avait pas été retenue pour le moteur d’exécution de référence. Néanmoins, PHP 7 a pu bénéficier d’autres mécanismes pour améliorer ses performances, rattraper HHVM et susciter un regain d’intérêt pour PHP.</p> + +<p>Aujourd’hui, près de dix ans plus tard, il ne reste plus beaucoup d’options pour continuer d’améliorer les performances de PHP. Bien que la compilation à la volée ne devrait pas beaucoup améliorer la performance du rendu des pages Web, cette technique apporte deux avantages :</p> + +<ul> +<li>une très bonne approche pour l’utilisation de PHP dans du calcul intensif, et cela devrait permettre d’utiliser PHP dans des domaines où on ne le considérait pas comme une option ;</li> +<li>permettre de basculer des pans entiers du code PHP par l’équivalent dans un langage plus proche du processeur (comme le langage C) lors de cette compilation à  la volée.</li> +</ul> + +<p>Cette compilation à la volée a failli être <a href="https://github.com/zendtech/php-src/tree/jit-dynasm-7.4">intégrée</a> dans PHP 7.4 en mode expérimental. Ce changement correspond au plus <a href="https://github.com/php/php-src/commit/9a06876072b9ccb023d4a14426ccb587f10882f3">grand <em>commit</em></a> de l’histoire de PHP.</p> + +<p>La future version PHP 8 apportera également d’autres améliorations que nous aurons plaisir à partager dans un an…</p> +<h3 id="toc-2029">2029</h3> + +<p>Utiliseraâ€tâ€on PHP dans dix ans, en 2029 ?</p> + +<p>D’après le site <em>W3Techs</em>, PHP est encore et toujours <a href="https://w3techs.com/technologies/overview/programming_language/all">le langage le plus utilisé</a> côté serveur Web. Les statistiques sont mises à  jour quotidiennement. Voici les chiffres lors de la rédaction de cette dépêche :</p> + +<ul> +<li>79 % PHP ;</li> +<li>11 % ASP.NET ;</li> +<li>  5 % Java et Scala ;</li> +<li>  3 % Ruby (vive <em>LinuxFr.org</em>) ;</li> +<li>  2 % HTML (fichiers statiques) ;</li> +<li>  1 % Python ;</li> +<li>  1 % JavaScript.</li> +</ul> + +<p>Pour la méthodologie utilisée, lire les <a href="https://w3techs.com/technologies">explications fournies par <em>W3Techs</em></a>.</p> + +<p>Avec un zoom sur les <a href="https://w3techs.com/technologies/details/pl-php/all/all">versions de PHP</a> :</p> + +<ul> +<li>PHP 3    0,0x %   😱 plus maintenu depuis 19 ans !</li> +<li>PHP 4    0,5 %   😵 plus maintenu depuis 11 ans !</li> +<li>PHP 5  58 %   😮 plus maintenu depuis un an ;</li> +<li>PHP 6    0 %   🤠version abandonnée, jamais sortie ;</li> +<li>PHP 7  42 %   😀 version actuelle ;</li> +<li>PHP 8    0 %   🤩 sortie prévue dans un an.</li> +</ul> +</div><div><a href="https://linuxfr.org/news/php-7-4.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/118316/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/php-7-4#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>Nonolapéro</name> + </author> + <author> + <name>Oliver</name> + </author> + <author> + <name>Davy Defaud</name> + </author> + <author> + <name>Yves Bourguignon</name> + </author> + <author> + <name>ZeroHeure</name> + </author> + <author> + <name>Nils Ratusznik</name> + </author> + <author> + <name>Dafyd</name> + </author> + <author> + <name>Julien Jorge</name> + </author> + <author> + <name>windu.2b</name> + </author> + <author> + <name>Christophe "CHiPs" PETIT</name> + </author> + <author> + <name>bobble bubble</name> + </author> + <author> + <name>Ysabeau</name> + </author> + <author> + <name>dourouc05</name> + </author> + <category term="PHP"/> + <category term="php"/> + <category term="php7"/> + <category term="web"/> + <category term="développement_web"/> + <wfw:commentRss>https://linuxfr.org/nodes/118316/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/39005</id> + <published>2019-01-15T20:11:09+01:00</published> + <updated>2019-01-16T12:02:38+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/drupalcamp-2019"/> + <title>Drupalcamp 2019 </title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>L’association Drupal France et francophonie (drupalfr) annonce le retour dans la capitale de son événement « Drupalcamp 2019 » à l’espace Saintâ€Martin à  Paris III, les 15, 16 et 17 février 2019, autour du CMS Drupal, réalisé en PHP.</p> + +<p>Cette année, nous mettons l’accent sur :</p> + +<ul> +<li>des retours d’expériences pour rassembler de nombreux témoignages d’entreprises utilisatrices de Drupal ;</li> +<li>des conférences données par des professionnels reconnus et des membres de la communauté Drupal, au cours desquels des thématiques nouvelles seront explorées ;</li> +<li>des sessions de découverte étayées par des démonstrations à l’attention d’un public plus novice.</li> +</ul> + +<p>Il commencera le vendredi et continuera le weekâ€end pour permettre de proposer plus de conférences et de thématiques, tout en gardant l’esprit Barcamp.</p> + +<p>Enfin, ce sont les derniers jours pour proposer une conférence, ainsi que pour bénéficier du tarif <em>earlybird</em>, dont vous pourrez prendre connaissance à travers le site officiel.</p> +</div><ul><li>lien náµ’Â 1 : <a title="https://www.drupalcamp.fr" hreflang="fr" href="https://linuxfr.org/redirect/103407">Drupalcamp 2019</a></li><li>lien náµ’Â 2 : <a title="https://paris2019.drupalcamp.fr/je-propose-ma-session" hreflang="fr" href="https://linuxfr.org/redirect/103408">Proposer une conférence</a></li><li>lien náµ’Â 3 : <a title="https://paris2019.drupalcamp.fr/billetterie" hreflang="fr" href="https://linuxfr.org/redirect/103409">Billeterie</a></li><li>lien náµ’Â 4 : <a title="https://paris2019.drupalcamp.fr/sponsors" hreflang="fr" href="https://linuxfr.org/redirect/103410">Devenir sponsors</a></li></ul><div></div><div><a href="https://linuxfr.org/news/drupalcamp-2019.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/116187/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/drupalcamp-2019#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>hellosct1</name> + </author> + <author> + <name>Julien Jorge</name> + </author> + <author> + <name>Davy Defaud</name> + </author> + <author> + <name>claudex</name> + </author> + <category term="PHP"/> + <category term="drupalcamp"/> + <category term="drupal"/> + <wfw:commentRss>https://linuxfr.org/nodes/116187/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/38646</id> + <published>2018-06-07T11:34:02+02:00</published> + <updated>2018-06-07T12:18:25+02:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/appel-a-conferences-pour-le-forum-php-2018-plus-que-deux-semaines-pour-proposer-un-sujet"/> + <title>Appel à conférences pour le Forum PHP 2018 : plus que deux semaines pour proposer un sujet</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>Le 25 et 26 octobre 2018 aura lieu à  Paris le Forum PHP 2018 : deux jours de conférences organisées par l’AFUP, concernant PHP et les technologies du Web qui gravitent autour, par et pour la communauté.</p> + +<p>Afin de préparer cet événement, un appel à conférencières et conférenciers a été lancé, celuiâ€ci se termine le lundi 18 juin au soir. Il vous reste donc deux semaines pour proposer des sujets.</p> + +<p>Que vous soyez chevronné ou débutant, n’hésitez pas : l’AFUP recherche tous types de profils et propose un programme de mentorat pour bénéficier de l’aide d’une oratrice ou d’un orateur confirmé qui peut vous accompagner tout au long de votre démarche, de la soumission du sujet jusqu’à votre conférence. </p> + +<p>Cette année, le CFP permet en plus de suggérer les conférenciers que vous souhaiteriez voir lors de l’événement : l’équipe de sélection étudiera vos propositions avec attention.</p> + +<p>Les formats de conférences possibles sont de 20 à 40 minutes.</p></div><ul><li>lien náµ’Â 1 : <a title="https://event.afup.org/" hreflang="fr" href="https://linuxfr.org/redirect/102192">Site de l’événement</a></li><li>lien náµ’Â 2 : <a title="https://afup.org/event/forumphp2018" hreflang="fr" href="https://linuxfr.org/redirect/102193">Lien direct vers le CFP</a></li></ul><div></div><div><a href="https://linuxfr.org/news/appel-a-conferences-pour-le-forum-php-2018-plus-que-deux-semaines-pour-proposer-un-sujet.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/114658/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/appel-a-conferences-pour-le-forum-php-2018-plus-que-deux-semaines-pour-proposer-un-sujet#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>Adrien Gallou</name> + </author> + <author> + <name>Pierre Jarillon</name> + </author> + <author> + <name>Davy Defaud</name> + </author> + <author> + <name>ZeroHeure</name> + </author> + <author> + <name>Nils Ratusznik</name> + </author> + <category term="PHP"/> + <category term="php"/> + <wfw:commentRss>https://linuxfr.org/nodes/114658/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/38322</id> + <published>2017-12-05T16:56:13+01:00</published> + <updated>2017-12-05T17:38:03+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/derniere-ligne-droite-pour-l-appel-a-conferencier-e-du-phptour-2018"/> + <title>Dernière ligne droite pour l’appel à conférencier·e du PHPTour 2018</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>Les 17 et 18 mai 2018 aura lieu sur Montpellier le PHPTour : un événement organisé par l’AFUP concernant PHP, mais aussi les technologies du Web qui gravitent autour.</p> + +<p>Afin de préparer cet événement, un appel à conférencier·e a été lancé, celuiâ€ci se termine le dimanche 10 décembre. Il vous reste donc très peu de temps pour <a href="https://afup.org/event/phptourmontpellier2018">faire une proposition de sujet</a>.</p> + +<p>Que vous soyiez un·e conférencier·e chevronné·e ou débutant·e, n’hésitez pas : l’AFUP recherche tous types de profils pour le PHPTour, qui se définit comme la conférence du Web, du PHP et des technologies associées, par et pour la communauté.</p> + +<p>L‘AFUP propose également un programme de <em>mentoring</em> grâce auquel vous pouvez bénéficier de l’aide d’un·e orat·rice.eur confirmé·e, qui peut vous accompagner tout au long de votre démarche, de la soumission du sujet jusqu’à votre conférence. </p> + +<p>Les formats de conférences possibles sont de 20 à 40 minutes.</p> + +<p>Si vous ne souhaitez pas soumettre de sujet, il vous est toujours possible d’aider l’équipe organisatrice <a href="https://afup.org/event/phptourmontpellier2018">en votant pour les conférences</a>, cela permettra de prendre le pouls de la communauté et de connaître les sujets le plus demandés.</p></div><ul><li>lien náµ’Â 1 : <a title="https://event.afup.org/" hreflang="fr" href="https://linuxfr.org/redirect/101070">Site de l’événement</a></li><li>lien náµ’Â 2 : <a title="https://afup.org/event/phptourmontpellier2018" hreflang="fr" href="https://linuxfr.org/redirect/101071">Lien direct vers le CFP</a></li><li>lien náµ’Â 3 : <a title="https://linuxfr.org/users/bricef/journaux/cfp-php-tour-montpellier-ouvert-jusqu-au-10-decembre-2017" hreflang="fr" href="https://linuxfr.org/redirect/101072">Journal : CFP PHP Tour Montpellier ouvert jusqu’au 10 décembre 2017</a></li></ul><div></div><div><a href="https://linuxfr.org/news/derniere-ligne-droite-pour-l-appel-a-conferencier-e-du-phptour-2018.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/113253/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/derniere-ligne-droite-pour-l-appel-a-conferencier-e-du-phptour-2018#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>Adrien Gallou</name> + </author> + <author> + <name>Davy Defaud</name> + </author> + <author> + <name>Benoît Sibaud</name> + </author> + <author> + <name>Nÿco</name> + </author> + <category term="PHP"/> + <category term="php"/> + <category term="phptour"/> + <wfw:commentRss>https://linuxfr.org/nodes/113253/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/38207</id> + <published>2017-10-03T10:00:01+02:00</published> + <updated>2017-10-08T17:43:03+02:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/drupalcamp-2017-lannion"/> + <title>DrupalCamp 2017 Lannion</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p><strong>Après Nantes, c’est au tour de Lannion d’accueillir le DrupalCamp 2017.</strong></p> + +<p>Le DrupalCamp est proposé par l’association Drupal France et francophonie. Il se déroulera <strong>du 27 au 29 octobre 2017</strong>, à l’Espace Sainteâ€Anne de Lannion (22).</p> + +<p>Ce sera l’occasion de découvrir ce gestionnaire de contenu (CMS) ou en approfondir ses connaissances au cours de trois jours de conférences et de rencontres.</p> + +<p>Sprints, conférences et discussions sont <strong>accessibles librement</strong>, à tous les niveaux techniques et fonctionnels, à tous les profils du développeur à l’utilisateur. Toutes ces rencontres se font dans la bonne humeur, des soirées étant aussi organisées les vendredi et samedi soirs (accessibles avec le pack weekâ€end).</p></div><ul><li>lien náµ’Â 1 : <a title="https://lannion2017.drupalcamp.bzh" hreflang="fr" href="https://linuxfr.org/redirect/100715">DrupalCamp 2017 Lannion</a></li><li>lien náµ’Â 2 : <a title="https://www.drupal.fr" hreflang="fr" href="https://linuxfr.org/redirect/100716">Drupal.fr</a></li></ul><div><h3 id="quest-que-drupal">Qu’est que Drupal</h3> + +<p>Drupal est un CMS (système de gestion de contenu) libre, gratuit et <em>Open Source</em> écrit en PHP.<br> +Dries Buytaert, qui en a développé la première version (2001, Université d’Anvers), le désigne alors comme « un assembleur rapide de site » (<em>rapid Website assembler</em>). La dernière version (8) est sortie en novembre 2015, elle a bénéficié d’une refonte en profondeur avec notamment l’intégration de composants du cadriciel Symfony.</p> + +<p>Drupal est un outil qui s’adresse à la fois aux débutants et aux programmeurs experts.</p> +<h3 id="programme">Programme</h3> + +<p>Les journées de vendredi et samedi sont dédiées aux conférences et discussions. La journée du dimanche est consacrée aux ateliers et sprints (contributions). Un atelier est déjà prévu : un sprint de traduction de <strong>Drupal en breton</strong>. <a href="https://lannion2017.drupalcamp.bzh/brezhonneg">https://lannion2017.drupalcamp.bzh/brezhonneg</a></p> + +<p>Le contenu définitif du programme sera dévoilé début octobre, d’ici là vous pouvez consulter les propositions d’ateliers sur cette page ou proposer les vôtres :<br><a href="https://lannion2017.drupalcamp.bzh/programme/sessions-proposees">https://lannion2017.drupalcamp.bzh/programme/sessions-proposees</a>.</p> +<h3 id="inscription">Inscription</h3> + +<p><strong>L’accès aux conférences et ateliers est complètement gratuit !</strong></p> + +<p>Mais vous pouvez réserver un « pack weekâ€end » qui propose deux repas le midi, des cafés, l’accès aux soirées communautaires, un Tâ€shirt ou un sac de « <em>goodies</em> ».</p> +<h3 id="informations-pratiques">Informations pratiques</h3> + +<ul> +<li>horaires : de 9 h à  18 h 30</li> +<li>lieu : Espace Sainteâ€Anne, 2 rue de Kerampont, 22300 Lannion</li> +<li>tarif : entrée libre !</li> +</ul><h3 id="contacts">Contacts</h3> + +<ul> +<li>site : <a href="https://lannion2017.drupalcamp.bzh">https://lannion2017.drupalcamp.bzh</a> +</li> +<li>Twitter : <a href="https://twitter.com/drupalcampfr"><em>@drupalcampfr</em></a> +</li> +<li>Facebook : <a href="https://www.facebook.com/groups/adfffff/">https://www.facebook.com/groups/adfffff/</a> +</li> +<li>Instagram : <a href="https://www.instagram.com/drupalfrance/">https://www.instagram.com/drupalfrance/</a> +</li> +</ul></div><div><a href="https://linuxfr.org/news/drupalcamp-2017-lannion.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/112714/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/drupalcamp-2017-lannion#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>obriat</name> + </author> + <author> + <name>Davy Defaud</name> + </author> + <author> + <name>Benoît Sibaud</name> + </author> + <category term="PHP"/> + <category term="drupal"/> + <category term="cms"/> + <category term="php"/> + <category term="lannion"/> + <category term="bzh"/> + <wfw:commentRss>https://linuxfr.org/nodes/112714/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/38018</id> + <published>2017-05-29T13:53:28+02:00</published> + <updated>2017-05-29T15:39:24+02:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/cheky"/> + <title>Cheky</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>Cheky (anciennement LBCAlerte) est un logiciel sous licence GPL v3 permettant de recevoir des alertes pour <em>Leboncoin.fr</em> et <em>SeLoger.com</em>.</p> + +<p>Les alertes peuvent se faire sous plusieurs formes :</p> + +<ul> +<li>envoi de courriel ;</li> +<li>envoi de SMS via l'API Free Mobile et OVH Telecom  ;</li> +<li>envoi de notification (Pushbullet, Pushover, etc.) ;</li> +<li>par flux RSS.</li> +</ul><p>La fonction secondaire de Cheky est de vous permettre de <a href="https://www.cheky.net/documentation/sauvegarder-annonces-leboncoin">sauvegarder les annonces <em>Leboncoin</em></a> (avec contenu + photos). Cette sauvegarde conserve les annonces en cas de suppression ou de modification sur <em>Leboncoin</em>.</p> + +<p>Pour en savoir plus, voyez la suite…</p></div><ul><li>lien náµ’Â 1 : <a title="https://www.cheky.net" hreflang="fr" href="https://linuxfr.org/redirect/99938">Site du projet</a></li><li>lien náµ’Â 2 : <a title="https://www.cheky.net/documentation" hreflang="fr" href="https://linuxfr.org/redirect/99939">Documentation</a></li><li>lien náµ’Â 3 : <a title="https://github.com/Blount/LBCAlerte" hreflang="en" href="https://linuxfr.org/redirect/99940">Dépôt GitHub</a></li><li>lien náµ’Â 4 : <a title="https://forum.cheky.net" hreflang="fr" href="https://linuxfr.org/redirect/99941">Forum pour le support</a></li></ul><div><p>Le logiciel est développé en PHP (≥ 5.4) et HTML/CSS. Un serveur Web sera nécessaire pour le faire fonctionner et une tâche <code>cron</code> devra être configurée. Le stockage des données se fait soit par fichier soit par base de données MySQL. Cheky est conçu pour être léger afin qu’il puisse tourner sur tout type de matériel, notamment sur des Raspberry. En outre, il n’y a aucune garantie de compatibilité avec Windows, je n’ai tout simplement jamais testé Cheky sous ce système d’exploitation.</p> + +<p>Une extension pour Firefox existe, mais c’est une galère monstre de faire valider les extensions sur leur dépôt de module. Un mois à attendre (et obtenir finalement un refus) pour avoir utilisé Mootools construit via leur <em>builder</em> officiel, afin de retirer des parties incompatibles avec le mode extension de Firefox. Bref, leur système actuel de validation est vraiment un repoussoir à développeur (mon point de vue). Je vais donc voir à héberger moiâ€même l’extension, tout en la faisant signer chez eux si c’est possible.</p> + +<p>Concernant la <a href="https://www.cheky.net/documentation">documentation</a>, je tente au mieux de la maintenir à  jour au fil des versions, ce qui n’est pas toujours évident, car cela demande du temps. En complément de la documentation, j’apporte un support via un <a href="https://forum.cheky.net/">forum</a>.</p> + +<p>Étant le principal développeur (99 %) de Cheky, je suis donc votre interlocuteur privilégié pour toute proposition d’amélioration ou de correction.</p></div><div><a href="https://linuxfr.org/news/cheky.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/111967/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/cheky#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>Blount</name> + </author> + <author> + <name>Nils Ratusznik</name> + </author> + <author> + <name>Pierre Jarillon</name> + </author> + <author> + <name>Benoît Sibaud</name> + </author> + <author> + <name>ZeroHeure</name> + </author> + <author> + <name>Davy Defaud</name> + </author> + <category term="PHP"/> + <category term="alerte"/> + <category term="leboncoin"/> + <category term="seloger"/> + <category term="firefox"/> + <wfw:commentRss>https://linuxfr.org/nodes/111967/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/37766</id> + <published>2017-01-02T17:42:00+01:00</published> + <updated>2017-01-02T20:31:14+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/codevtt-v1-2-0-suivi-d-activite-et-gestion-de-projet-avec-mantisbt"/> + <title>CodevTT v1.2.0 : suivi d’activité et gestion de projet avec MantisBT</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>CodevTT est un outil libre (GPL v3) de gestion de projet réactif en lien direct avec le développement, permettant un suivi détaillé de l’avancement des projets et des activités de l’équipe.</p> + +<p>Sa caractéristique principale est d’être en lien direct avec MantisBT — un système de suivi d’anomalies — dont on étendra le périmètre d’activité.</p> + +<p>Parmi les nouveautés de la version 1.2.0 : améliorations de l’interface graphique, de nouveaux greffons et un nouveau planificateur de tâches permettant de répartir la charge d’une tâche sur plusieurs personnes.</p> + +<p><img src="//img.linuxfr.org/img/687474703a2f2f636f64657674742e6f72672f736974652f77702d636f6e74656e742f75706c6f6164732f323031322f30322f636f64657674745f6c6f676f5f30335f6d696e692e706e67/codevtt_logo_03_mini.png" alt="CodevTT" title="Source : http://codevtt.org/site/wp-content/uploads/2012/02/codevtt_logo_03_mini.png"></p></div><ul><li>lien náµ’Â 1 : <a title="http://codevtt.org" hreflang="en" href="https://linuxfr.org/redirect/99020">Site officiel</a></li><li>lien náµ’Â 2 : <a title="https://youtu.be/StMHEF0dP88" hreflang="fr" href="https://linuxfr.org/redirect/99021">Vidéo de présentation (YouTube)</a></li><li>lien náµ’Â 3 : <a title="http://codevtt.org/codev/" hreflang="fr" href="https://linuxfr.org/redirect/99022">Démo en ligne</a></li><li>lien náµ’Â 4 : <a title="http://codevtt.org/site/?page_id=116" hreflang="fr" href="https://linuxfr.org/redirect/99023">Captures d’écran</a></li><li>lien náµ’Â 5 : <a title="https://github.com/lbayle/codev/blob/master/doc/fr/CodevTT_Kit_demarrage.pdf?raw=true" hreflang="fr" href="https://linuxfr.org/redirect/99024">Documentation (PDF)</a></li><li>lien náµ’Â 6 : <a title="https://github.com/lbayle/codev" hreflang="fr" href="https://linuxfr.org/redirect/99025">Code source (GitHub)</a></li></ul><div><p>En puisant des informations dans la base de données de MantisBT et en proposant un système simple de saisie des comptesâ€rendus d’activité aux utilisateurs, CodevTT réduit considérablement le nombre d’opérations manuelles à effectuer pour générer rapports, statistiques, alertes, plannings, <a href="https://fr.wikipedia.org/wiki/Diagramme_de_Gantt">diagrammes de Gantt</a> et autres indicateurs de production et de suivi.</p> + +<p>Les données de MantisBT étant tenues à jour en permanence par les développeurs, le chef de projet peut avoir une vue en temps réel de l’avancement du projet, sans créer de surcharge de travail pour l’équipe. Les informations et alertes remontées par CodevTT permettent au chef de projet d’identifier plus rapidement les points durs du projet. La réduction d’un grand nombre de tâches récurrentes lui permet de se concentrer davantage sur les parties nécessitant le plus d’attention et d’analyse.</p> + +<p>Les statistiques aident à identifier les actions à entreprendre pour améliorer la productivité de l’équipe et permettront d’en mesurer l’efficacité à court, moyen et long terme. La section <em>Contrats et Commandes</em> permet d’avoir une vue client de l’avancement et propose des indicateurs qui pourront lui être remontés.</p> + +<p>CodevTT est donc un outil de gestion de projet réactif, en lien direct avec le développement. Il se fixe comme objectif la maîtrise du suivi et la réduction des coûts de gestion de projet par la simplification et l’automatisation des processus.</p> + +<p>CodevTT est un logiciel libre soutenu par AtoS, qui l’utilise en interne pour gérer ses projets (avec une base d’utilisateurs actuelle d’environ 300 personnes).</p></div><div><a href="https://linuxfr.org/news/codevtt-v1-2-0-suivi-d-activite-et-gestion-de-projet-avec-mantisbt.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/110940/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/codevtt-v1-2-0-suivi-d-activite-et-gestion-de-projet-avec-mantisbt#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>lbayle</name> + </author> + <author> + <name>Davy Defaud</name> + </author> + <author> + <name>Benoît Sibaud</name> + </author> + <category term="PHP"/> + <category term="mantisbt"/> + <category term="timetracking"/> + <category term="codevtt"/> + <category term="projet"/> + <category term="gestion"/> + <category term="suivi_d'activité"/> + <wfw:commentRss>https://linuxfr.org/nodes/110940/comments.atom</wfw:commentRss> + </entry> + <entry> + <id>tag:linuxfr.org,2005:News/37714</id> + <published>2016-12-10T23:57:33+01:00</published> + <updated>2016-12-11T13:02:54+01:00</updated> + <link rel="alternate" type="text/html" href="https://linuxfr.org/news/api-platform-2-un-cadriciel-pour-creer-des-api-web-hypermedia-en-quelques-minutes"/> + <title>API Platform 2 : un cadriciel pour créer des API Web hypermédia en quelques minutes</title> + <rights>Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr</rights> + <content type="html"><div><p>Après une année de développements et plus de 700 <em>commits</em> réalisés par plus d’une centaine de contributeurs à travers le monde, la nouvelle version d’API Platform vient d’être publiée. API Platform v2 est une réécriture profonde du cadriciel (<em>framework</em>) incluant une refonte complète de la conception, des ajouts de nouvelles fonctionnalités et des corrections de bogues.</p> + +<p>API Platform est un <em>framework</em> libre (licence MIT) écrit en PHP 7 et basé sur <a href="https://fr.wikipedia.org/wiki/Symfony">Symfony</a> destiné à la création d’API Web modernes, puissantes et sécurisées. Cet outil est particulièrement adapté à la construction de systèmes d’informations « <em>API-centric</em> » basés sur l’<a href="https://en.wikipedia.org/wiki/HATEOAS">hypermédia</a> et le <a href="https://fr.wikipedia.org/wiki/Web_des_donn%C3%A9es">Web des données</a> (<em>linked data</em>). Il permet de réaliser facilement des applications d’une seule page (<a href="https://en.wikipedia.org/wiki/Single-page_application"><em>singleâ€page applications</em></a>) ou dédiées aux mobiles en utilisant des bibliothèques JavaScript telles que <a href="https://fr.wikipedia.org/wiki/React_%28JavaScript%29=">React</a> ou <a href="https://fr.wikipedia.org/wiki/AngularJS">AngularJS</a>.</p> + +<p>Le sponsor principal d’API Platform est la société coopérative lilloise <a href="https://les-tilleuls.coop">Les-Tilleuls.coop</a>. Il s’agit d’une <a href="https://fr.wikipedia.org/wiki/Soci%C3%A9t%C3%A9_coop%C3%A9rative_et_participative">SCOP</a> spécialisée dans la conception et la réalisation de logiciels comptant une vingtaine de salariés qui pratiquent l’autogestion et se partagent les bénéfices engrangés de manière égalitaire.</p> + +<p><img src="//img.linuxfr.org/img/68747470733a2f2f64756e676c61732e66722f77702d636f6e74656e742f75706c6f6164732f323031362f31312f4150492d506c6174666f726d2d64656d6f2e706e67/API-Platform-demo.png" alt="Capture d'écran" title="Source : https://dunglas.fr/wp-content/uploads/2016/11/API-Platform-demo.png"></p> + +<p>En seconde partie de la dépêche, vous trouverez une traduction en français de l’annonce de sortie de cette version deux, qui revient sur les fonctionnalités principales du cadriciel.</p></div><ul><li>lien náµ’Â 1 : <a title="https://api-platform.com" hreflang="en" href="https://linuxfr.org/redirect/98786">Site Web d’API Platform</a></li><li>lien náµ’Â 2 : <a title="https://github.com/api-platform/api-platform" hreflang="en" href="https://linuxfr.org/redirect/98787">Le code source sur GitHub</a></li><li>lien náµ’Â 3 : <a title="https://dunglas.fr/2016/11/api-platform-2-0-released-creating-powerful-web-apis-has-never-been-so-easy/" hreflang="en" href="https://linuxfr.org/redirect/98788">L’annonce de la sortie de la version 2</a></li><li>lien náµ’Â 4 : <a title="https://les-tilleuls.coop" hreflang="fr" href="https://linuxfr.org/redirect/98789">La SCOP Les-Tilleuls.coop</a></li></ul><div><h2 class="sommaire">Sommaire</h2> +<ul class="toc"> +<li><ul> +<li><a href="#exposer-une-api-en-quelques-secondes-gr%C3%A2ce-au-nouveau-syst%C3%A8me-des-configuration-et-de-m%C3%A9tadonn%C3%A9es">Exposer une API en quelques secondes grâce au nouveau système des configuration et de métadonnées</a></li> +<li><a href="#int%C3%A9gration-de-docker">Intégration de Docker</a></li> +<li><a href="#un-g%C3%A9n%C3%A9rateur-de-mod%C3%A8le-de-donn%C3%A9es-am%C3%A9lior%C3%A9">Un générateur de modèle de données amélioré</a></li> +<li><a href="#la-n%C3%A9gociation-de-contenu-et-le-support-int%C3%A9gr%C3%A9-pour-json-ld-hydra-hal-yaml-csv-et-xml">La négociation de contenu et le support intégré pour JSON-LD, Hydra, HAL, YAML, CSV et XML</a></li> +<li><a href="#une-interface-utilisateur-pratique-et-une-documentation-swagger2-automatique">Une interface utilisateur pratique et une documentation Swagger 2 automatique</a></li> +<li><a href="#de-nouveaux-filtres">De nouveaux filtres</a></li> +<li><a href="#s%C3%A9curis%C3%A9-par-d%C3%A9faut-respectant-les-recommandations-de-lowasp">Sécurisé par défaut, respectant les recommandations de l’OWASP</a></li> +<li><a href="#am%C3%A9lioration-des-performances">Amélioration des performances</a></li> +<li><a href="#mise-%C3%A0-disposition-en-tant-que-composants-autonomes-dissoci%C3%A9s-de-symfony-et-doctrine">Mise à disposition en tant que composants autonomes, dissociés de Symfony et Doctrine</a></li> +<li><a href="#qualit%C3%A9-du-code-et-tests-automatis%C3%A9s">Qualité du code et tests automatisés</a></li> +<li><a href="#r%C3%A9%C3%A9criture-de-la-documentation-et-nouveau-site-web">Réécriture de la documentation et nouveau site Web</a></li> +<li><a href="#une-communaut%C3%A9-en-plein-essor">Une communauté en plein essor</a></li> +<li><a href="#les-prochaines-%C3%A9tapes">Les prochaines étapes</a></li> +</ul></li> +</ul><p>API Platform repose sur trois principes fondateurs :</p> + +<ol> +<li>créer une API facilement et rapidement : n’importe quel développeur Web doit pouvoir créer une API REST et obtenir le support du <a href="https://fr.wikipedia.org/wiki/CRUD">CRUD</a>, une documentation autoâ€générée, l’authentification via JSON Web Token ou <a href="https://fr.wikipedia.org/wiki/OAuth" title="Définition Wikipédia">OAuth</a>, la gestion des enâ€têtes <a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing" title="Crossâ€origin resource sharing">CORS</a>, la validation des données, les tris et les filtres, le cache, etc. ;</li> +<li>les formats ouverts modernes sont gérés nativement, sans demander de travail supplémentaire pour le développeur : Swagger/OpenAPI, JSON-LD, Hydra, HAL, API Problem (RFC 7807), Schema.org sont pris en charge par défaut et la couche d’abstraction fournie par le cadriciel permet d’ajouter facilement le prise en charge d’autres nouveaux formats d’API (JSON API et GraphQL sont actuellement en cours de développement) ;</li> +<li>chaque fonctionnalité du cadriciel doit être extensible, modulaire et débrayable.</li> +</ol><h3 id="exposer-une-api-en-quelques-secondes-grâce-au-nouveau-système-des-configuration-et-de-métadonnées">Exposer une API en quelques secondes grâce au nouveau système des configuration et de métadonnées</h3> + +<p>Grâce au nouveau système de configuration et au composant de métadonnées (la couche d’abstraction entre les différents formats pris en charge), vous pouvez créer de manière très simple une API hypermédia de qualité en modélisant vos données sous forme de classes PHP et en ajoutant quelques annotations.</p> + +<p>Exemple :</p> + +<pre><code class="php"><span class="o">&lt;?</span><span class="nx">php</span> + +<span class="c1">// src/AppBundle/Entity/Book.php</span> + +<span class="k">namespace</span> <span class="nx">AppBundle\Entity</span><span class="p">;</span> + +<span class="k">use</span> <span class="nx">ApiPlatform\Core\Annotation\ApiResource</span><span class="p">;</span> +<span class="k">use</span> <span class="nx">Doctrine\ORM\Mapping</span> <span class="k">as</span> <span class="nx">ORM</span><span class="p">;</span> +<span class="k">use</span> <span class="nx">Symfony\Component\Validator\Constraints</span> <span class="k">as</span> <span class="nx">Assert</span><span class="p">;</span> + +<span class="sd">/**</span> +<span class="sd"> * A book.</span> +<span class="sd"> *</span> +<span class="sd"> * @ApiResource</span> +<span class="sd"> * @ORM\Entity</span> +<span class="sd"> */</span> +<span class="k">class</span> <span class="nc">Book</span> +<span class="p">{</span> + <span class="sd">/**</span> +<span class="sd"> * @var int The id of this book.</span> +<span class="sd"> *</span> +<span class="sd"> * @ORM\Id</span> +<span class="sd"> * @ORM\GeneratedValue</span> +<span class="sd"> * @ORM\Column(type="integer")</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="nv">$id</span><span class="p">;</span> + + <span class="sd">/**</span> +<span class="sd"> * @var string|null The ISBN number of this book (or null if it doesn't have one).</span> +<span class="sd"> *</span> +<span class="sd"> * @ORM\Column(nullable=true)</span> +<span class="sd"> * @Assert\Isbn</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="nv">$isbn</span><span class="p">;</span> + + <span class="sd">/**</span> +<span class="sd"> * @var string The title of this book.</span> +<span class="sd"> *</span> +<span class="sd"> * @ORM\Column</span> +<span class="sd"> * @Assert\NotBlank</span> +<span class="sd"> */</span> + <span class="k">public</span> <span class="nv">$title</span><span class="p">;</span> + + <span class="c1">// Prefer private properties, accessors and mutators in real applications</span> +<span class="p">}</span></code></pre> + +<p>Cette classe est suffisante pour obtenir une API fonctionnelle, supportant les fonctionnalités suivantes :</p> + +<ul> +<li>des <a href="https://api-platform.com/docs/core/operations">opérations CRUD</a> ;</li> +<li>la <a href="https://api-platform.com/docs/core/validation">validation des données</a> et la sérialisation des erreurs aux formats JSON-LD, Swagger et Hydra ;</li> +<li>la <a href="https://api-platform.com/docs/core/pagination">pagination</a> ;</li> +<li>une interface utilisateur agréable et une documentation autogénérée utilisant les données de la PHPDoc.</li> +</ul><p>Consultez la <a href="https://demo.api-platform.com/">démo</a> pour tester un exemple plus avancé (<a href="https://github.com/api-platform/demo/">code source</a> de seulement deux classes) !</p> + +<p>Les relations hypermédias entre les différentes ressources exposées par l’API sont gérées nativement. Utiliser n’importe quelle autre fonctionnalité d’API Platform consiste juste à ajouter quelques lignes de configuration. Découvrez ça dans le <a href="https://api-platform.com/docs/distribution/">guide de démarrage</a>.</p> + +<p>Si vous n’aimez pas les annotations, vous pouvez utiliser les fichiers de configuration au format XML ou YAML à la place. Si vous n’aimez pas la correspondance objetâ€base de données (<a href="https://fr.wikipedia.org/wiki/Mapping_objet-relationnel" title="Objectâ€Relational Mapping">ORM</a>) de <a href="https://fr.wikipedia.org/wiki/Doctrine_%28ORM%29">Doctrine</a> ou si vous ne souhaitez pas utiliser le validateur de <a href="https://fr.wikipedia.org/wiki/Symfony">Symfony</a>, vous pouvez créer des adaptateurs pour brancher votre code personnalisé et utiliser vos bibliothèques préférées. En somme, API Platform a été conçu pour être complètement extensible.</p> +<h3 id="intégration-de-docker">Intégration de Docker</h3> + +<p>La distribution officielle d’API Platform est fournie avec une configuration Docker adaptée au développement d’API. Cela inclut Apache et PHP 7 et une image de MySQL. Pour faire fonctionner une application API Platform de manière optimisée sur votre machine, tapez les commandes suivantes dans son répertoire racine :</p> + +<pre><code class="bash"><span class="nv">$ </span>docker-compose up -d <span class="c"># Télécharge, construit et exécute les images Docker</span> +<span class="nv">$ </span>docker-compose <span class="nb">exec </span>web bin/console doctrine:schema:create <span class="c"># Crée le schéma MySQL, nécessaire une seule fois</span></code></pre> + +<p>Une fois que l’application est démarrée, rendez vous sur <a href="http://localhost/">http://localhost/</a> pour commencer à jouer avec votre API.</p> + +<p>Les images d’API Platform peuvent également être déployées en production facilement en utilisant Docker Swarm (Amazon Web Services, Azure…) ou Google Container Engine (avec Kubernetes).</p> +<h3 id="un-générateur-de-modèle-de-données-amélioré">Un générateur de modèle de données amélioré</h3> + +<p>Au lieu de créer votre propre modèle de données, pourquoi ne pas réutiliser des vocabulaires ouverts comme le très populaire Schema.org et ainsi profiter de la puissance du Web des données et du Web sémantique ? Exactement comme le fait Google, mais grâce à un cadriciel 100 % libre.</p> + +<p>Depuis sa première sortie, API Platform est fourni avec un générateur de code permettant de créer un modèle de données en PHP incluant les classes, les propriétés, les accesseurs et mutateurs (<em>getters</em> et <em>setters</em>), une PHPDoc complète, les correspondances avec l’ORM Doctrine, les annotations de validation et la correspondance avec le vocabulaire externe pris en charge par API Platform. Ce générateur a été mis à jour afin d’être compatible avec la nouvelle configuration d’API Platform 2. Grâce à ce générateur couplé au système de création d’API d’API Platform, vous pouvez réaliser une API fonctionnelle sans écrire une seule ligne de PHP :</p> + +<pre><code class="yaml"><span class="l-Scalar-Plain">types</span><span class="p-Indicator">:</span> + <span class="l-Scalar-Plain">Book</span><span class="p-Indicator">:</span> + <span class="l-Scalar-Plain">parent</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">false</span> <span class="c1"># Generate only one class, not the full hierarchy from Schema.org</span> + <span class="l-Scalar-Plain">properties</span><span class="p-Indicator">:</span> + <span class="l-Scalar-Plain">isbn</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">~</span> + <span class="l-Scalar-Plain">name</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">~</span> + <span class="l-Scalar-Plain">description</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">~</span> + <span class="l-Scalar-Plain">author</span><span class="p-Indicator">:</span> <span class="p-Indicator">{</span> <span class="nv">range</span><span class="p-Indicator">:</span> <span class="nv">Text</span> <span class="p-Indicator">}</span> + <span class="l-Scalar-Plain">dateCreated</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">~</span> + <span class="l-Scalar-Plain">Review</span><span class="p-Indicator">:</span> + <span class="l-Scalar-Plain">parent</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">false</span> + <span class="l-Scalar-Plain">properties</span><span class="p-Indicator">:</span> + <span class="l-Scalar-Plain">reviewBody</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">~</span> + <span class="l-Scalar-Plain">rating</span><span class="p-Indicator">:</span> <span class="p-Indicator">{</span> <span class="nv">range</span><span class="p-Indicator">:</span> <span class="nv">Integer</span><span class="p-Indicator">,</span> <span class="nv">nullable</span><span class="p-Indicator">:</span> <span class="nv">false</span> <span class="p-Indicator">}</span> <span class="c1"># This is a custom field that doesn't exist in the vocab</span> + <span class="l-Scalar-Plain">itemReviewed</span><span class="p-Indicator">:</span> <span class="p-Indicator">{</span> <span class="nv">range</span><span class="p-Indicator">:</span> <span class="nv">Book</span><span class="p-Indicator">,</span> <span class="nv">nullable</span><span class="p-Indicator">:</span> <span class="nv">false</span><span class="p-Indicator">,</span> <span class="nv">cardinality</span><span class="p-Indicator">:</span> <span class="s">'(*..1)'</span> <span class="p-Indicator">}</span></code></pre> + +<p>Découvrezâ€en plus au sujet du générateur dans la <a href="https://api-platform.com/docs/schema-generator/getting-started">documentation</a> et la <a href="https://github.com/api-platform/demo/pull/3">démo</a>.</p> +<h3 id="la-négociation-de-contenu-et-le-support-intégré-pour-json-ld-hydra-hal-yaml-csv-et-xml">La négociation de contenu et le support intégré pour JSON-LD, Hydra, HAL, YAML, CSV et XML</h3> + +<pre><code class="yaml"><span class="c1"># app/config/config.yml</span> + +<span class="l-Scalar-Plain">api_platform</span><span class="p-Indicator">:</span> + <span class="l-Scalar-Plain">formats</span><span class="p-Indicator">:</span> + <span class="l-Scalar-Plain">jsonld</span><span class="p-Indicator">:</span> <span class="p-Indicator">[</span><span class="s">'application/ld+json'</span><span class="p-Indicator">]</span> + <span class="l-Scalar-Plain">jsonhal</span><span class="p-Indicator">:</span> <span class="p-Indicator">[</span><span class="s">'application/hal+json'</span><span class="p-Indicator">]</span> + <span class="l-Scalar-Plain">xml</span><span class="p-Indicator">:</span> <span class="p-Indicator">[</span><span class="s">'application/xml'</span><span class="p-Indicator">,</span> <span class="s">'text/xml'</span><span class="p-Indicator">]</span> + <span class="l-Scalar-Plain">json</span><span class="p-Indicator">:</span> <span class="p-Indicator">[</span><span class="s">'application/json'</span><span class="p-Indicator">]</span> + <span class="l-Scalar-Plain">yaml</span><span class="p-Indicator">:</span> <span class="p-Indicator">[</span><span class="s">'application/x-yaml'</span><span class="p-Indicator">]</span> + <span class="l-Scalar-Plain">csv</span><span class="p-Indicator">:</span> <span class="p-Indicator">[</span><span class="s">'text/csv'</span><span class="p-Indicator">]</span> + <span class="l-Scalar-Plain">html</span><span class="p-Indicator">:</span> <span class="p-Indicator">[</span><span class="s">'text/html'</span><span class="p-Indicator">]</span> <span class="c1"># This is the API Platform UI</span></code></pre> + +<p>Cette configuration donne accès à l’ensemble des formats disponibles (Symfony 3.2 — actuellement en version candidate — est requis pour la prise en charge du <a href="https://fr.wikipedia.org/wiki/YAML" title="YAML Ain’t a Markup Language — YAML n’est pas un langage de balisage">YAML</a> et du <a href="https://fr.wikipedia.org/wiki/Comma-separated_values" title="Commaâ€separated_values — Valeurs séparées par des virgules">CSV</a>). Dès lors, vous pouvez préciser le format souhaité à travers l’interface utilisateur ; en utilisant les enâ€têtes HTTP adéquats, ou en ajoutant le nom du format en extension de n’importe quelle adresse URL de l’API (exemple : <a href="https://demo.api-platform.com/books.jsonld">https://demo.api-platform.com/books.jsonld</a>). L’ajout et l’utilisation de formats non pris en charge par défaut peuvent être réalisés en écrivant des adaptateurs personnalisés.</p> + +<p><a href="https://api-platform.com/docs/core/content-negotiation">Découvrez plus de détails au sujet de la négociation de contenu dans API Platform</a>.</p> +<h3 id="une-interface-utilisateur-pratique-et-une-documentation-swagger2-automatique">Une interface utilisateur pratique et une documentation Swagger 2 automatique</h3> + +<p>API Platform 2 génère une documentation extensive au format <a href="http://swagger.io/getting-started/">Swagger 2</a> / <a href="https://en.wikipedia.org/wiki/OpenAPI_Specification">OpenAPI</a>. Toutes les adresses URL et types sont automatiquement décrits grâce à notre système d’extraction des métaâ€données.</p> + +<p>Une interface Web construite à partir de Swagger UI est aussi automatiquement mise à disposition. Faites appel à n’importe quelle adresse URL de l’API en utilisant un navigateur Web et (grâce à l’enâ€tête HTTP <code>Accept</code> envoyé par le navigateur) API Platform va afficher la requête envoyée à l’API, ainsi que la réponse reçue dans une interface Web agréable. Une documentation humainement compréhensible de l’opération en cours sera également affichée.</p> + +<p><img src="//img.linuxfr.org/img/68747470733a2f2f64756e676c61732e66722f77702d636f6e74656e742f75706c6f6164732f323031362f31312f4150492d506c6174666f726d2d55492e706e67/API-Platform-UI.png" alt="Doc" title="Source : https://dunglas.fr/wp-content/uploads/2016/11/API-Platform-UI.png"></p> + +<p>Explorez la page d’accueil de votre API pour découvrir la documentation de toutes les opérations disponibles, incluant la description de toutes les ressources et propriétés extraites des métaâ€données PHP. Utilisez le bac à sable pour jouer avec votre API.</p> +<h3 id="de-nouveaux-filtres">De nouveaux filtres</h3> + +<p>Quelques nouveaux filtres ont été ajoutés en complément des filtres existants de recherche, d’ordre, de tri ou de date :</p> + +<ul> +<li>le filtre <a href="https://api-platform.com/docs/core/filters#boolean-filter">booléen</a> permettant de filtrer les propriétés booléennes ;</li> +<li>le filtre <a href="https://api-platform.com/docs/core/filters#numeric-filter">numérique</a> permettant de filtrer les champs numériques.</li> +</ul><p>Ces filtres sont désormais disponibles depuis l’interface utilisateur et documentés dans les formats Hydra et Swagger. <a href="https://api-platform.com/docs/core/filters">Découvrez comment ajouter des filtres dans votre collection d’API</a>.</p> + +<p>Les filtres sont désormais implémentés grâce à l’utilisation du tout nouveau système d’extension. Ce système permet de se brancher aux processus de génération des requêtes base de données afin de les modifier. Il est particulièrement utile pour implémenter des fonctionnalités de sécurité. <a href="https://api-platform.com/docs/core/extensions">Découvrez comment exploiter le mécanisme d’extension pour filtrer le résultat d’un point d’entrée en fonction du rôle de l’utilisateur connecté</a>.</p> +<h3 id="sécurisé-par-défaut-respectant-les-recommandations-de-lowasp">Sécurisé par défaut, respectant les recommandations de l’OWASP</h3> + +<p>Toutes les fonctionnalités d’API Platform 2 suivent les recommandations de sécurité édictée par l’<a href="https://www.owasp.org">OWASP</a>. Nous avons créé une suite de tests pour nous assurer que toutes ces recommandations soient respectées et documentées. <a href="https://github.com/api-platform/core/tree/master/features/security">Découvrez comment API Platform 2 sécurise votre API</a>.</p> +<h3 id="amélioration-des-performances">Amélioration des performances</h3> + +<p>Nous sommes continuellement en train d’améliorer les performances d’API Platform et des composants Symfony que le cadriciel utilise (comme le sérialiseur ou le composant PropertyAccess). Cette nouvelle version est plus rapide que la version 1 et optimise automatiquement les requêtes SQL en fonction des groupes de sérialisation. API Platform 2 est également compatible avec PHP PM. En l’utilisant, les temps de réponse de l’API sont divisés par dix.</p> +<h3 id="mise-à -disposition-en-tant-que-composants-autonomes-dissociés-de-symfony-et-doctrine">Mise à disposition en tant que composants autonomes, dissociés de Symfony et Doctrine</h3> + +<p>API Platform est conçu comme un ensemble de composants PHP indépendants : son système de métaâ€données, les sérialiseurs JSON-LD, Hydra, Swagger et HAL, les ponts vers Doctrine et Symfony, etc. Tous ces composants peuvent être utilisés séparément pour créer votre propre API. Pour le moment, la bibliothèque Core doit être téléchargée, mais une sousâ€division du dépôt principal (<em>subtree split</em>) sera disponible pour la version 2.1. Elle permettra l’installation spécifique d’un composant. Les classes spécifiques peuvent déjà être utilisées séparément de la distribution standard et sans Symfony.</p> + +<p>Nous avons également déplacé le code suffisamment générique d’API Platform vers Symfony. Par exemple, le nouveau composant Symfony PropertyInfo a été extrait d’API Platform. Quelques corrections de bogues et des nouvelles fonctionnalités, telle que la prise en charge des profondeurs maximales de sérialisation ou encore des formats YAML et CSV au sein du Serializer de Symfony ont été réalisées durant le développement d’API Platform.</p> + +<p>L’<a href="https://en.wikipedia.org/wiki/Object-relational_mapping" title="Objectâ€relational mapping — Correspondance objetâ€base de données">ORM</a> Doctrine n’a jamais été obligatoire pour utiliser API Platform, mais l’ensemble des interfaces permettant d’implémenter une infrastructure de persistance différente a été repensé et est désormais documenté.</p> +<h3 id="qualité-du-code-et-tests-automatisés">Qualité du code et tests automatisés</h3> + +<p>Nous avons considérablement amélioré la qualité de code d’API Platform pour sa version deux. API Platform v1 était déjà testé via Behat. Dans la version deux, nous avons ajouté des tests unitaires supplémentaires, afin de prévenir les bogues et de démontrer que chaque classe respecte les principes <a href="https://fr.wikipedia.org/wiki/SOLID_%28informatique%29">SOLID</a>. La couverture du code est désormais de 96 %. Notre suite de tests est automatiquement lancée sous GNU/Linux (en utilisant Travis) et sous Windows (en utilisant AppVeyor).</p> + +<p>Nous avons également utilisé Scrutinizr et SensioLabs Insight afin de détecter les mauvaises pratiques et améliorer la qualité globale du code. API Platform est désormais noté 8,7/10 sur Scrutinizr et a reçu la médaille Platinum (meilleure évaluation, donc) sur Insight.</p> +<h3 id="réécriture-de-la-documentation-et-nouveau-site-web">Réécriture de la documentation et nouveau site Web</h3> + +<p>La documentation a été améliorée et toutes les nouvelles fonctionnalités sont désormais documentées. Le guide de démarrage a été complètement réécrit. Un nouveau site Web construit avec React et Redux a également été développé. Il est notamment doté d’un puissant moteur de recherche fourni par Algolia.</p> + +<p><img src="//img.linuxfr.org/img/68747470733a2f2f636f6d6d756e6974792e616c676f6c69612e636f6d2f646f637365617263682f696d672f73686f77636173652f6578616d706c652d617069706c6174666f726d2e676966/example-apiplatform.gif" alt="Doc" title="Source : https://community.algolia.com/docsearch/img/showcase/example-apiplatform.gif"></p> +<h3 id="une-communauté-en-plein-essor">Une communauté en plein essor</h3> + +<p>API Platform, c’est plus de cent contributeurs à travers le monde, une équipe principale composée de Hamza Amrouche , Antoine Bluchet, Samuel Roze, Teoh Han Hui, Théo Fidry, Vincent Chalamon et Kévin Dunglas), des ateliers et des conférences données à travers le monde (d’ailleurs, ne loupez pas l’atelier API Platform de demain lors de la <em>Symfony Con</em> de Berlin).</p> + +<p>API Platform est régulièrement classé dans les dépôts PHP les plus populaires de GitHub auprès de grands projets tels que Laravel, Symfony et Wordpress. Nous avons d’ailleurs dépassé le millier d’étoiles sur GitHub début novembre ! Des formations, des prestations de développements, un support commercial, ainsi que les ateliers sont dispensés dans toute l’Europe par <em>Les-Tilleuls.coop</em>, principal sponsor du cadriciel.</p> + +<p>Merci à toutes les personnes qui ont travaillé sur ces développements, à celles qui ont contribué à la documentation ou qui ont participé à populariser API Platform ! Ce projet ne serait rien sans vous !</p> +<h3 id="les-prochaines-étapes">Les prochaines étapes</h3> + +<p>La sortie de la version 2 d’API Platform n’est que la première étape ! Nous travaillons déjà sur de nouvelles fonctionnalités et certaines sont déjà sur le point d’être intégrées à la branche 2.1 :</p> + +<ul> +<li>le prise en charge native de MongoDB et de JSON API ;</li> +<li>une autoâ€génération de l’administration via l’utilisation de React et <em>Admin on Rest</em>.</li> +</ul><p>Restez à l’écoute des prochaines mises à jour ! Si vous ne l’avez pas encore fait, c’est l’occasion ou jamais de <a href="https://api-platform.com/docs/distribution/">tester API Platform</a> !</p> + +<p>Si vous aimez le projet, vous pouvez nous aider en nous donnant une étoile sur GitHub !</p></div><div><a href="https://linuxfr.org/news/api-platform-2-un-cadriciel-pour-creer-des-api-web-hypermedia-en-quelques-minutes.epub">Télécharger ce contenu au format EPUB</a></div> <p> + <strong>Commentaires :</strong> + <a href="//linuxfr.org/nodes/110745/comments.atom">voir le flux Atom</a> + <a href="https://linuxfr.org/news/api-platform-2-un-cadriciel-pour-creer-des-api-web-hypermedia-en-quelques-minutes#comments">ouvrir dans le navigateur</a> + </p> +</content> + <author> + <name>Kévin Dunglas</name> + </author> + <author> + <name>Davy Defaud</name> + </author> + <author> + <name>ZeroHeure</name> + </author> + <author> + <name>palm123</name> + </author> + <author> + <name>Nils Ratusznik</name> + </author> + <author> + <name>bubar🦥</name> + </author> + <author> + <name>Pierre Jarillon</name> + </author> + <category term="PHP"/> + <category term="rest"/> + <category term="api"/> + <category term="api-platform"/> + <category term="framework"/> + <category term="php"/> + <category term="php7"/> + <category term="symfony"/> + <wfw:commentRss>https://linuxfr.org/nodes/110745/comments.atom</wfw:commentRss> + </entry> +</feed> diff --git a/tests/library/Class/RssItemTest.php b/tests/library/Class/RssItemTest.php index 99820b86df9..a01e61b1fc7 100644 --- a/tests/library/Class/RssItemTest.php +++ b/tests/library/Class/RssItemTest.php @@ -19,8 +19,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ class RssItemDescriptionTest extends PHPUnit_Framework_TestCase { - /** @var Class_RssItem */ - protected $_item; + protected Class_RssItem $_item; @@ -48,3 +47,30 @@ class RssItemDescriptionTest extends PHPUnit_Framework_TestCase { $this->assertNotContains('<a class=', $this->_item->getDescription()); } } + + + + +class RssItemFromAtomFeedTest extends PHPUnit_Framework_TestCase { + protected Class_RssItem $_item; + + + + protected function setUp() { + parent::setUp(); + $feed = Zend_Feed::importString(file_get_contents(ROOT_PATH . 'tests/fixtures/php.atom')); + $this->_item = $item = new Class_RssItem($feed->current()); + } + + + /** @test */ + public function itemShouldReturnFirstDescription() { + $this->assertContains('wallabag est une application', $this->_item->getDescription()); + } + + + /** @test */ + public function descriptionShouldBeStripTagged() { + $this->assertNotContains('<a class=', $this->_item->getDescription()); + } +} -- GitLab