{"id":151757,"date":"2021-01-11T17:00:32","date_gmt":"2021-01-11T14:00:32","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/how-to-statically-analyse-php-projects-with-phpstan-cloudsavvy-it\/"},"modified":"2021-01-11T17:00:32","modified_gmt":"2021-01-11T14:00:32","slug":"how-to-statically-analyse-php-projects-with-phpstan-cloudsavvy-it","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/how-to-statically-analyse-php-projects-with-phpstan-cloudsavvy-it\/","title":{"rendered":"#How to Statically Analyse PHP Projects with PHPStan \u2013 CloudSavvy IT"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_84 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a2920d4f0377\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #dd3333;color:#dd3333\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #dd3333;color:#dd3333\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a2920d4f0377\" checked aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-statically-analyse-php-projects-with-phpstan-cloudsavvy-it\/#Adding_PHPStan_to_Your_Project\" >Adding PHPStan to Your Project<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-statically-analyse-php-projects-with-phpstan-cloudsavvy-it\/#Error_Types_and_Levels\" >Error Types and Levels<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-statically-analyse-php-projects-with-phpstan-cloudsavvy-it\/#Configuring_PHPStan\" >Configuring PHPStan<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-statically-analyse-php-projects-with-phpstan-cloudsavvy-it\/#Ignoring_Errors\" >Ignoring Errors<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-statically-analyse-php-projects-with-phpstan-cloudsavvy-it\/#Optional_Rules\" >Optional Rules<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-statically-analyse-php-projects-with-phpstan-cloudsavvy-it\/#Conclusion\" >Conclusion<\/a><\/li><\/ul><\/nav><\/div>\n<p><strong>&#8220;#How to Statically Analyse PHP Projects with PHPStan \u2013 CloudSavvy IT&#8221;<\/strong><\/p>\n<div id=\"article-content-area\">\n<img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-8891\" src=\"https:\/\/www.cloudsavvyit.com\/thumbcache\/0\/0\/01da48fae324e5f2af86fc7d46cd8a92\/p\/uploads\/2021\/01\/78f4c01e.jpg\" alt=\"PHPStan logo\" width=\"1600\" height=\"900\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p><a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/phpstan.org\/\">PHPStan<\/a> is a static analysis system for PHP projects. It finds bugs in your codebase by inspecting the source files. You don\u2019t need to run your code or manually write tests to discover issues!<\/p>\n<p>The term \u201cstatic analysis\u201d is defined as debugging code without actually executing it. It\u2019s most often used with interpreted languages, such as PHP, as the issues it finds tend to surface at the compilation stage in compiled languages.<\/p>\n<p>Static analysis works best when run within a well-structured, strongly-typed codebase. This is particularly important in the case of PHPStan as it\u2019s technically a hybrid analysis tool.<\/p>\n<p>Contrary to our definition of static analysis, <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/phpstan.org\/blog\/zero-config-analysis-with-static-reflection\">PHPStan will actually load<\/a> and run your source files. This is because it partially utilises PHP\u2019s <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/www.php.net\/manual\/en\/book.reflection.php\">built-in introspective capabilities<\/a> to analyse your project.<\/p>\n<p>Consequently, side effects at the root of the <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/download-scripts-themes-apps\/\" data-internallinksmanager029f6b8e52c=\"9\" title=\"Download Scripts &amp; Themes &amp; Apps\" target=\"_blank\" rel=\"noopener\">script<\/a> will end up being executed:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"php\">\n<pre class=\"de1\"><span class=\"kw2\">function<\/span> example<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span> <span class=\"sy0\">:<\/span> void <span class=\"br0\">{<\/span>\n    <span class=\"kw1\">echo<\/span> <span class=\"st0\">\"Example output\"<\/span><span class=\"sy0\">;<\/span>\n<span class=\"br0\">}<\/span>\n\u00a0\nexample<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Were PHPStan to analyse the file shown above, you would observe <code>Example output<\/code> being emitted to the console. For this reason, it\u2019s best to run PHPStan against inert source files (containing only classes and functions) which do not present side effects when loaded.<\/p>\n<h2 id=\"adding-phpstan-to-your-project\"><span class=\"ez-toc-section\" id=\"Adding_PHPStan_to_Your_Project\"><\/span>Adding PHPStan to Your Project<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>To run PHPStan, you\u2019ll need to have PHP 7.1 or newer. This requirement only applies to the version of PHP used to execute PHPStan itself. The tool is capable of analysing source files targeting older versions of PHP.<\/p>\n<p>It\u2019s recommended you use Composer to add PHPStan as a dependency:<\/p>\n<pre>composer require --dev phpstan\/phpstan<\/pre>\n<p>The PHPStan binary will be added to your project at <code>vendor\/bin\/phpstan<\/code>. You can now use it to analyse your codebase for the first time:<\/p>\n<pre>vendor\/bin\/phpstan analyse src<\/pre>\n<p>The command shown above will run PHPStan\u2019s tests against all the source files in your <code>src<\/code> directory. Depending on the size of your codebase, this might take a few minutes to complete.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-8897\" src=\"https:\/\/www.cloudsavvyit.com\/thumbcache\/0\/0\/d8157499d444407b05054223dd7d427e\/p\/uploads\/2021\/01\/6c9b9ecf.jpeg\" alt=\"A successful PHPStan run\" width=\"600\" height=\"260\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>You\u2019ll see a green \u201c[OK] No errors\u201d message if all the tests pass. Otherwise, the list of errors encountered will be displayed. Follow the guidance shown to resolve each error before re-running PHPStan.<\/p>\n<h2 id=\"error-types-and-levels\"><span class=\"ez-toc-section\" id=\"Error_Types_and_Levels\"><\/span>Error Types and Levels<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>PHPStan includes a plethora of checks covering a wide variety of possible codebase issues. Some of the most common ones you\u2019ll encounter include the following:<\/p>\n<ul>\n<li><strong>Type system issues<\/strong> \u2013 Assigning a typed property an invalid value, or passing incorrectly typed parameters to a method. This also includes contract issues, such as a class incorrectly implementing an interface.<\/li>\n<li><strong>Function invocations<\/strong> \u2013 Passing too many, or not enough, parameters when calling a function or method (e.g.\u00a03 instead of 4).<\/li>\n<li><strong>Unknown classes, methods and functions<\/strong> \u2013 Trying to use something which doesn\u2019t exist within the codebase.<\/li>\n<li><strong>Access to undefined\/possiby undefined variables<\/strong> \u2013 Trying to use a variable that is not defined in a given scope, or that which may not always have a value but is used in a context where one is assumed.<\/li>\n<li><strong>Dead code checking<\/strong> \u2013 Flagging of useless code, such as boolean comparisons which will always resolve to the same value and code branches which will not never get executed (e.g.\u00a0code following a <code>return<\/code> statement within functions).<\/li>\n<\/ul>\n<p>Rules are sorted into 9 different \u201clevels\u201d, labelled from 0 to 8. The special level <code>max<\/code> acts as an alias for the highest possible level. Over time, PHPStan may add additional numerical levels, so using <code>max<\/code> ensures you always get the strictest possible checks.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-8898\" src=\"https:\/\/www.cloudsavvyit.com\/thumbcache\/0\/0\/9cd768eb2c10a3996d0fddaceba5991a\/p\/uploads\/2021\/01\/4e9ba80b.jpeg\" alt=\"A failed PHPStan run\" width=\"740\" height=\"280\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>By default, PHPStan executes level 0. This includes only the most fundamental of tests. It\u2019s a good idea to get your codebase passing each level individually before advancing to the next one. Mature projects are likely to run into another set of issues with each new level.<\/p>\n<p>To change the level PHPStan uses, you can pass the <code>--level<\/code> command line parameter:<\/p>\n<p><code>vendor\/bin\/phpstan analyse src --level 8<\/code><\/p>\n<p>In addition to the built-in checks, PHPStan extensions are available to add even more functionality. You can also write your own rules from scratch. This is useful when you\u2019re deprecating functionality that developers should no longer use in any new code. We\u2019ll cover creating custom rules in a future article.<\/p>\n<h2 id=\"configuring-phpstan\"><span class=\"ez-toc-section\" id=\"Configuring_PHPStan\"><\/span>Configuring PHPStan<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Beyond initial experimentation, using PHPStan\u2019s command-line interface can quickly become tiresome. It\u2019s best to add a configuration file to your project which can then be committed to source control for all your developers to use.<\/p>\n<p>PHPStan uses the <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/ne-on.org\/\">Neon<\/a> configuration file format, which has a syntax very similar to YAML. Create a <code>phpstan.neon<\/code> file in your project\u2019s root directory. This file is automatically loaded whenever PHPStan starts, so you can now run the <code>analyse<\/code> command with no further arguments:<\/p>\n<pre>vendor\/bin\/phpstan analyse<\/pre>\n<p>To override the configuration file which is used, pass the <code>--configuration<\/code> flag:<\/p>\n<pre>vendor\/bin\/phpstan analyse --configuration \/phpstan-config.neon<\/pre>\n<p>You now need to populate your <code>phpstan.neon<\/code> file with some content. A good starting point might look like this:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"yml\">\n<pre class=\"de1\">parameters:&#13;\n  level: 0&#13;\n  paths:&#13;\n    - src<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>This basic configuration file should give the same output as the command-line invocation shown earlier. You can add additional directories to scan as new lines in the <code>paths<\/code> section. To exclude files and directories, add them to an <code>excludes_analyse<\/code> leaf within the same <code>parameters<\/code> section.<\/p>\n<h2 id=\"ignoring-errors\"><span class=\"ez-toc-section\" id=\"Ignoring_Errors\"><\/span>Ignoring Errors<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Occasionally, PHPStan may surface an issue which is unavoidable. If there\u2019s a problem which you cannot im<a href=\"https:\/\/buradabiliyorum.com\/en\/category\/social-mediaa\/\" data-internallinksmanager029f6b8e52c=\"1\" title=\"Social Media\" target=\"_blank\" rel=\"noopener\">media<\/a>tely address, you may wish to explicitly ignore it in order to allow the tests to pass.<\/p>\n<p>This is particularly important when you want to move up to another level of checks, or you\u2019re using PHPStan in a CI environment where a failed run will stop your build deploying. Even so, don\u2019t take this course of action lightly \u2013 you should only choose to ignore a reported error if you\u2019re certain it will be safe to do so.<\/p>\n<p>Once you\u2019ve made the decision, add a new <code>ignoreErrors<\/code> section within the <code>parameters<\/code> of your configuration file. You have to define the message to match, as a regex, and the paths to apply the exclusion to:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"yml\">\n<pre class=\"de1\">parameters:&#13;\n  level: 0&#13;\n  paths:&#13;\n    - src&#13;\n  ignoreErrors:&#13;\n    - message: '\/Return type string of method ExampleClass::example() is not covariant(.*).'&#13;\n      path: src\/ExampleClass.php<\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>You can optionally specify <code>paths<\/code> as an array of paths, replacing the single <code>path<\/code> key shown above.<\/p>\n<h2 id=\"optional-rules\"><span class=\"ez-toc-section\" id=\"Optional_Rules\"><\/span>Optional Rules<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>PHPStan\u2019s strictness can be adjusted by a <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/watch-movies-tv-seriess\/\" data-internallinksmanager029f6b8e52c=\"8\" title=\"Watch Movies &amp; TV Series\" target=\"_blank\" rel=\"noopener\">series<\/a> of configuration variables. These allow you to finetune the checks which are made, outside of the levels system described above. Some of these are potentially controversial or unlikely to align with all private style guides, hence they\u2019re off by default.<\/p>\n<p>A few settings which might be worth enabling include:<\/p>\n<ul>\n<li><code>checkAlwaysTrueInstanceof<\/code> \u2013 Flags uses of <code>instanceof<\/code> which will always evaluate to <code>true<\/code>.<\/li>\n<li><code>checkAlwaysTrueStrictComparison<\/code> \u2013 Flags when an expression using <code>===<\/code> or <code>!==<\/code> will always evaluate to <code>true<\/code>.<\/li>\n<li><code>checkFunctionNameCase<\/code> \u2013 Ensures the casing of function names matches their definition when called throughout the codebase.<\/li>\n<li><code>polluteScopeWithLoopInitialAssignments<\/code> \u2013 When set to <code>false<\/code> (it\u2019s <code>true<\/code> by default), variables declared in initial loop statements (e.g.\u00a0<code>$i<\/code> in <code>$for ($i = 1; $i &lt; 10; $i++)<\/code>) are prevented from being accessed outside the loop\u2019s code block, avoiding possible pollution of the parent scope.<\/li>\n<li><code>reportStaticMethodSignatures<\/code> \u2013 Enforces full type checking for parameters and return types in static methods when overridden by a child class.<\/li>\n<\/ul>\n<p>Complete details on these optional settings \u2013 and many more \u2013 can be found within PHPStan\u2019s <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/phpstan.org\/config-reference\">configuration reference<\/a>.<\/p>\n<h2 id=\"conclusion\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>That\u2019s the end of our introduction to <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/phpstan.org\/\">PHPStan<\/a>. It helps you have confidence in your codebase and highlights possible issues before they become a problem in production.<\/p>\n<p>PHPStan is so quick to setup that there\u2019s really no reason not to use it, especially when working with a modern strongly-typed codebase. Don\u2019t be tricked into thinking it can replace manual testing though. PHPStan may boast a large assortment of checks but it cannot identify logical issues and does not understand your project\u2019s business rules. It\u2019s merely another asset in your toolbox when assessing a codebase\u2019s health, serving alongside trusted companions such as unit tests and end-to-end functionality tests.\n<\/p><\/div>\n<blockquote><p><strong><span style=\"color: #ff6600;\">If you liked the article, do not forget to share it with your friends. Follow us on\u00a0<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/news.google.com\/publications\/CAAqBwgKMLG0nwswvr63Aw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Google News<\/a><\/span>\u00a0too, click on the star and choose us from your favorites.<\/span><\/strong><\/p><\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\">For forums sites go to <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/forum.buradabiliyorum.com\/\" target=\"_blank\" rel=\"noopener\">Forum.BuradaBiliyorum.Com<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\"><strong>If you want to read more like this article, you can visit our <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/en.buradabiliyorum.com\/technology\/\" target=\"_blank\" rel=\"noopener\">Technology category.<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<p><span style=\"color: black;\"><a style=\"color: #ff9900;\" href=\"https:\/\/www.cloudsavvyit.com\/8890\/how-to-statically-analyse-php-projects-with-phpstan\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;#How to Statically Analyse PHP Projects with PHPStan \u2013 CloudSavvy IT&#8221; PHPStan is a static analysis system for PHP projects. It finds bugs in your codebase by inspecting the source files. You don\u2019t need to run your code or manually write tests to discover issues! The term \u201cstatic analysis\u201d is defined as debugging code without&#8230;<\/p>\n","protected":false},"author":1,"featured_media":151758,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/01\/78f4c01e.jpg","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-151757","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/151757","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/comments?post=151757"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/151757\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/151758"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=151757"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=151757"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=151757"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}