{"id":2803,"date":"2020-01-29T22:05:11","date_gmt":"2020-01-29T20:05:11","guid":{"rendered":"https:\/\/nyamsprod.com\/blog\/?p=2803"},"modified":"2020-01-30T11:50:45","modified_gmt":"2020-01-30T09:50:45","slug":"generating-uri-template-in-php","status":"publish","type":"post","link":"https:\/\/nyamsprod.com\/blog\/generating-uri-template-in-php\/","title":{"rendered":"A class to generate URI Template in PHP"},"content":{"rendered":"<div class=\"message warning\">\n<p><strong>Attention:<\/strong> Les informations de ce billet sont susceptibles d'&ecirc;tre obsol&egrave;tes car vieux de plus 2 ans.<\/p>\n<p><strong>Warning: <\/strong> The information you are reading may be obsolete, this post was published more than 2 years ago.<\/p>\n<\/div>\n<p>Ever since I released the <code>League\\Uri<\/code> package I always wanted to add an URI template class in it. But I never felt having to write one because I never used the URI template feature myself and the only time I had to do it I used the implementation that came bundle with the <code>Guzzle<\/code> library. It turns out that <code>Guzzle's<\/code> maintainers have decided to drop their own implementation for the next <code>Guzzle<\/code> major release which is in beta release as of this writing. And since I was in need of such feature I finally got around to add the functionality to the <code>League\\Uri<\/code> library.<br>In this post I would like to introduce the <code>League\\Uri\\UriTemplate<\/code>, the main new feature of <code>League\\Uri 6.1<\/code>.<\/p>\n\n\n\n<p>For starter, like most of the other classes included in the library the <code>League\\Uri\\UriTemplate<\/code> follows a known RFC which is <a rel=\"noreferrer noopener\" aria-label=\"RFC6750 (s\u2019ouvre dans un nouvel onglet)\" href=\"https:\/\/tools.ietf.org\/html\/rfc6570\" target=\"_blank\">RFC6750<\/a>. This RFC describes how to interpolate and expand a template so that its result is a fully compliant URI as described in <a rel=\"noreferrer noopener\" aria-label=\"RFC3986 (s\u2019ouvre dans un nouvel onglet)\" href=\"https:\/\/tools.ietf.org\/html\/rfc3986\" target=\"_blank\">RFC3986<\/a>.<br><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using the template<\/h2>\n\n\n\n<p>While the core expansion logic is based on the <code>Guzzle<\/code> 6.5 implementation, its public facing API is a combination of the main Python and Java implementations.<\/p>\n\n\n<script src=\"https:\/\/gist.github.com\/7eeee674eb64e8384637e9c07239d3b7.js?file=uri-template-basic-usage.php\"><\/script>\n\n\n\n<p>The advantage of this public API versus the one that was used in the <code>Guzzle<\/code> implementation is that with one object you can create an infinite number of URI instance by just changing your variables on each <code>UriTemplate::expand<\/code> calls. The template is parsed only once on instantiation. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Using the variables<\/h2>\n\n\n\n<p>Another nit trick is that you can define default variables on the constructor <br><\/p>\n\n\n<script src=\"https:\/\/gist.github.com\/7eeee674eb64e8384637e9c07239d3b7.js?file=uri-template-with-default-variables.php\"><\/script>\n\n\n\n<p>In the example above, the <code>version<\/code> variable is applied without you having to fill it in the when calling the <code>expand<\/code> method. Keep in mind, that to give you more flexibility the default variables can still be overwritten if the same variables are used with the <code>expand<\/code> method.<\/p>\n\n\n<script src=\"https:\/\/gist.github.com\/7eeee674eb64e8384637e9c07239d3b7.js?file=uri-template-with-default-variables-overwritten.php\"><\/script>\n\n\n\n<h2 class=\"wp-block-heading\">Interoperability<\/h2>\n\n\n\n<p>To enable better interoperability with other implementations in other languages, the class was design using an independent <a rel=\"noreferrer noopener\" aria-label=\"uri template test suite (s\u2019ouvre dans un nouvel onglet)\" href=\"https:\/\/github.com\/uri-templates\/uritemplate-test\" target=\"_blank\">URI template test suite<\/a> for expansion conformance. So while updating the implementation I made sure to always pass this independent test.<br><br>In order to do so, under the hood, the class does lots of validations on instantiation and when using the <code>expand<\/code> method to make sure:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>the template syntax is conformed to the RFC;<\/li><li>the variable syntax is not forbidden by the RFC;<\/li><li>the resulting expansion produces an RFC compliant URI instance;<\/li><\/ul>\n\n\n\n<p>Some optimisations are also introduced to lazy cache template expansion in case no variable and\/or no expression are presents.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Alternative<\/h2>\n\n\n\n<p>If you already worked with URI Template in PHP you probably came across the <a href=\"https:\/\/github.com\/rize\/UriTemplate\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (s\u2019ouvre dans un nouvel onglet)\">rize\/uri-template<\/a> library. The main differences between both implementations apart from the public API are that the latter offers features that are not covered by the RFC, and thus, are not present in this class. Namely an extraction feature which returns the possible variables used in a valid URI and an extension to add the ability to expand URI using <code>http_build_query<\/code> type parameters.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Final note<\/h2>\n\n\n\n<p>The <a href=\"https:\/\/github.com\/thephpleague\/uri\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (s\u2019ouvre dans un nouvel onglet)\">League\/Uri<\/a> is an open source project with a MIT License so contributions are more than welcome and  will be fully credited. These contributions can be anything from reporting an issue, requesting or <br> adding missing features or simply improving or correcting some typo on the documentation website.<\/p>\n\n\n\n<p>And if you appreciate the work and the effort put in the library you can also <a href=\"https:\/\/github.com\/sponsors\/nyamsprod\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (s\u2019ouvre dans un nouvel onglet)\">sponsor me<\/a> to enable me to continue to fix and improve the library.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to use the new UriTemplate class in league uri v6<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[5],"tags":[412,785,794,820],"class_list":["post-2803","post","type-post","status-publish","format-standard","hentry","category-web","tag-php","tag-thephpleague","tag-uri","tag-uri-template"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/nyamsprod.com\/blog\/wp-json\/wp\/v2\/posts\/2803","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nyamsprod.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nyamsprod.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nyamsprod.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nyamsprod.com\/blog\/wp-json\/wp\/v2\/comments?post=2803"}],"version-history":[{"count":5,"href":"https:\/\/nyamsprod.com\/blog\/wp-json\/wp\/v2\/posts\/2803\/revisions"}],"predecessor-version":[{"id":2814,"href":"https:\/\/nyamsprod.com\/blog\/wp-json\/wp\/v2\/posts\/2803\/revisions\/2814"}],"wp:attachment":[{"href":"https:\/\/nyamsprod.com\/blog\/wp-json\/wp\/v2\/media?parent=2803"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nyamsprod.com\/blog\/wp-json\/wp\/v2\/categories?post=2803"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nyamsprod.com\/blog\/wp-json\/wp\/v2\/tags?post=2803"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}