{"id":166,"date":"2024-09-21T15:53:00","date_gmt":"2024-09-21T13:53:00","guid":{"rendered":"https:\/\/jagullo.fr\/blog\/?p=166"},"modified":"2024-09-21T15:53:48","modified_gmt":"2024-09-21T13:53:48","slug":"le-design-pattern-singleton-en-php","status":"publish","type":"post","link":"https:\/\/jagullo.fr\/blog\/le-design-pattern-singleton-en-php\/","title":{"rendered":"Le design pattern Singleton en php"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"definition-du-singleton\">D\u00e9finition du Singleton<\/h2>\n\n\n\n<p>En math\u00e9matique le Singleton repr\u00e9sente un ensemble constitu\u00e9 d&rsquo;un \u00e9l\u00e9ment unique. En POO (programmation orient\u00e9e objet) <strong>le patron de conception Singleton <\/strong>reprend ce concept en permettant \u00e0 une classe de renvoyer la m\u00eame instance lorsqu&rsquo;on l&rsquo;appelle \u00e0 diff\u00e9rent endroit du programme. Savoir bien optimiser son code est une t\u00e2che importante du m\u00e9tier de d\u00e9veloppeur web ou du de la programmation en g\u00e9n\u00e9ral. Plus la r\u00e9ponse du serveur est rapide, plus le site se chargera rapidement dans le navigateur du client ce qui am\u00e9liore aussi le r\u00e9f\u00e9rencement. En optimisant au mieux la RAM sur le serveur, ce dernier peut r\u00e9pondre \u00e0 plus de requ\u00eates en m\u00eame temps.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"960\" height=\"640\" src=\"https:\/\/jagullo.fr\/blog\/wp-content\/uploads\/2024\/08\/illustration_singleton-php.jpg\" alt=\"\" class=\"wp-image-3932\" srcset=\"https:\/\/jagullo.fr\/blog\/wp-content\/uploads\/2024\/08\/illustration_singleton-php.jpg 960w, https:\/\/jagullo.fr\/blog\/wp-content\/uploads\/2024\/08\/illustration_singleton-php-300x200.jpg 300w, https:\/\/jagullo.fr\/blog\/wp-content\/uploads\/2024\/08\/illustration_singleton-php-768x512.jpg 768w\" sizes=\"(max-width: 960px) 100vw, 960px\" \/><figcaption class=\"wp-element-caption\">Le Singleton repr\u00e9sente une classe statique qui renvoie sa propre instance<\/figcaption><\/figure>\n\n\n\n<p>Prenons l&rsquo;exemple d&rsquo;une classe <code><strong><code>Translator<\/code><\/strong><\/code> permettant de g\u00e9rer les diff\u00e9rentes langues d&rsquo;une application. Elle charge le fichier de traduction concernant la locale et renvoie les donn\u00e9e s&rsquo;y trouvant. Cette classe peut \u00eatre appel\u00e9e \u00e0 diff\u00e9rents niveaux de l&rsquo;application web, dans une vue, un contr\u00f4leur ou un module. Si \u00e0 chaque fois on instancie la classe quand on en a besoin, alors on augmente les ressources m\u00e9moires allou\u00e9es au script en cours d&rsquo;ex\u00e9cution. Ce design pattern am\u00e9liore donc la clart\u00e9 du code tout en optimisant la RAM du serveur.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"un-exemple-concret\">Exemple concret de ce patron de conception<\/h2>\n\n\n\n<p>Pour \u00e9viter de devoir instancier la classe \u00e0 chaque utilisation, on va stocker la classe dans <strong>une propri\u00e9t\u00e9 statique <\/strong>afin d&rsquo;y acc\u00e9der \u00e0 la prochaine utilisation. Il suffit d&rsquo;appeler une fonction statique nomm\u00e9e g\u00e9n\u00e9ralement <strong>getInstance<\/strong> qui renvoie cet attribut s&rsquo;il n&rsquo;est pas nul. Au premier appel de la fonction getInstance, le script d\u00e9tecte si la classe a d\u00e9j\u00e0 \u00e9t\u00e9 cr\u00e9\u00e9e et retourne l&rsquo;objet statique. Voici un exemple d&rsquo;un Singleton classique en PHP avec la classe Translator :<\/p>\n\n\n\n<pre class=\"wp-block-code language-php\"><code>class Translator {\n    private static $instance;\n    public static function getInstance():static {\n        if (is_null(static::$instance)) {\n            static::$instance = new Translator();\n        }\n        return static::$instance;\n    }\n}\n$translator = Translator::getInstance();<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"un-peu-d-optimisation\">Un peu d&rsquo;optimisation<\/h2>\n\n\n\n<p>Ce script fait plusieurs lignes \u00e0 ajouter au d\u00e9but de toutes les classes que l&rsquo;on souhaite exploiter sous forme de Singleton. Nous pouvons <strong>factoriser le code<\/strong> en utilisant le principe des <a href=\"https:\/\/www.php.net\/manual\/fr\/language.oop5.traits.php\" target=\"_blank\" rel=\"noreferrer noopener\">traits en PHP<\/a>. Les traits sont une forme d&rsquo;extension de classe pour inclure des propri\u00e9t\u00e9s et des m\u00e9thodes communes \u00e0 l&rsquo;int\u00e9rieur d&rsquo;une classe. Pour \u00e9tendre un trait, il suffit de l&rsquo;appeler en utilisant le mot cl\u00e9 <strong>use<\/strong>. En d\u00e9veloppement web, ce m\u00e9canisme est tr\u00e8s pratique pour appeler facilement quelques fonctions redondantes qui sont communes \u00e0 plusieurs classes.<\/p>\n\n\n\n<pre class=\"wp-block-code language-php\"><code>trait Singleton {\n    private static $instance;\n    public static function getInstance():static {\n        if (is_null(static::$_instance)) {\n            $class = static::class;\n            static::$_instance = new $class;\n        }\n        return static::$instance;\n    }\n}\nclass Translator {\n    use Singleton;\n}\n$translator = Translator::getInstance();<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"pour-le-travail-en-equipe\">Comparaison avec Python<\/h2>\n\n\n\n<p>Ci-dessous <strong>un script Python<\/strong> pour comparer le design pattern Singleton entre PHP et ce dernier. On peut remarquer que ce dernier permet d&rsquo;\u00e9viter l&rsquo;utilisation d&rsquo;une fonction getInstance pour r\u00e9cup\u00e9rer la classe. On peut utiliser directement le nom de la classe qui va appeler l&rsquo;instance en cours.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>class Translator:\n    _instance = None\n\n    def __new__(cls):\n        if cls._instance is None:\n            cls._instance = super().__new__(cls)\n        return cls._instance\n\ntranslator = Translator()<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"limite-du-singleton\">Cas d&rsquo;utilisation du Singleton<\/h2>\n\n\n\n<p class=\"no-margin-bottom\">Pour finir, on peut citer <strong>quelques cas d&rsquo;utilisation<\/strong> de ce patron de conception dans une application web :<\/p>\n\n\n\n<ul class=\"wp-block-list no-margin-bottom\">\n<li>Gestionnaire de configuration<\/li>\n\n\n\n<li>Gestionnaire de journalisation (pour g\u00e9rer les logs)<\/li>\n\n\n\n<li>Gestionnaire de connexion \u00e0 la base de donn\u00e9es ou autres<\/li>\n\n\n\n<li>Gestionnaire de cache<\/li>\n\n\n\n<li>Gestionnaire de ressources<\/li>\n\n\n\n<li>Gestionnaire de plugins<\/li>\n\n\n\n<li>Gestion des pr\u00e9f\u00e9rences utilisateur<\/li>\n<\/ul>\n\n\n\n<p>Ce design pattern tr\u00e9s pratique est l&rsquo;un des plus populaires et des plus utilis\u00e9s. De nombreux d\u00e9veloppeurs l&rsquo;utilisent au quotidien. On le retrouve dans des frameworks connus comme Symfony ou m\u00eame dans des plugins WordPress.<\/p>\n\n\n\n<link rel=\"stylesheet\" href=\"\/blog\/wp-content\/themes\/Extra-child\/assets\/css\/prism.css\">\n<script src=\"\/blog\/wp-content\/themes\/Extra-child\/assets\/js\/prism.js\"><\/script>\n<div class=\"list-tags\"><a href=\"https:\/\/jagullo.fr\/blog\/tag\/design-pattern\/\" class=\"link-tag\" title=\"Design Pattern\">Design Pattern<\/a><a href=\"https:\/\/jagullo.fr\/blog\/tag\/php\/\" class=\"link-tag\" title=\"PHP\">PHP<\/a><\/div>","protected":false},"excerpt":{"rendered":"<p>D\u00e9finition du Singleton En math\u00e9matique le Singleton repr\u00e9sente un ensemble constitu\u00e9 d&rsquo;un \u00e9l\u00e9ment unique. En POO (programmation orient\u00e9e objet) le patron de conception Singleton reprend ce concept en permettant \u00e0 une classe de renvoyer la m\u00eame instance lorsqu&rsquo;on l&rsquo;appelle \u00e0 diff\u00e9rent endroit du programme. Savoir bien optimiser son code est une t\u00e2che importante du m\u00e9tier [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3932,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[8],"tags":[26,27],"class_list":["post-166","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developpement","tag-design-pattern","tag-php","et-has-post-format-content","et_post_format-et-post-format-standard"],"_links":{"self":[{"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/posts\/166","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/comments?post=166"}],"version-history":[{"count":3,"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/posts\/166\/revisions"}],"predecessor-version":[{"id":3944,"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/posts\/166\/revisions\/3944"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/media\/3932"}],"wp:attachment":[{"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/media?parent=166"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/categories?post=166"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jagullo.fr\/blog\/wp-json\/wp\/v2\/tags?post=166"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}