{"id":932,"date":"2014-05-26T09:39:05","date_gmt":"2014-05-26T07:39:05","guid":{"rendered":"http:\/\/www.lafabriquedecode.com\/blog\/?p=932"},"modified":"2019-01-25T13:32:50","modified_gmt":"2019-01-25T11:32:50","slug":"php-design-pattern-proxy","status":"publish","type":"post","link":"http:\/\/www.lafabriquedecode.com\/blog\/2014\/05\/php-design-pattern-proxy\/","title":{"rendered":"PHP : le design pattern Proxy"},"content":{"rendered":"<p>Proxy, proxy&#8230;proxy de cache, proxy Web&#8230;vous avez sans doute d\u00e9j\u00e0 lu ce terme quelque part, n&rsquo;est-ce pas ? Si oui, alors vous avez d\u00e9j\u00e0 sa principale raison d&rsquo;\u00eatre en t\u00eate : un <strong>proxy<\/strong> s&rsquo;intercale entre vous et&#8230;quelque chose !<\/p>\n<p>En programmation, ce quelque chose est un objet \u00ab\u00a0distant\u00a0\u00bb&#8230;distant parce qu&rsquo;il peut se trouver ailleurs sur le r\u00e9seau mais pas seulement ! Il peut tr\u00e8s bien se trouver sur la m\u00eame machine mais dans un autre espace d&rsquo;adressage. En pratique, le proxy <strong>impl\u00e9mente la m\u00eame interface que l&rsquo;objet auquel il sert d&rsquo;\u00e9cran<\/strong>, car il va se substituer \u00e0 lui !<\/p>\n<p>Ce design pattern fait \u00e9tat de relations entre des objets, voil\u00e0 pourquoi on dit qu&rsquo;il est <em>structurel<\/em> ! Proxy (ou Procuration ou encore <em>Surrogate<\/em> en anglais) a des similitudes avec un autre pattern structurel : <a href=\"http:\/\/www.lafabriquedecode.com\/blog\/2013\/04\/php-un-exemple-simple-de-design-pattern-decorator\/\" title=\"PHP : un exemple simple de design pattern Decorator\">D\u00e9corateur<\/a>. Cependant, il convient de bien garder \u00e0 l&rsquo;esprit que si D\u00e9corateur a pour but d&rsquo;ajouter des fonctionnalit\u00e9s \u00e0 l&rsquo;objet d\u00e9cor\u00e9, Proxy est souvent l\u00e0 pour effectuer un contr\u00f4le d&rsquo;acc\u00e8s \u00e0 un objet.<\/p>\n<p>Si vous avez d\u00e9j\u00e0 travaill\u00e9 avec le framework Symfony et l&rsquo;ORM Doctrine, cette notion de proxy ne vous est pas inconnue car vous manipulez des <em>proxies<\/em> en bien des occasions !<br \/>\n<div id=\"attachment_937\" style=\"width: 649px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2014\/03\/3_bodyguards2.jpg\"><img aria-describedby=\"caption-attachment-937\" loading=\"lazy\" src=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2014\/03\/3_bodyguards2.jpg\" alt=\"Gardes du corps peu enclins \u00e0 la discussion\" width=\"639\" height=\"376\" class=\"size-full wp-image-937\" srcset=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2014\/03\/3_bodyguards2.jpg 639w, http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2014\/03\/3_bodyguards2-300x176.jpg 300w, http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2014\/03\/3_bodyguards2-624x367.jpg 624w\" sizes=\"(max-width: 639px) 100vw, 639px\" \/><\/a><p id=\"caption-attachment-937\" class=\"wp-caption-text\">Les proxies du pr\u00e9sident de la R\u00e9publique ! Pour \u00e9mettre une requ\u00eate \u00e0 ce dernier, c&rsquo;est par eux qu&rsquo;il faudra passer !<\/p><\/div><\/p>\n<h1>L&rsquo;interpr\u00e8te, un mandataire id\u00e9al !<\/h1>\n<p>Voil\u00e0 un nouveau terme fran\u00e7ais pour notre Proxy : <strong>mandataire<\/strong>. Quel meilleur exemple que celui de l&rsquo;interpr\u00e8te, par lequel il est imp\u00e9ratif de passer lors des sommets internationaux, si l&rsquo;on veut \u00eatre compris des grands de ce monde (et \u00e9ventuellement lui faire porter la responsabilit\u00e9 d&rsquo;un incident diplomatique) ! Voil\u00e0 un exemple tr\u00e8s simple pour illustrer \u00e7a : des interfaces que le sujet r\u00e9el (le pr\u00e9sident russe) et son proxy (l&rsquo;interpr\u00e8te russe-fran\u00e7ais) impl\u00e9mentent tous deux et un pr\u00e9sident h\u00f4te qui prend en composition un interpr\u00e8te avec lequel il va parler tandis que celui-ci va de son c\u00f4t\u00e9 discuter avec le sujet r\u00e9el. Dans cet exemple, j&rsquo;en profite pour utiliser la d\u00e9rivation d&rsquo;interfaces, le mot cl\u00e9 final, une classe abstraite&#8230;En r\u00e9alit\u00e9 j&rsquo;aurais largement pu simplifier le code, j&rsquo;aurais pu aussi injecter directement l&rsquo;interpr\u00e8te dans le constructeur du pr\u00e9sident h\u00f4te, qui m\u00e8ne les conversations, au lieu de mettre un <em>setter<\/em> dont je ne suis pas sp\u00e9cialement adepte, bref j&rsquo;aurais pu faire des tas de choses autrement mais je veux garder le code efficace et amusant autant que possible !<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\ninterface PersonneInterface\r\n{\r\n    public function parlerDuTemps(): string;\r\n}\r\n\r\ninterface PresidentInterface extends PersonneInterface\r\n{\r\n    public function parlerDuRechauffementClimatique(): string;\r\n    public function parlerDesGuerres(): string;\r\n}\r\n \r\nfinal class PresidentRusse implements PresidentInterface\r\n{\r\n    public function parlerDuTemps(): string\r\n    {\r\n        return '\u042f \u043e\u0447\u0435\u043d\u044c \u0440\u0430\u0434 \u0431\u044b\u0442\u044c \u0437\u0434\u0435\u0441\u044c, \u043f\u043e\u0433\u043e\u0434\u0430 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u0430\u044f \u0432 \u041f\u0430\u0440\u0438\u0436\u0435';\r\n    }\r\n\r\n    public function parlerDuRechauffementClimatique(): string\r\n    {\r\n        return '\u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 !';\r\n    }\r\n\r\n    public function parlerDesGuerres(): string\r\n    {\r\n        return '\u043a\u0430\u043a\u0430\u044f \u0432\u043e\u0439\u043d\u0430?';\r\n    }\r\n}\r\n\r\ninterface InterpreteInterface\r\n{\r\n    public function boireUnVerreEau(): string;\r\n}\r\n\r\nabstract class Interprete implements InterpreteInterface\r\n{\r\n    protected $presidentHote;\r\n    \r\n    protected $presidentInvite;\r\n\r\n    public function __construct(PresidentInterface $presidentHote,\r\n                              PresidentInterface $presidentInvite)\r\n    {\r\n        $this-&gt;presidentHote = $presidentHote;\r\n        $this-&gt;presidentInvite = $presidentInvite;\r\n    }\r\n    \r\n    public function boireUnVerreEau(): string\r\n    {\r\n        return 'Glou Glou Glou'.PHP_EOL;\r\n    }\r\n}\r\n \r\nfinal class InterpreteRusse extends Interprete implements PresidentInterface\r\n{\r\n    public function parlerDuTemps(): string\r\n    {\r\n        $temps = 'Au sujet du temps, le pr\u00e9sident russe me dit : &quot;';\r\n        $temps .= $this-&gt;presidentInvite-&gt;parlerDuTemps().'&quot;'.PHP_EOL;\r\n        \r\n        return $temps;\r\n    }\r\n\r\n    public function parlerDuRechauffementClimatique(): string\r\n    {\r\n        $climat = 'Au sujet du climat, le pr\u00e9sident russe me dit : &quot;';\r\n        $climat .= $this-&gt;presidentInvite-&gt;parlerDuRechauffementClimatique().'&quot;';\r\n        \r\n        return $climat.PHP_EOL;\r\n    }\r\n\r\n    public function parlerDesGuerres(): string\r\n    {\r\n        if ($this-&gt;presidentHote instanceof PresidentFrancais) {\r\n            return 'Le pr\u00e9sident russe ne souhaite pas \u00e9voquer le sujet \r\n                    avec le pr\u00e9sident fran\u00e7ais ! Prenons plut\u00f4t Vodka !'.PHP_EOL;\r\n        }\r\n        \r\n        $guerre = 'Au sujet des guerres, le pr\u00e9sident russe me dit : &quot;';\r\n        $guerre .= $this-&gt;presidentInvite-&gt;parlerDesGuerres().'&quot;'.PHP_EOL;\r\n        \r\n        return $guerre;\r\n    }\r\n}\r\n \r\nfinal class PresidentFrancais implements PresidentInterface\r\n{\r\n    private $interprete;\r\n     \r\n    public function attacherInterprete(InterpreteInterface $interprete): void\r\n    {\r\n        $this-&gt;interprete = $interprete;\r\n    }\r\n    \r\n    public function parlerDuTemps(): string\r\n    {\r\n        return 'Pr\u00e9sident, il fait bon vivre \u00e0 Paris, n'est-ce pas ?'.PHP_EOL;\r\n    }\r\n\r\n    public function parlerDuRechauffementClimatique(): string\r\n    {\r\n        return 'Que pensez-vous du r\u00e9chauffement climatique ?'.PHP_EOL;\r\n    }\r\n\r\n    public function parlerDesGuerres(): string\r\n    {\r\n        return 'Que vous inspirent les conflits mondiaux ?'.PHP_EOL;\r\n    }\r\n    \r\n    public function discuterSurPerron(): void\r\n    {\r\n        if (!$this-&gt;interprete) {\r\n            throw new RuntimeException('O\u00f9 est l\\'interpr\u00e8te ?');\r\n        }\r\n         \r\n        echo $this-&gt;parlerDuTemps();\r\n        echo $this-&gt;interprete-&gt;parlerDuTemps();\r\n        \r\n        echo $this-&gt;parlerDuRechauffementClimatique();\r\n        echo $this-&gt;interprete-&gt;parlerDuRechauffementClimatique();\r\n        \r\n        echo $this-&gt;parlerDesGuerres();\r\n        echo $this-&gt;interprete-&gt;parlerDesGuerres();\r\n    }\r\n}\r\n \r\n$presidentFrancais = new PresidentFrancais();\r\n$presidentRusse = new PresidentRusse();\r\n$InterpreteRusse = new InterpreteRusse($presidentFrancais, $presidentRusse);\r\n\r\n$presidentFrancais-&gt;attacherInterprete($InterpreteRusse);\r\n \r\ntry {\r\n    $presidentFrancais-&gt;discuterSurPerron();\r\n} catch (RuntimeException $exception) {\r\n    echo &quot;All\u00f4, ici le chef du protocole !&quot;, PHP_EOL;\r\n    echo &quot;Le pr\u00e9sident vient de me dire '&quot; . \r\n              $exception-&gt;getMessage(), &quot;'&quot;, PHP_EOL;\r\n    echo &quot;Vite, allez chercher un interpr\u00e8te !&quot;, PHP_EOL;\r\n}\r\n\r\necho $InterpreteRusse-&gt;boireUnVerreEau();\r\n<\/pre>\n<p>Une fois de plus, voil\u00e0 un <em>design pattern<\/em> fait la part belle \u00e0 l&rsquo;abstraction !<\/p>\n<p>Vous notez ici que la tentation serait grande pour notre interpr\u00e8te de proposer des fonctionnalit\u00e9s que ne propose pas le pr\u00e9sident dont il assure la traduction. En faisant ainsi, nous nous \u00e9loignerions de Proxy &#8211; dont le r\u00f4le consiste majoritairement \u00e0 faire de la d\u00e9l\u00e9gation &#8211; pour adopter une approche D\u00e9corateur.<\/p>\n<p>Notre interpr\u00e8te russe joue \u00e9galement le r\u00f4le de proxy <em>de protection<\/em> en filtrant les acc\u00e8s au pr\u00e9sident russe sur des questions \u00e9pineuses: en l&rsquo;occurrence, le pr\u00e9sident russe n&rsquo;a pas tellement envie de parler des guerres avec son homologue fran\u00e7ais et l&rsquo;interpr\u00e8te a re\u00e7u lors de son <em>briefing<\/em> des instructions sans \u00e9quivoque&#8230;heureusement qu&rsquo;en bon russe, il a pr\u00e9vu un verre de vodka pour d\u00e9samorcer tout d\u00e9but de crise diplomatique ! Faire des v\u00e9rifications de droit d&rsquo;acc\u00e8s, voil\u00e0 aussi un autre aspect de ce <em>design pattern<\/em>.<\/p>\n<h1>Le chargement fain\u00e9ant<\/h1>\n<p>Personne n&#8217;emploie ce terme en r\u00e9alit\u00e9, mais il me fait rire ! Le <em>lazy loading<\/em> consiste \u00e0 diff\u00e9rer le chargement du vrai objet (celui qui nous <em>mandate<\/em>, qui nous donne <em>procuration<\/em>) jusqu&rsquo;au moment o\u00f9 l&rsquo;on s&rsquo;en servira effectivement ! Ceci est notamment utile lorsqu&rsquo;un objet est un plut\u00f4t gourmand en ressources.<\/p>\n<p>Prenons l&rsquo;exemple d&rsquo;une classe qui sert habituellement \u00e0 manipuler des images. Lorsqu&rsquo;on l&rsquo;instancie, elle range dans une variable d&rsquo;instance pr\u00e9vue \u00e0 cette effet la totalit\u00e9 du flux de l&rsquo;image qu&rsquo;on lui passe en param\u00e8tre.<\/p>\n<p>Notre proxy, qui poss\u00e8de le m\u00eame super-type que la classe image (une classe abstraite impl\u00e9mentant une interface) ne va pas effectuer ce chargement mais il va attendre le dernier moment pour instancier la classe qui le mandate et appeler dessus les m\u00e9thodes demand\u00e9es par le client :<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\ninterface ImageInterface\r\n{\r\n    public function donnerTaille(): int;\r\n    public function aContenu(): bool;\r\n    public function afficherContenu(): ?string;\r\n}\r\n\r\nabstract class AbstractImage implements ImageInterface\r\n{\r\n\tprotected $cheminFichier;\r\n\tprotected $contenuFichier;\r\n\tprotected $tailleFichier;\r\n\t\r\n\tpublic function __construct($cheminFichier)\r\n\t{\r\n\t\t$this-&gt;cheminFichier = $cheminFichier;\r\n\t}\r\n\t\r\n\tpublic function donnerTaille(): int\r\n\t{\r\n\t\treturn $this-&gt;tailleFichier;\r\n\t}\r\n\t\r\n\tpublic function aContenu(): bool\r\n\t{\r\n\t\treturn null !== $this-&gt;contenuFichier;\r\n\t}\r\n}\r\n\r\nclass StandardImage extends AbstractImage\r\n{\r\n\tpublic function __construct($cheminFichier)\r\n\t{\r\n\t\tparent::__construct($cheminFichier);\r\n\t\t$this-&gt;contenuFichier = file_get_contents(\r\n                                          $this-&gt;cheminFichier);\r\n\t\t$this-&gt;tailleFichier = filesize(\r\n                                          $this-&gt;cheminFichier);\r\n\t}\r\n\t\r\n\tpublic function afficherContenu(): ?string\r\n\t{\r\n\t\treturn $this-&gt;contenuFichier;\r\n\t}\r\n}\r\n\r\nclass ProxyImage extends AbstractImage {\r\n\t\r\n\tprivate $vraieImage;\r\n\t\r\n\tpublic function __construct($cheminFichier)\r\n\t{\r\n\t\tparent::__construct($cheminFichier);\r\n\t\t$this-&gt;tailleFichier = filesize($this-&gt;cheminFichier);\r\n\t}\r\n\t\r\n\tpublic function afficherContenu(): ?string\r\n\t{\r\n\t\tif (!$this-&gt;vraieImage) {\r\n\t\t\t$this-&gt;vraieImage = new StandardImage(\r\n                                              $this-&gt;cheminFichier);\r\n\t\t}\r\n\t\t\r\n\t\treturn $this-&gt;vraieImage-&gt;afficherContenu();\r\n\t}\r\n}\r\n\r\nfinal class GestionnaireImage\r\n{\r\n\tpublic function traiterImage (ImageInterface $image): void\r\n\t{\r\n\t\techo $image-&gt;donnerTaille() . ' octets';\r\n\t\techo 'Contenu pr\u00e9sent ?'.($image-&gt;aContenu());\r\n\t\techo $image-&gt;afficherContenu();\r\n\t}\r\n}\r\n\r\n$gestionnaireImage = new GestionnaireImage();\r\n\r\n$image = new StandardImage('elephant.jpg');\r\necho $gestionnaireImage-&gt;traiterImage($image);\r\n\r\n$proxy = new ProxyImage('elephant.jpg');\r\necho $gestionnaireImage-&gt;traiterImage($proxy);\r\n<\/pre>\n<p>Le client (<strong>GestionnaireImage<\/strong>) travaille d&rsquo;ordinaire avec des objets de la classe <strong>StandardImage<\/strong>, qui, d\u00e8s qu&rsquo;elle est instanci\u00e9e, stocke le flux complet du fichier cibl\u00e9 dans une variable d&rsquo;instance. Ceci peut s&rsquo;av\u00e9rer extr\u00eamement co\u00fbteux si l&rsquo;image est de grande taille ou si un grand nombre d&rsquo;images sont requises en m\u00eame temps par diff\u00e9rents utilisateurs de notre classe, voire les deux ! <\/p>\n<p>Nous intercalons donc un objet Proxy entre le client de notre code et le sujet cibl\u00e9 : <strong>ProxyImage<\/strong> poss\u00e8de le m\u00eame super-type que <strong>StandardImage<\/strong>, il est donc tout \u00e0 fait capable d&rsquo;agir en qualit\u00e9 de mandataire ! Son r\u00f4le sera de diff\u00e9rer la construction du sujet cibl\u00e9 jusqu&rsquo;au moment o\u00f9 son utilisation sera requise; il doit pour cela poss\u00e9der une r\u00e9f\u00e9rence \u00e0 ce sujet, voil\u00e0 pourquoi vous voyez la donn\u00e9e membre priv\u00e9e $vraieImage dans <strong>ProxyImage<\/strong> ! C&rsquo;est le mandataire qui instancie le sujet, au d\u00e9part il poss\u00e8de sur le fichier image une r\u00e9f\u00e9rence <em>indirecte<\/em> (le nom de fichier) puis finit par obtenir une r\u00e9f\u00e9rence <em>directe<\/em> (l&rsquo;objet StandardImage, avec le flux complet).<\/p>\n<p>Dans le cas de <strong>StandardImage<\/strong>, le contenu du fichier cible est int\u00e9gralement stock\u00e9 dans la propri\u00e9t\u00e9 priv\u00e9e d\u00e9di\u00e9e \u00e0 cet effet, mais pas dans le cas de <strong>ProxyImage<\/strong> qui n&rsquo;instanciera la classe mandat\u00e9e que lorsque la m\u00e9thode <em>afficherContenu<\/em> sera invoqu\u00e9e. La valeur retourn\u00e9e par <em>$image->aContenu()<\/em> vaudra TRUE dans le cas de <strong>StandardImage<\/strong> et FALSE dans le cas du Proxy; c&rsquo;est bien le signe que le Proxy fait l&rsquo;\u00e9conomie de la lecture du flux du fichier image sur lequel nous travaillons. Cependant, lorsque le client demande l&rsquo;affichage de l&rsquo;image, le Proxy ne peut faire autrement que d&rsquo;instancier <strong>StandardImage<\/strong> pour invoquer dessus la m\u00e9thode qui va retourner le flux utile \u00e0 cet affichage.<\/p>\n<p>Au final, le mandataire est plus efficace que le sujet r\u00e9el qu&rsquo;il masque puisque lors de l&rsquo;appel \u00e0 <strong>donnerTaille<\/strong> dans <strong>traiterImage<\/strong>, il n&rsquo;a pas r\u00e9cup\u00e9r\u00e9 l&rsquo;int\u00e9gralit\u00e9 du flux binaire du fichier cible. C&rsquo;est \u00e9videmment ce qu&rsquo;il fait lorsqu&rsquo;il doit afficher celui-ci, ne pouvant faire autrement.<\/p>\n<p>Pour utiliser cet exemple, il vous faudra bien entendu une image nomm\u00e9e <em>elephant.jpg<\/em> que je vous fournis un peu plus bas !<\/p>\n<p><strong>Quand on doit diff\u00e9rer les op\u00e9rations qui s&rsquo;av\u00e8rent co\u00fbteuses lors de la cr\u00e9ation d&rsquo;un objet au moment o\u00f9 elle seront effectivement requises alors le design pattern Proxy peut s&rsquo;av\u00e9rer d&rsquo;une aide pr\u00e9cieuse !<\/strong><\/p>\n<div id=\"attachment_978\" style=\"width: 2058px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2014\/05\/elephant.jpg\"><img aria-describedby=\"caption-attachment-978\" loading=\"lazy\" src=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2014\/05\/elephant.jpg\" alt=\"La belle image qui a servi \u00e0 mes tests !\" width=\"2048\" height=\"1366\" class=\"size-full wp-image-978\" srcset=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2014\/05\/elephant.jpg 2048w, http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2014\/05\/elephant-300x200.jpg 300w, http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2014\/05\/elephant-1024x683.jpg 1024w, http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2014\/05\/elephant-624x416.jpg 624w\" sizes=\"(max-width: 2048px) 100vw, 2048px\" \/><\/a><p id=\"caption-attachment-978\" class=\"wp-caption-text\">La belle image qui a servi \u00e0 mes tests !<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Proxy, proxy&#8230;proxy de cache, proxy Web&#8230;vous avez sans doute d\u00e9j\u00e0 lu ce terme quelque part, n&rsquo;est-ce pas ? Si oui, alors vous avez d\u00e9j\u00e0 sa principale raison d&rsquo;\u00eatre en t\u00eate : un proxy s&rsquo;intercale entre vous et&#8230;quelque chose ! En programmation, ce quelque chose est un objet \u00ab\u00a0distant\u00a0\u00bb&#8230;distant parce qu&rsquo;il peut se trouver ailleurs sur [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[24,40,14,3,29],"tags":[43,75],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v19.6.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>PHP : le design pattern Proxy - La Fabrique de code - Tech blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"http:\/\/www.lafabriquedecode.com\/blog\/2014\/05\/php-design-pattern-proxy\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PHP : le design pattern Proxy - La Fabrique de code - Tech blog\" \/>\n<meta property=\"og:description\" content=\"Proxy, proxy&#8230;proxy de cache, proxy Web&#8230;vous avez sans doute d\u00e9j\u00e0 lu ce terme quelque part, n&rsquo;est-ce pas ? Si oui, alors vous avez d\u00e9j\u00e0 sa principale raison d&rsquo;\u00eatre en t\u00eate : un proxy s&rsquo;intercale entre vous et&#8230;quelque chose ! En programmation, ce quelque chose est un objet \u00ab\u00a0distant\u00a0\u00bb&#8230;distant parce qu&rsquo;il peut se trouver ailleurs sur [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"http:\/\/www.lafabriquedecode.com\/blog\/2014\/05\/php-design-pattern-proxy\/\" \/>\n<meta property=\"og:site_name\" content=\"La Fabrique de code - Tech blog\" \/>\n<meta property=\"article:published_time\" content=\"2014-05-26T07:39:05+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-01-25T11:32:50+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2014\/03\/3_bodyguards2.jpg\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary\" \/>\n<meta name=\"twitter:creator\" content=\"@LaFabrique2Code\" \/>\n<meta name=\"twitter:site\" content=\"@LaFabrique2Code\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/2014\/05\/php-design-pattern-proxy\/\",\"url\":\"http:\/\/www.lafabriquedecode.com\/blog\/2014\/05\/php-design-pattern-proxy\/\",\"name\":\"PHP : le design pattern Proxy - La Fabrique de code - Tech blog\",\"isPartOf\":{\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#website\"},\"datePublished\":\"2014-05-26T07:39:05+00:00\",\"dateModified\":\"2019-01-25T11:32:50+00:00\",\"author\":{\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/83863c048b82fd9ccf6407bddd241162\"},\"breadcrumb\":{\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/2014\/05\/php-design-pattern-proxy\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\/\/www.lafabriquedecode.com\/blog\/2014\/05\/php-design-pattern-proxy\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/2014\/05\/php-design-pattern-proxy\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"http:\/\/www.lafabriquedecode.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PHP : le design pattern Proxy\"}]},{\"@type\":\"WebSite\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#website\",\"url\":\"http:\/\/www.lafabriquedecode.com\/blog\/\",\"name\":\"La Fabrique de code - Tech blog\",\"description\":\"PHP objet, MySQL, Design Patterns, OOP...et plus !\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"http:\/\/www.lafabriquedecode.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Person\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/83863c048b82fd9ccf6407bddd241162\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"http:\/\/0.gravatar.com\/avatar\/fc2e1de7c8a1871b50ff9c6a6f8682a2?s=96&d=retro&r=g\",\"contentUrl\":\"http:\/\/0.gravatar.com\/avatar\/fc2e1de7c8a1871b50ff9c6a6f8682a2?s=96&d=retro&r=g\",\"caption\":\"admin\"},\"url\":\"http:\/\/www.lafabriquedecode.com\/blog\/author\/admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"PHP : le design pattern Proxy - La Fabrique de code - Tech blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"http:\/\/www.lafabriquedecode.com\/blog\/2014\/05\/php-design-pattern-proxy\/","og_locale":"fr_FR","og_type":"article","og_title":"PHP : le design pattern Proxy - La Fabrique de code - Tech blog","og_description":"Proxy, proxy&#8230;proxy de cache, proxy Web&#8230;vous avez sans doute d\u00e9j\u00e0 lu ce terme quelque part, n&rsquo;est-ce pas ? Si oui, alors vous avez d\u00e9j\u00e0 sa principale raison d&rsquo;\u00eatre en t\u00eate : un proxy s&rsquo;intercale entre vous et&#8230;quelque chose ! En programmation, ce quelque chose est un objet \u00ab\u00a0distant\u00a0\u00bb&#8230;distant parce qu&rsquo;il peut se trouver ailleurs sur [&hellip;]","og_url":"http:\/\/www.lafabriquedecode.com\/blog\/2014\/05\/php-design-pattern-proxy\/","og_site_name":"La Fabrique de code - Tech blog","article_published_time":"2014-05-26T07:39:05+00:00","article_modified_time":"2019-01-25T11:32:50+00:00","og_image":[{"url":"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2014\/03\/3_bodyguards2.jpg"}],"author":"admin","twitter_card":"summary","twitter_creator":"@LaFabrique2Code","twitter_site":"@LaFabrique2Code","twitter_misc":{"\u00c9crit par":"admin","Dur\u00e9e de lecture estim\u00e9e":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"http:\/\/www.lafabriquedecode.com\/blog\/2014\/05\/php-design-pattern-proxy\/","url":"http:\/\/www.lafabriquedecode.com\/blog\/2014\/05\/php-design-pattern-proxy\/","name":"PHP : le design pattern Proxy - La Fabrique de code - Tech blog","isPartOf":{"@id":"http:\/\/www.lafabriquedecode.com\/blog\/#website"},"datePublished":"2014-05-26T07:39:05+00:00","dateModified":"2019-01-25T11:32:50+00:00","author":{"@id":"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/83863c048b82fd9ccf6407bddd241162"},"breadcrumb":{"@id":"http:\/\/www.lafabriquedecode.com\/blog\/2014\/05\/php-design-pattern-proxy\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["http:\/\/www.lafabriquedecode.com\/blog\/2014\/05\/php-design-pattern-proxy\/"]}]},{"@type":"BreadcrumbList","@id":"http:\/\/www.lafabriquedecode.com\/blog\/2014\/05\/php-design-pattern-proxy\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"http:\/\/www.lafabriquedecode.com\/blog\/"},{"@type":"ListItem","position":2,"name":"PHP : le design pattern Proxy"}]},{"@type":"WebSite","@id":"http:\/\/www.lafabriquedecode.com\/blog\/#website","url":"http:\/\/www.lafabriquedecode.com\/blog\/","name":"La Fabrique de code - Tech blog","description":"PHP objet, MySQL, Design Patterns, OOP...et plus !","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"http:\/\/www.lafabriquedecode.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"fr-FR"},{"@type":"Person","@id":"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/83863c048b82fd9ccf6407bddd241162","name":"admin","image":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/image\/","url":"http:\/\/0.gravatar.com\/avatar\/fc2e1de7c8a1871b50ff9c6a6f8682a2?s=96&d=retro&r=g","contentUrl":"http:\/\/0.gravatar.com\/avatar\/fc2e1de7c8a1871b50ff9c6a6f8682a2?s=96&d=retro&r=g","caption":"admin"},"url":"http:\/\/www.lafabriquedecode.com\/blog\/author\/admin\/"}]}},"_links":{"self":[{"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/posts\/932"}],"collection":[{"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/comments?post=932"}],"version-history":[{"count":30,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/posts\/932\/revisions"}],"predecessor-version":[{"id":1137,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/posts\/932\/revisions\/1137"}],"wp:attachment":[{"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/media?parent=932"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/categories?post=932"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/tags?post=932"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}