{"id":1071,"date":"2016-06-23T18:39:16","date_gmt":"2016-06-23T16:39:16","guid":{"rendered":"http:\/\/www.lafabriquedecode.com\/blog\/?p=1071"},"modified":"2016-06-23T18:39:16","modified_gmt":"2016-06-23T16:39:16","slug":"zend-framework-2-eviter-le-message","status":"publish","type":"post","link":"http:\/\/www.lafabriquedecode.com\/blog\/2016\/06\/zend-framework-2-eviter-le-message\/","title":{"rendered":"Zend Framework 2 : supprimer l&rsquo;appel \u00e0 getServiceLocator dans les contr\u00f4leurs"},"content":{"rendered":"<p>Vous avez peut-\u00eatre r\u00e9cemment jou\u00e9 avec la <a href=\"http:\/\/framework.zend.com\/manual\/current\/en\/user-guide\/skeleton-application.html\" target=\"_blank\">Skeleton Application<\/a> de Zend Framework (ou pire, remarqu\u00e9 \u00e7a lors d&rsquo;une mise \u00e0 jour) et en lan\u00e7ant votre application, vous avez vu s&rsquo;afficher le message suivant, du \u00e0 l&rsquo;appel de la m\u00e9thode <em>getServiceLocator<\/em> dans votre contr\u00f4leur (<em>AlbumController<\/em>, pour ceux qui ont tent\u00e9 de suivre le tutoriel) :<\/p>\n<blockquote><p>Deprecated: You are retrieving the service locator from within the class Album\\Controller\\AlbumController. Please be aware that ServiceLocatorAwareInterface is deprecated and will be removed in version 3.0, along with the ServiceLocatorAwareInitializer. You will need to update your class to accept all dependencies at creation, either via constructor arguments or setters, and use a factory to perform the injections.<\/p><\/blockquote>\n<p>Pour faire simple, on vous avertit que dans la version future de ZF, cette fa\u00e7on de faire sera consid\u00e9r\u00e9e comme obsol\u00e8te (j&rsquo;aime entendre les gens dire \u00ab\u00a0d\u00e9pr\u00e9cat\u00e8de\u00a0\u00bb) et qu&rsquo;il vaudrait mieux injecter la d\u00e9pendance \u00e0 la cr\u00e9ation de votre objet, en l&rsquo;occurrence ici celui qui r\u00e9sulte de l&rsquo;instanciation de la classe AlbumController (voir <a href=\"http:\/\/framework.zend.com\/manual\/current\/en\/user-guide\/database-and-models.html\" target=\"_blank\">cette page<\/a>).<br \/>\n<div id=\"attachment_1074\" style=\"width: 730px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2016\/06\/inscr5.png\"><img aria-describedby=\"caption-attachment-1074\" loading=\"lazy\" src=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2016\/06\/inscr5.png\" alt=\"Ah...heu...bon...OK, soit !\" width=\"720\" height=\"478\" class=\"size-full wp-image-1074\" srcset=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2016\/06\/inscr5.png 720w, http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2016\/06\/inscr5-300x199.png 300w, http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2016\/06\/inscr5-624x414.png 624w\" sizes=\"(max-width: 720px) 100vw, 720px\" \/><\/a><p id=\"caption-attachment-1074\" class=\"wp-caption-text\">Ah&#8230;heu&#8230;bon&#8230;OK, soit !<\/p><\/div><br \/>\nPour mettre en place quelque chose d&rsquo;un peu \u00e9l\u00e9gant, je vous invite \u00e0 faire appel \u00e0 une factory dans votre fichier <strong>module\/Album\/config\/module.config.php<\/strong> :<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n     'factories' =&gt; array(\r\n                      'Album\\Controller\\Album' =&gt; 'Album\\Factory\\AlbumControllerFactory'\r\n                    ),\r\n     ...\r\n<\/pre>\n<p>Voici le code de votre <strong>factory<\/strong>, plac\u00e9e si ce n&rsquo;est pas d\u00e9j\u00e0 fait, dans un r\u00e9pertoire \u00e9ponyme:<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nnamespace Album\\Factory;\r\n\r\nuse Album\\Controller\\AlbumController;\r\nuse Zend\\ServiceManager\\FactoryInterface;\r\nuse Zend\\ServiceManager\\ServiceLocatorInterface;\r\n\r\nuse Album\\Service\\ControllerService;\r\n\r\nclass AlbumControllerFactory implements FactoryInterface\r\n{\r\n    \/**\r\n    * Create service\r\n    *\r\n    * @param ServiceLocatorInterface $sl\r\n    *\r\n    * @return Album\\Controller\\AlbumController\r\n    *\/\r\n    public function createService(ServiceLocatorInterface $sl)\r\n    {\r\n        $cs = new ControllerService($sl-&gt;getServiceLocator()-&gt;get('doctrine.entitymanager.orm_default'));\r\n        return new AlbumController($cs);\r\n    }\r\n}\r\n<\/pre>\n<p>Dans ma factory, qui est la seule \u00e0 savoir comment se fabrique un contr\u00f4leur de type Album, je r\u00e9cup\u00e8re le service que j&rsquo;injecte dans le constructeur d&rsquo;AlbumController (relisez le message d&rsquo;erreur ci-dessus, on vous dit bien qu&rsquo;<em>il vaudrait mieux injecter la d\u00e9pendance \u00e0 la cr\u00e9ation de votre objet<\/em>, ce que vous faites). Ici j&rsquo;utilise comme service l&rsquo;Entity Manager de Doctrine, mais \u00e7a pourrait \u00eatre n&rsquo;importe quel autre service, \u00e9videmment !<\/p>\n<p>Regardons maintenant le constructeur que j&rsquo;ai rajout\u00e9 dans mon contr\u00f4leur:<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n    protected $service;\r\n\r\n    public function __construct(\\Album\\Service\\ControllerServiceInterface $service) {\r\n        $this-&gt;service = $service-&gt;getService();\r\n    }\r\n<\/pre>\n<p>J&rsquo;injecte dans mon constructeur les d\u00e9pendances de celui-ci, sous la forme d&rsquo;une interface (le po-ly-mor-phisme, que diable !). Cette interface c&rsquo;est moi qui l&rsquo;ai \u00e9crite, dans mon r\u00e9pertoire Service, elle est simplissime :<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n namespace Album\\Service;\r\n\r\n interface ControllerServiceInterface\r\n {\r\n    public function getService();\r\n }\r\n<\/pre>\n<p>Elle dit que tout objet qui l&rsquo;impl\u00e9mente se doit d&rsquo;avoir une m\u00e9thode qui permette d&rsquo;acc\u00e9der au service qu&rsquo;il contient.<\/p>\n<p>Dans le m\u00eame r\u00e9pertoire, j&rsquo;ai \u00e9crit un service d\u00e9di\u00e9 \u00e0 mon contr\u00f4leur :<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n namespace Album\\Service;\r\n\r\n class ControllerService implements ControllerServiceInterface\r\n {\r\n    protected $service;\r\n\r\n    public function __construct($service) {\r\n        $this-&gt;service = $service;\r\n    }\r\n\r\n    public function getService() {\r\n        return $this-&gt;service;\r\n    }\r\n }\r\n<\/pre>\n<p>On me reprochait d&rsquo;avoir fait \u00e7a dans mon contr\u00f4leur:<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">$this-&gt;em = $this-&gt;getServiceLocator()-&gt;get('doctrine.entitymanager.orm_default');<\/pre>\n<p>D\u00e9sormais c&rsquo;est ma <strong>factory<\/strong> qui se charge de faire \u00e7a, on a donc d\u00e9port\u00e9 les responsabilit\u00e9s dans la fabrique, qui est la seule \u00e0 savoir comment se constitue l&rsquo;objet qu&rsquo;elle fabrique. J&rsquo;ai choisi d&rsquo;injecter les d\u00e9pendances (le service) \u00e0 la cr\u00e9ation de l&rsquo;objet et pas via un <em>setter<\/em>, c&rsquo;est un choix strictement personnel. Rien ne vous emp\u00eache de proc\u00e9der autrement.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Vous avez peut-\u00eatre r\u00e9cemment jou\u00e9 avec la Skeleton Application de Zend Framework (ou pire, remarqu\u00e9 \u00e7a lors d&rsquo;une mise \u00e0 jour) et en lan\u00e7ant votre application, vous avez vu s&rsquo;afficher le message suivant, du \u00e0 l&rsquo;appel de la m\u00e9thode getServiceLocator dans votre contr\u00f4leur (AlbumController, pour ceux qui ont tent\u00e9 de suivre le tutoriel) : Deprecated: [&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":[40,38,91],"tags":[34,93,94,92],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v19.6.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Zend Framework 2 : supprimer l&#039;appel \u00e0 getServiceLocator dans les contr\u00f4leurs - La Fabrique de code - Tech blog<\/title>\n<meta name=\"description\" content=\"Une solution \u00e9l\u00e9gante pour d\u00e9porter l&#039;appel \u00e0 getServiceLocator d&#039;un contr\u00f4leur vers une factory qui injectera le service, \u00e9vitant le message &quot;Deprecated&quot; !\" \/>\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\/2016\/06\/zend-framework-2-eviter-le-message\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Zend Framework 2 : supprimer l&#039;appel \u00e0 getServiceLocator dans les contr\u00f4leurs - La Fabrique de code - Tech blog\" \/>\n<meta property=\"og:description\" content=\"Une solution \u00e9l\u00e9gante pour d\u00e9porter l&#039;appel \u00e0 getServiceLocator d&#039;un contr\u00f4leur vers une factory qui injectera le service, \u00e9vitant le message &quot;Deprecated&quot; !\" \/>\n<meta property=\"og:url\" content=\"http:\/\/www.lafabriquedecode.com\/blog\/2016\/06\/zend-framework-2-eviter-le-message\/\" \/>\n<meta property=\"og:site_name\" content=\"La Fabrique de code - Tech blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-06-23T16:39:16+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2016\/06\/inscr5.png\" \/>\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=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/2016\/06\/zend-framework-2-eviter-le-message\/\",\"url\":\"http:\/\/www.lafabriquedecode.com\/blog\/2016\/06\/zend-framework-2-eviter-le-message\/\",\"name\":\"Zend Framework 2 : supprimer l'appel \u00e0 getServiceLocator dans les contr\u00f4leurs - La Fabrique de code - Tech blog\",\"isPartOf\":{\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#website\"},\"datePublished\":\"2016-06-23T16:39:16+00:00\",\"dateModified\":\"2016-06-23T16:39:16+00:00\",\"author\":{\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/83863c048b82fd9ccf6407bddd241162\"},\"description\":\"Une solution \u00e9l\u00e9gante pour d\u00e9porter l'appel \u00e0 getServiceLocator d'un contr\u00f4leur vers une factory qui injectera le service, \u00e9vitant le message \\\"Deprecated\\\" !\",\"breadcrumb\":{\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/2016\/06\/zend-framework-2-eviter-le-message\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"http:\/\/www.lafabriquedecode.com\/blog\/2016\/06\/zend-framework-2-eviter-le-message\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"http:\/\/www.lafabriquedecode.com\/blog\/2016\/06\/zend-framework-2-eviter-le-message\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"http:\/\/www.lafabriquedecode.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Zend Framework 2 : supprimer l&rsquo;appel \u00e0 getServiceLocator dans les contr\u00f4leurs\"}]},{\"@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":"Zend Framework 2 : supprimer l'appel \u00e0 getServiceLocator dans les contr\u00f4leurs - La Fabrique de code - Tech blog","description":"Une solution \u00e9l\u00e9gante pour d\u00e9porter l'appel \u00e0 getServiceLocator d'un contr\u00f4leur vers une factory qui injectera le service, \u00e9vitant le message \"Deprecated\" !","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\/2016\/06\/zend-framework-2-eviter-le-message\/","og_locale":"fr_FR","og_type":"article","og_title":"Zend Framework 2 : supprimer l'appel \u00e0 getServiceLocator dans les contr\u00f4leurs - La Fabrique de code - Tech blog","og_description":"Une solution \u00e9l\u00e9gante pour d\u00e9porter l'appel \u00e0 getServiceLocator d'un contr\u00f4leur vers une factory qui injectera le service, \u00e9vitant le message \"Deprecated\" !","og_url":"http:\/\/www.lafabriquedecode.com\/blog\/2016\/06\/zend-framework-2-eviter-le-message\/","og_site_name":"La Fabrique de code - Tech blog","article_published_time":"2016-06-23T16:39:16+00:00","og_image":[{"url":"http:\/\/www.lafabriquedecode.com\/blog\/wp-content\/uploads\/2016\/06\/inscr5.png"}],"author":"admin","twitter_card":"summary","twitter_creator":"@LaFabrique2Code","twitter_site":"@LaFabrique2Code","twitter_misc":{"\u00c9crit par":"admin","Dur\u00e9e de lecture estim\u00e9e":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"http:\/\/www.lafabriquedecode.com\/blog\/2016\/06\/zend-framework-2-eviter-le-message\/","url":"http:\/\/www.lafabriquedecode.com\/blog\/2016\/06\/zend-framework-2-eviter-le-message\/","name":"Zend Framework 2 : supprimer l'appel \u00e0 getServiceLocator dans les contr\u00f4leurs - La Fabrique de code - Tech blog","isPartOf":{"@id":"http:\/\/www.lafabriquedecode.com\/blog\/#website"},"datePublished":"2016-06-23T16:39:16+00:00","dateModified":"2016-06-23T16:39:16+00:00","author":{"@id":"http:\/\/www.lafabriquedecode.com\/blog\/#\/schema\/person\/83863c048b82fd9ccf6407bddd241162"},"description":"Une solution \u00e9l\u00e9gante pour d\u00e9porter l'appel \u00e0 getServiceLocator d'un contr\u00f4leur vers une factory qui injectera le service, \u00e9vitant le message \"Deprecated\" !","breadcrumb":{"@id":"http:\/\/www.lafabriquedecode.com\/blog\/2016\/06\/zend-framework-2-eviter-le-message\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["http:\/\/www.lafabriquedecode.com\/blog\/2016\/06\/zend-framework-2-eviter-le-message\/"]}]},{"@type":"BreadcrumbList","@id":"http:\/\/www.lafabriquedecode.com\/blog\/2016\/06\/zend-framework-2-eviter-le-message\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"http:\/\/www.lafabriquedecode.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Zend Framework 2 : supprimer l&rsquo;appel \u00e0 getServiceLocator dans les contr\u00f4leurs"}]},{"@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\/1071"}],"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=1071"}],"version-history":[{"count":3,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/posts\/1071\/revisions"}],"predecessor-version":[{"id":1075,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/posts\/1071\/revisions\/1075"}],"wp:attachment":[{"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/media?parent=1071"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/categories?post=1071"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.lafabriquedecode.com\/blog\/wp-json\/wp\/v2\/tags?post=1071"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}