{"id":92016,"date":"2020-10-18T17:00:31","date_gmt":"2020-10-18T14:00:31","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/php-code-quality-tools-to-check-and-improve-your-code\/"},"modified":"2020-10-18T17:00:31","modified_gmt":"2020-10-18T14:00:31","slug":"php-code-quality-tools-to-check-and-improve-your-code","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/","title":{"rendered":"#PHP code quality tools to check and improve your code"},"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-6a2d7e17548aa\" 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-6a2d7e17548aa\" checked aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#In_your_terminal\" >In your terminal<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#In_Vim_Neovim\" >In Vim \/ Neovim<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#In_PHPStorm\" >In PHPStorm<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#PHP-CS-Fixer_PHP_coding_standards_fixer\" >PHP-CS-Fixer (PHP coding standards fixer)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#PHPCS_PHP_CodeSniffer\" >PHPCS (PHP CodeSniffer)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#PHPMD_PHP_Mess_Detector\" >PHPMD (PHP Mess Detector)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#PHPStan_PHP_Static_Analysis_Tool\" >PHPStan (PHP Static Analysis Tool)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#PHPUnit_and_the_CRAP_metric\" >PHPUnit and the CRAP metric<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#Checking_your_PHP_code_deeper\" >Checking your PHP code deeper<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#PhpLoc\" >PhpLoc<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#PHP_insight\" >PHP insight<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#PHPCPD_PHP_Copy_past_detector\" >PHPCPD (PHP Copy past detector)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#PHPMND_PHP_magic_number_detector\" >PHPMND (PHP magic number detector)<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#dePHPend\" >dePHPend<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#churn-php\" >churn-php<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#PhpCodeFixer\" >PhpCodeFixer<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/buradabiliyorum.com\/en\/php-code-quality-tools-to-check-and-improve-your-code\/#PhpMetrics\" >PhpMetrics<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<p>&#8220;<strong>#PHP code quality tools to check and improve your code<\/strong>&#8221;<\/p>\n<div>\n                            <img loading=\"lazy\" decoding=\"async\" class=\" lazy\" alt=\"a good mentor is better than any quality tool\" width=\"726\" height=\"484\" src=\"https:\/\/thevaluable.dev\/images\/2018\/03\/quality-tool-php.jpg\" data-lazy=\"true\"\/><\/p>\n<p>They were coded by Dave, your colleague developer.<\/p>\n<p>The classes are full of formatting errors, poor indentation, and weird one letter variables. There are so many dependencies you need to scroll down for minutes to escape the bloated constructor.<\/p>\n<p>Shacking, you open the unit tests to understand how it should work\u2026 but they don\u2019t exist. Horror and misfortune!<\/p>\n<p>You could ask Dave to come to your desk, yelling at him that you never saw anywhere such a cr<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\">app<\/a>y code, cursing him and his family for generations to come.<\/p>\n<p>However, since you are such a respectful human being, you know it\u2019s not a good solution. Teaching instead of blaming always gives better results.<\/p>\n<p>With a calm worthy of a Zen monk, you first fix the bug driving your boss crazy with Dave\u2019s help. Then, you decide to introduce to your team some code quality tools.<\/p>\n<p>You\u2019ve got a good approach dear reader: code quality tools are essential to write solid and error-free PHP code. It can help your colleagues detect defects in the codebase and teach them some key concepts.<\/p>\n<p>Don\u2019t forget however that the advice and the data they can provide won\u2019t be appropriate everywhere. As often, it depends largely on the context: is your codebase large? Is there a good reason the cyclomatic complexity is high for some function?<\/p>\n<p>If you are already bored by this article and just want to see a plain PHP tools list, you can directly go to the reference list at the end.<\/p>\n<p>The last thing before diving in: tools presented in this article analyze or format your code. I won\u2019t speak about testing.<\/p>\n<p><em>[Read: 3 concrete steps to learning a programming language]<\/em><\/p>\n<p>There are always multiple ways to install the tools described here.<\/p>\n<p>My personal preference is to use the composer\u2019s global package installation using <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/github.com\/consolidation\/cgr\">cgr<\/a> to avoid dependency problems on the global scope.<\/p>\n<p>You can as well use the <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/en.wikipedia.org\/wiki\/PHAR_%28file_format%29\">PHAR<\/a> format, in most cases.<\/p>\n<p>You can refer to the documentation of each tool to have every possible way of installing them.<\/p>\n<h3 id=\"in-your-terminal\"><span class=\"ez-toc-section\" id=\"In_your_terminal\"><\/span>In your terminal<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>All the tools can be used in the terminal. Most of the time you just need to pass the codebase\u2019s path as an argument and voila! I describe this process for every tools in this article.<\/p>\n<p>I advise you to call the tools from the main folder of your project. Every example assume that your codebase is in the folder <code>src<\/code>.<\/p>\n<h3 id=\"in-vim--neovim\"><span class=\"ez-toc-section\" id=\"In_Vim_Neovim\"><\/span>In Vim \/ Neovim<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>You can easily configure in Vim every tool you want and let them parse your open files.<\/p>\n<p>With the plugin <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/thevaluable.dev\/vim-php-ide\/\">neomake<\/a> you can plug easily PHPMD, PHPSTAN, and PHPCS to Vim. It will display in the gutter warnings and errors. Very handy!<\/p>\n<p>You can even create your own makers to use every PHP code quality tools you want. As a reference, you can consult my <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/github.com\/Phantas0s\/.dotfiles\/blob\/master\/nvim\/pluggedconf\/neomake.nvimrc\">neomake config file<\/a>.<\/p>\n<h3 id=\"in-phpstorm\"><span class=\"ez-toc-section\" id=\"In_PHPStorm\"><\/span>In PHPStorm<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Since <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/thevaluable.dev\/phpstorm-vs-vim\/\">I don\u2019t use PhpStorm anymore<\/a>, I won\u2019t explain how to install these tools in the IDE.<\/p>\n<p>Nevertheless here some handly links to Jetbrain\u2019s documentation:<\/p>\n<p>I wouldn\u2019t write any line of code without the following plugins. They will format your code properly and gives you precious advice.<\/p>\n<h3 id=\"php-cs-fixer-php-coding-standards-fixer\"><span class=\"ez-toc-section\" id=\"PHP-CS-Fixer_PHP_coding_standards_fixer\"><\/span>PHP-CS-Fixer (PHP coding standards fixer)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Let\u2019s begin by the cause of long meetings, hatred behavior, and murder impulses: code formatting rules. A great example of <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/en.wikipedia.org\/wiki\/Law_of_triviality\">Parkinson\u2019s Law of Triviality<\/a>.<\/p>\n<p>Personally I don\u2019t have any preferences regarding code formatting. What I care about is to have a <em>consistent<\/em> one:<\/p>\n<ul>\n<li>It\u2019s easier to read<\/li>\n<li>It frees your mind for more important questions<\/li>\n<\/ul>\n<p>PHP-CS-fixer is a simple tools that allows you to format your code automatically. By default, <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/www.php-fig.org\/psr\/psr-1\/\">PSR-1<\/a> and <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/www.php-fig.org\/psr\/psr-2\/\">PSR-2<\/a> rules are used but you can define your own formatting rules.<\/p>\n<p>With the following command you can format an entire codebase:<\/p>\n<p><code>$ php-cs-fixer fix src\/<\/code><\/p>\n<p>You have as well the possibility to preview the modifications without applying them (<code>--diff<\/code> option) or you can precise the rules (<code>--rules<\/code> option) you want to use.<\/p>\n<h3 id=\"phpcs-php-codesniffer\"><span class=\"ez-toc-section\" id=\"PHPCS_PHP_CodeSniffer\"><\/span>PHPCS (PHP CodeSniffer)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>PHP CodeSniffer is a very good tool to output the coding standards violations you have in your codebase. Two command line scripts can be used: <code>phpcs<\/code> to output the actual coding standards flaws, and phpcbf which can fix some errors for you.<\/p>\n<p>You can type for example:<\/p>\n<p><code>$ phpcs src\/<\/code><\/p>\n<p>The output will look like that:<\/p>\n<pre><code>FILE: \/home\/superCoolUser\/mySuperProject\/src\/Model\/SuperModel.php&#13;\n------------------------------------------------------------------------------------------&#13;\nFOUND 6 ERRORS AND 1 WARNINGS AFFECTING 7 LINES&#13;\n------------------------------------------------------------------------------------------&#13;\n  2 | ERROR   | [ ] Missing file doc comment&#13;\n 14 | ERROR   | [ ] Missing @category tag in class comment&#13;\n 20 | ERROR   | [ ] Missing doc comment for function __construct()&#13;\n 34 | WARNING | [ ] Line exceeds 85 characters; contains 93 characters&#13;\n 57 | ERROR   | [x] Opening parenthesis of a multi-line function call must be the last content on the line&#13;\n 60 | ERROR   | [ ] Expected \"if (...) {n\"; found \"if(...) {n\"&#13;\n 63 | ERROR   | [x] Closing parenthesis of a multi-line function call must be on a line by itself&#13;\n----------------------------------------------------------------------------&#13;\nPHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY&#13;\n----------------------------------------------------------------------------&#13;\n<\/code><\/pre>\n<p>As you can see phpcbf can fix automatically two errors for you by typing:<\/p>\n<p><code>$ phpcbf src\/Model\/SuperModel.php<\/code><\/p>\n<p>You can use the default coding standard shipped with PHP Code Sniffer or you can easily implement your own.<\/p>\n<h3 id=\"phpmd-php-mess-detector\"><span class=\"ez-toc-section\" id=\"PHPMD_PHP_Mess_Detector\"><\/span>PHPMD (PHP Mess Detector)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>PHPMD will display the possible bugs and misuses of the language in your application.<\/p>\n<p>Here how to do the magic:<\/p>\n<p><code>$ phpmd src\/ text cleancode<\/code><\/p>\n<p>PHPMD will scan the directory and sub-directories of your project and output in plain text the errors found. You can as well create an <code>html<\/code> or <code>xml<\/code> output by replacing the <code>text<\/code> option in the command line above.<\/p>\n<p>In this example, we use the <code>cleancode<\/code> ruleset but you can obviously change it or create your own.<\/p>\n<p>Do you want to output the errors in a file? Easy:<\/p>\n<p><code>$ phpmd src\/ html cleancode --reportfile ~\/phpmd.html<\/code><\/p>\n<p>If you choose <code>xml<\/code> as output you will have more information regarding the rule set as following:<\/p>\n<div class=\"highlight\">\n<pre class=\"chroma\"><code class=\"language-xml\" data-lang=\"xml\">  <span class=\"nt\">&lt;file<\/span> <span class=\"na\">name=<\/span><span class=\"s\">\"\/home\/mySuperUser\/mySuperProject\/src\/randomClass.php\"<\/span><span class=\"nt\">&gt;<\/span>&#13;\n    <span class=\"nt\">&lt;violation<\/span> <span class=\"na\">beginline=<\/span><span class=\"s\">\"61\"<\/span> <span class=\"na\">endline=<\/span><span class=\"s\">\"61\"<\/span> <span class=\"na\">rule=<\/span><span class=\"s\">\"BooleanArgumentFlag\"<\/span> <span class=\"na\">ruleset=<\/span><span class=\"s\">\"Clean Code Rules\"<\/span> <span class=\"na\">externalInfoUrl=<\/span><span class=\"s\">\"http:\/\/phpmd.org\/rules\/cleancode.html#booleanargumentflag\"<\/span> <span class=\"na\">priority=<\/span><span class=\"s\">\"1\"<\/span><span class=\"nt\">&gt;<\/span>&#13;\n      The method notThatCoolMethod has a boolean flag argument $badBoolean, which is a certain sign of a Single Responsibility Principle violation.&#13;\n    <span class=\"nt\">&lt;\/violation&gt;<\/span>&#13;\n    <span class=\"nt\">&lt;violation<\/span> <span class=\"na\">beginline=<\/span><span class=\"s\">\"102\"<\/span> <span class=\"na\">endline=<\/span><span class=\"s\">\"104\"<\/span> <span class=\"na\">rule=<\/span><span class=\"s\">\"ElseExpression\"<\/span> <span class=\"na\">ruleset=<\/span><span class=\"s\">\"Clean Code Rules\"<\/span> <span class=\"na\">externalInfoUrl=<\/span><span class=\"s\">\"http:\/\/phpmd.org\/rules\/cleancode.html#elseexpression\"<\/span> <span class=\"na\">priority=<\/span><span class=\"s\">\"1\"<\/span><span class=\"nt\">&gt;<\/span>&#13;\n      The method superMethod uses an else expression. Else is never necessary and you can simplify the code to work without else.&#13;\n    <span class=\"nt\">&lt;\/violation&gt;<\/span>&#13;\n  <span class=\"nt\">&lt;\/file&gt;<\/span>&#13;\n<\/code><\/pre>\n<\/div>\n<p>You can see for example the priority of the rules violated. You can then refine your result by using the <code>--minimumpriority<\/code> option for example.<\/p>\n<p>In short: PHPMD is a great tool I really encourage you to use. It will detect a lot of potential problems in your code and will save you hours of debugging.<\/p>\n<p>Your boss will be so happy he will increase your salary by 200%. Guaranteed.<\/p>\n<h3 id=\"phpstan-php-static-analysis-tool\"><span class=\"ez-toc-section\" id=\"PHPStan_PHP_Static_Analysis_Tool\"><\/span>PHPStan (PHP Static Analysis Tool)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>PHPStan is another tool to have in your toolbox. Does it aim? Output errors like a compiled language would display during compilation. It\u2019s a good complement to PHPMD.<\/p>\n<p>You can run it as follow:<\/p>\n<p><code>$ phpstan analyse src\/ --level=7<\/code><\/p>\n<p>You can precise the strictness of PHPStan with the level option. The minimum is <code>level 0<\/code>, the maximum <code>level 7<\/code>.<\/p>\n<p>To give you an idea here an example of the output:<\/p>\n<pre><code> ------ -----------------------------------------------------------------------&#13;\n  Line   src\/MySuperModels\/RandomModel&#13;\n ------ -----------------------------------------------------------------------&#13;\n  78     Instantiated class AppServiceApiInvalidArgumentException not found.&#13;\n  82     Instantiated class AppServiceApiInvalidArgumentException not found.&#13;\n  93     Method AppServiceApiClientClientInterface::post() invoked with 3 parameters, 4 required.&#13;\n  103    Casting to string something that's already string.&#13;\n ------ -----------------------------------------------------------------------&#13;\n<\/code><\/pre>\n<p>Like the other tools, you can create your own rules.<\/p>\n<h3 id=\"phpunit-and-the-crap-metric\"><span class=\"ez-toc-section\" id=\"PHPUnit_and_the_CRAP_metric\"><\/span>PHPUnit and the CRAP metric<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This article is not about the unit test. I assume you know that unit testing your code is far more important than anything present in this article.<\/p>\n<p>PHPUnit can as well display very interesting information: the <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/blog.ndepend.com\/crap-metric-thing-tells-risk-code\/\">CRAP<\/a> metric.<\/p>\n<p>CRAP uses the <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/en.wikipedia.org\/wiki\/Cyclomatic_complexity\">cyclomatic complexity<\/a> with the code coverage of your code to display what might be the code difficult to change in your application.<\/p>\n<p>The more the CRAP index is high, the more your code will be considered as \u201ccrappy.\u201d<\/p>\n<p>Indeed if your code has a great complexity but a low code coverage, you can expect it to cause unfortunate bugs each time you change it. You won\u2019t even notice till your boss yells at you. Expect Dave, your colleague developer, trying to push you even more down for him to shine in the shadow of your shame.<\/p>\n<p>To display the CRAP metrics, you need to produce a code coverage report:<\/p>\n<p><code>$ phpunit phpunit --coverage-html .\/tempFolder<\/code><\/p>\n<p>This will create HTML files in the <code>tempFolder<\/code> directory. You can open the <code>index.html<\/code> in there and click on the dashboard link to finally contemplate the CRAP indicator.<\/p>\n<p><img decoding=\"async\" alt=\"crap metric\" class=\" lazy\" src=\"https:\/\/thevaluable.dev\/images\/2018\/03\/crap.png\" data-lazy=\"true\"\/><em>Journey to the center of the CRAP<\/em><\/p>\n<p>Please remember, however: code coverage doesn\u2019t mean that your code is well tested. This is an entirely different topic I will keep for another article.<\/p>\n<h2 id=\"checking-your-php-code-deeper\"><span class=\"ez-toc-section\" id=\"Checking_your_PHP_code_deeper\"><\/span>Checking your PHP code deeper<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>I use the following tools to make sure that the project I work on goes in the right direction. They can help you with seeing the big picture.<\/p>\n<p>They can as well be a real-life savior when you need to work on an unknown (legacy) application. They can be a great help for refactoring.<\/p>\n<h3 id=\"phploc\"><span class=\"ez-toc-section\" id=\"PhpLoc\"><\/span>PhpLoc<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>PhpLoc is a very good tool to get an idea of the size of a project.<\/p>\n<p>You can execute on your codebase:<\/p>\n<p><code>$ phploc src<\/code><\/p>\n<p>This will output something like that:<\/p>\n<div class=\"highlight\">\n<pre class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\">Size&#13;\n  Lines of Code <span class=\"o\">(<\/span>LOC<span class=\"o\">)<\/span>                               <span class=\"m\">61<\/span>&#13;\n  Comment Lines of Code <span class=\"o\">(<\/span>CLOC<span class=\"o\">)<\/span>                       <span class=\"m\">0<\/span> <span class=\"o\">(<\/span>0.00%<span class=\"o\">)<\/span>&#13;\n  Non-Comment Lines of Code <span class=\"o\">(<\/span>NCLOC<span class=\"o\">)<\/span>                 <span class=\"m\">61<\/span> <span class=\"o\">(<\/span>100.00%<span class=\"o\">)<\/span>&#13;\n  Logical Lines of Code <span class=\"o\">(<\/span>LLOC<span class=\"o\">)<\/span>                      <span class=\"m\">23<\/span> <span class=\"o\">(<\/span>37.70%<span class=\"o\">)<\/span>&#13;\n    Classes                                         <span class=\"m\">17<\/span> <span class=\"o\">(<\/span>73.91%<span class=\"o\">)<\/span>&#13;\n      Average Class Length                          <span class=\"m\">17<\/span>&#13;\n        Minimum Class Length                        <span class=\"m\">17<\/span>&#13;\n        Maximum Class Length                        <span class=\"m\">17<\/span>&#13;\n      Average Method Length                          <span class=\"m\">3<\/span>&#13;\n        Minimum Method Length                        <span class=\"m\">1<\/span>&#13;\n        Maximum Method Length                        <span class=\"m\">7<\/span>&#13;\n    Functions                                        <span class=\"m\">0<\/span> <span class=\"o\">(<\/span>0.00%<span class=\"o\">)<\/span>&#13;\n      Average Function Length                        <span class=\"m\">0<\/span>&#13;\n    Not in classes or functions                      <span class=\"m\">6<\/span> <span class=\"o\">(<\/span>26.09%<span class=\"o\">)<\/span>&#13;\n&#13;\nCyclomatic Complexity&#13;\n  Average Complexity per LLOC                     0.26&#13;\n  Average Complexity per Class                    7.00&#13;\n    Minimum Class Complexity                      7.00&#13;\n    Maximum Class Complexity                      7.00&#13;\n  Average Complexity per Method                   2.20&#13;\n    Minimum Method Complexity                     1.00&#13;\n    Maximum Method Complexity                     4.00&#13;\n&#13;\nDependencies&#13;\n  Global Accesses                                    <span class=\"m\">0<\/span>&#13;\n    Global Constants                                 <span class=\"m\">0<\/span> <span class=\"o\">(<\/span>0.00%<span class=\"o\">)<\/span>&#13;\n    Global Variables                                 <span class=\"m\">0<\/span> <span class=\"o\">(<\/span>0.00%<span class=\"o\">)<\/span>&#13;\n    Super-Global Variables                           <span class=\"m\">0<\/span> <span class=\"o\">(<\/span>0.00%<span class=\"o\">)<\/span>&#13;\n  Attribute Accesses                                 <span class=\"m\">7<\/span>&#13;\n    Non-Static                                       <span class=\"m\">7<\/span> <span class=\"o\">(<\/span>100.00%<span class=\"o\">)<\/span>&#13;\n    Static                                           <span class=\"m\">0<\/span> <span class=\"o\">(<\/span>0.00%<span class=\"o\">)<\/span>&#13;\n  Method Calls                                      <span class=\"m\">14<\/span>&#13;\n    Non-Static                                      <span class=\"m\">14<\/span> <span class=\"o\">(<\/span>100.00%<span class=\"o\">)<\/span>&#13;\n    Static                                           <span class=\"m\">0<\/span> <span class=\"o\">(<\/span>0.00%<span class=\"o\">)<\/span>&#13;\n&#13;\nStructure&#13;\n  Namespaces                                         <span class=\"m\">1<\/span>&#13;\n  Interfaces                                         <span class=\"m\">0<\/span>&#13;\n  Traits                                             <span class=\"m\">0<\/span>&#13;\n  Classes                                            <span class=\"m\">1<\/span>&#13;\n    Abstract Classes                                 <span class=\"m\">0<\/span> <span class=\"o\">(<\/span>0.00%<span class=\"o\">)<\/span>&#13;\n    Concrete Classes                                 <span class=\"m\">1<\/span> <span class=\"o\">(<\/span>100.00%<span class=\"o\">)<\/span>&#13;\n  Methods                                            <span class=\"m\">5<\/span>&#13;\n    Scope&#13;\n      Non-Static Methods                             <span class=\"m\">5<\/span> <span class=\"o\">(<\/span>100.00%<span class=\"o\">)<\/span>&#13;\n      Static Methods                                 <span class=\"m\">0<\/span> <span class=\"o\">(<\/span>0.00%<span class=\"o\">)<\/span>&#13;\n    Visibility&#13;\n      Public Methods                                 <span class=\"m\">3<\/span> <span class=\"o\">(<\/span>60.00%<span class=\"o\">)<\/span>&#13;\n      Non-Public Methods                             <span class=\"m\">2<\/span> <span class=\"o\">(<\/span>40.00%<span class=\"o\">)<\/span>&#13;\n  Functions                                          <span class=\"m\">0<\/span>&#13;\n    Named Functions                                  <span class=\"m\">0<\/span> <span class=\"o\">(<\/span>0.00%<span class=\"o\">)<\/span>&#13;\n    Anonymous Functions                              <span class=\"m\">0<\/span> <span class=\"o\">(<\/span>0.00%<span class=\"o\">)<\/span>&#13;\n  Constants                                          <span class=\"m\">1<\/span>&#13;\n    Global Constants                                 <span class=\"m\">0<\/span> <span class=\"o\">(<\/span>0.00%<span class=\"o\">)<\/span>&#13;\n    Class Constants                                  <span class=\"m\">1<\/span> <span class=\"o\">(<\/span>100.00%<span class=\"o\">)<\/span>&#13;\n&#13;\n<\/code><\/pre>\n<\/div>\n<p>Those data can give you already some clues about the project:<\/p>\n<ul>\n<li>\n<code>Comment lines of code<\/code> is never good. Get rid of it without a second thought.<\/li>\n<li>Too high <code>Average Class length<\/code> is usually not good either. Split the <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"http:\/\/wiki.c2.com\/?GodClass\">god classes<\/a>.<\/li>\n<li>Too high <code>Average Method length<\/code> is again not good. For the sack of your colleagues, split them.<\/li>\n<li>\n<code>Cyclomatic complexity<\/code> can indicate a bit of everything and anything. Trusting something like <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/blog.ndepend.com\/crap-metric-thing-tells-risk-code\/\">CRAP<\/a> might be wiser.<\/li>\n<li>Avoid unnecessary <code>Dependencies<\/code>. Don\u2019t forget that <code>globals accesses, constants and variables<\/code> can <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/thevaluable.dev\/global-variable-states\/\">bring you many problems<\/a>.<\/li>\n<li>Avoid <code>abstract classes<\/code> as much as possible: remember composition over inheritance.<\/li>\n<\/ul>\n<p>In a nutshell: a very simple and valuable tool.<\/p>\n<h3 id=\"php-insight\"><span class=\"ez-toc-section\" id=\"PHP_insight\"><\/span>PHP insight<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>PHP Insight is a pretty good static analyzer that will give you much advice to improve the quality of your code.<\/p>\n<p>You can use it as follow:<\/p>\n<p><code>phpinsights analyse .\/src<\/code><\/p>\n<p>First, It will give you a quick overview of your codebase:<\/p>\n<p><img decoding=\"async\" alt=\"PHP Insight first screen\" class=\" lazy\" src=\"https:\/\/thevaluable.dev\/images\/2018\/03\/php-insight-1.png\" data-lazy=\"true\"\/><\/p>\n<p>Then, it will provide you much advice:<\/p>\n<p><img decoding=\"async\" alt=\"PHP Insight second screen\" class=\" lazy\" src=\"https:\/\/thevaluable.dev\/images\/2018\/03\/php-insight-2.png\" data-lazy=\"true\"\/><\/p>\n<p>This is a really useful tool. You can as well format the output (<code>JSON<\/code> for example) or even create your own rules!<\/p>\n<h3 id=\"phpcpd-php-copy-past-detector\"><span class=\"ez-toc-section\" id=\"PHPCPD_PHP_Copy_past_detector\"><\/span>PHPCPD (PHP Copy past detector)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>PHPCPD will scan your codebase and output the code duplicated.<\/p>\n<p>You can use it by typing:<\/p>\n<p><code>$ phpcpd src\/<\/code><\/p>\n<p>PHPCPD will produce this kind of output:<\/p>\n<pre><code>phpcpd 4.0.0 by Sebastian Bergmann.&#13;\n&#13;\nFound 1 clones with 44 duplicated lines in 2 files:&#13;\n&#13;\n  - \/home\/superUser\/src\/superFile.php:11-55&#13;\n    \/home\/superUser\/src\/superFolder\/superFile.php:11-55&#13;\n&#13;\n5.04% duplicated lines out of 873 total lines of code.&#13;\n&#13;\nTime: 29 ms, Memory: 4.00MB&#13;\n<\/code><\/pre>\n<p>You can include multiple files instead of a whole directory, exclude some files (or paths) or even output the result in a XML file.<\/p>\n<p>Keep in mind though: if you go to the DRY principle violation hunting in your codebase, keep in mind that <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/thevaluable.dev\/dry-principle-explained\/\">code duplication doesn\u2019t necessarily imply DRY violation<\/a>.<\/p>\n<h3 id=\"phpmnd-php-magic-number-detector\"><span class=\"ez-toc-section\" id=\"PHPMND_PHP_magic_number_detector\"><\/span>PHPMND (PHP magic number detector)<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>This tool is pretty specific: it can help you to find <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/en.wikipedia.org\/wiki\/Magic_number_%28programming%29\">magic numbers<\/a> in your code.<\/p>\n<p>The easiest way to use it:<\/p>\n<p><code>$ phpmnd src\/<\/code><\/p>\n<p>Here the output:<\/p>\n<pre><code>--------------------------------------------------------------------------------&#13;\n&#13;\nhttpClient\/myHttpClient.php:98. Magic number: 200&#13;\n  &gt; 98|         if ($response-&gt;getStatusCode() != 200) {&#13;\n&#13;\n--------------------------------------------------------------------------------&#13;\n&#13;\nservice\/superClass.php:47. Magic number: 8&#13;\n  &gt; 47|         for ($i = 0; $i &lt; 8; $i++) {&#13;\n&#13;\n--------------------------------------------------------------------------------&#13;\n&#13;\n<\/code><\/pre>\n<p>You can play with a lot of options, like the possibility to ignore numbers, exclude files \/ paths \/ extensions\u2026<\/p>\n<h3 id=\"dephpend\"><span class=\"ez-toc-section\" id=\"dePHPend\"><\/span>dePHPend<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Did you ever work on a project full of unnecessary dependencies, wondering how to understand this nightmare? Do you want to verify if your wonderful project is not mutating into a complex Big Ball of Mud?<\/p>\n<p>dePHPend can help you grandly on that matter.<\/p>\n<p>You can use it as follow:<\/p>\n<p><code>$ dephpend metrics src\/<\/code><\/p>\n<p>This output will then appear magically:<\/p>\n<p><img decoding=\"async\" alt=\"example dephpend output\" class=\" lazy\" src=\"https:\/\/thevaluable.dev\/images\/2018\/03\/screenshot-20180308-064635.png\" data-lazy=\"true\"\/><\/p>\n<p>As you can see, dePHPend will output the number of <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/en.wikipedia.org\/wiki\/Coupling_%28computer_programming%29\">Afferent Coupling<\/a>, the number of <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/en.wikipedia.org\/wiki\/Efferent_coupling\">Efferent Coupling<\/a> and display an instability indicator based on them.<\/p>\n<p>In clear:<\/p>\n<ul>\n<li>No class depend on the class <code>AppKernel<\/code>\n<\/li>\n<li>The class <code>AppKernel<\/code> depends on five other classes<\/li>\n<\/ul>\n<p>The instability score is high here: this class couple other classes together but is never used!<\/p>\n<p>You can as well output plain text or UML for example.<\/p>\n<h3 id=\"churn-php\"><span class=\"ez-toc-section\" id=\"churn-php\"><\/span>churn-php<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>churn-php will display the classes you should refactor based on the <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/en.wikipedia.org\/wiki\/Cyclomatic_complexity\">cyclomatic complexity<\/a> and the number of commit the class has.<\/p>\n<p>This is a pretty interesting approach. A very complex class that is often modified has indeed a high chance to introduce bugs.<\/p>\n<p>As the other tools, it is very straightforward to use:<\/p>\n<p><code>$ churn run src\/<\/code><\/p>\n<p>Here the result:<\/p>\n<div class=\"highlight\">\n<pre class=\"chroma\"><code class=\"language-bash\" data-lang=\"bash\">+-------------------------------------------+---------------+------------+-------+&#13;\n<span class=\"p\">|<\/span> File                                      <span class=\"p\">|<\/span> Times Changed <span class=\"p\">|<\/span> Complexity <span class=\"p\">|<\/span> Score <span class=\"p\">|<\/span>&#13;\n+-------------------------------------------+---------------+------------+-------+&#13;\n<span class=\"p\">|<\/span> src\/Service\/classToRefactor.php           <span class=\"p\">|<\/span> <span class=\"m\">12<\/span>            <span class=\"p\">|<\/span> <span class=\"m\">8<\/span>          <span class=\"p\">|<\/span> 0.441 <span class=\"p\">|<\/span>&#13;\n<span class=\"p\">|<\/span> src\/Service\/anotherClass.php              <span class=\"p\">|<\/span> <span class=\"m\">3<\/span>             <span class=\"p\">|<\/span> <span class=\"m\">15<\/span>         <span class=\"p\">|<\/span> 0.185 <span class=\"p\">|<\/span>&#13;\n+-------------------------------------------+---------------+------------+-------+&#13;\n<\/code><\/pre>\n<\/div>\n<p>The higher the score, the greater the need to refactor.<\/p>\n<h3 id=\"phpcodefixer\"><span class=\"ez-toc-section\" id=\"PhpCodeFixer\"><\/span>PhpCodeFixer<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Deprecated functions are bad. They can create very weird bugs difficult to debug. This tool can help you detect them in your shiny application. You can precise the version of PHP you work with and your main codebase directory as follow:<\/p>\n<p><code>$ phpcf --target 7.1 src<\/code><\/p>\n<p>And here the usual possible output:<\/p>\n<p><img decoding=\"async\" alt=\"phpcf output\" class=\" lazy\" src=\"https:\/\/thevaluable.dev\/images\/2018\/03\/screenshot-20180309-065821.png\" data-lazy=\"true\"\/><\/p>\n<h3 id=\"phpmetrics\"><span class=\"ez-toc-section\" id=\"PhpMetrics\"><\/span>PhpMetrics<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Last but not least: if you are a metric lover, PhpMetrics will be your daily fix. It will output <em>a lot<\/em> of metrics about your project.<\/p>\n<p>You need to type something like that:<\/p>\n<p><code>$ phpmetrics --report-html=myreport.html src\/<\/code><\/p>\n<p>The HTML output will be full of diagrams and numbers.<\/p>\n<p>Now keep in mind that metrics are not necessarily the absolute truth, it really depends on your project. I won\u2019t explain everything this tool can output here, maybe in a future article?<\/p>\n<p>My experience showed me that <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/thevaluable.dev\/fighting-software-entropy\/\">software entropy<\/a> is a real thing. The more you will modify your application, the more the application has chances to break. Your application will inevitably become more complex.<\/p>\n<p>These PHP code quality tools can definitely help you in that matter. Since your codebase will be more and more buggy, refactoring is a necessity and these tools can show you where to start. On a daily basis, they can give you good advice on all these little things you need to take care of to keep your codebase healthy.<\/p>\n<p>Keep in mind though: they are a good <strong>complement but not a replacement for a solid test suite<\/strong>, beginning by good unit tests.<\/p>\n<p>Do you use other tools than the ones described here? Do you use them differently? Don\u2019t hesitate to help the community by sharing your experience.<\/p>\n<hr\/>\n<p><em>This article was written by\u00a0<a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/thevaluable.dev\/page\/about\/\">Matthieu Cneude<\/a>\u00a0and was originally published on\u00a0<a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/thevaluable.dev\/\">The Valuable Dev<\/a>, a blog focusing on the important and timeless concepts in software development. You can read the piece <a rel=\"nofollow noopener noreferrer\" target=\"_blank\" href=\"https:\/\/thevaluable.dev\/code-quality-check-tools-php\/\">here<\/a>.\u00a0<\/em><\/p>\n<p class=\"post-article-read-next\">\n    <b>Read next:<\/b><\/p>\n<p>        Digital note-taking takes a step forward with the SyncPen    <\/p><\/div>\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 noreferrer\">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 noreferrer\">Technology category.<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<p><span style=\"color: black;\"><a style=\"color: #ff9900;\" href=\"https:\/\/thenextweb.com\/syndication\/2020\/10\/18\/php-code-quality-tools-to-check-and-improve-your-code\/\" target=\"_blank\" rel=\"noopener noreferrer\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;#PHP code quality tools to check and improve your code&#8221; They were coded by Dave, your colleague developer. The classes are full of formatting errors, poor indentation, and weird one letter variables. There are so many dependencies you need to scroll down for minutes to escape the bloated constructor. Shacking, you open the unit tests&#8230;<\/p>\n","protected":false},"author":1,"featured_media":92017,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/img-cdn.tnwcdn.com\/image\/tnw?filter_last=1&fit=1280,640&url=https:\/\/cdn0.tnwcdn.com\/wp-content\/blogs.dir\/1\/files\/2020\/10\/1-6.jpg&signature=e79b98d5e181c9a3b14ed94b16ea4513","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[76253,76254,73308,70759,73504],"class_list":["post-92016","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology","tag-code","tag-codebase","tag-programming-tool","tag-tech","tag-web-content"],"_links":{"self":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/92016","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=92016"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/92016\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/92017"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=92016"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=92016"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=92016"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}