Need to Improve your code quality? First of all, you need to install a code sniffer tool. A code sniffer tool is a program that reads your code and analyzes it. The best known php code sniffers are: PHP Code Sniffer, PHP Mess Detector and phpcs.
This post will help you find a perfect code quality tool for your needs by discussing the most important factors to consider when choosing a static code analysis tool.
PHP Insight
PHP Insight is a pretty good static analyzer which will give you many advice to improve the quality of your code.
You can use it as follow:
phpinsights analyse ./src
First, It will give you a quick overview of your codebase:

Then, it will provide you many advice:

This is a really useful tool. You can as well format the output (JSON
for example) or even create your own rules!
PHPCPD (PHP Copy past detector)
PHPCPD will scan your codebase and output the code duplicated.
You can use it by typing:
$ phpcpd src/
PHPCPD will produce this kind of output:
phpcpd 4.0.0 by Sebastian Bergmann.
Found 1 clones with 44 duplicated lines in 2 files:
- /home/superUser/src/superFile.php:11-55
/home/superUser/src/superFolder/superFile.php:11-55
5.04% duplicated lines out of 873 total lines of code.
Time: 29 ms, Memory: 4.00MB
You can include multiple files instead of a whole directory, exclude some files (or paths) or even output the result in a XML file.
Keep in mind though: if you go to the DRY principle violation hunting in your codebase, keep in mind that code duplication doesn’t necessarily imply DRY violation.
PHPMND (PHP Magic Number Detector)
This tools is pretty specific: it can help you to find magic numbers your code.
The easiest way to use it:
$ phpmnd src/
Here the output:
--------------------------------------------------------------------------------
httpClient/myHttpClient.php:98. Magic number: 200
> 98| if ($response->getStatusCode() != 200) {
--------------------------------------------------------------------------------
service/superClass.php:47. Magic number: 8
> 47| for ($i = 0; $i < 8; $i++) {
--------------------------------------------------------------------------------
You can play with a lot of options, like the possibility to ignore numbers, exclude files / paths / extensions…
dePHPend
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?
dePHPend can help you grandly on that matter.
You can use it as follow:
$ dephpend metrics src/
This output will then appear magically:

As you can see, dePHPend will output the number of Afferent Coupling, the number of Efferent Coupling and display an instability indicator based on them.
In clear:
- No class depend on the class
App\Kernel
- The class
App\Kernel
depends on five other classes
The instability score is high here: this class couple other classes together but is never used!
You can as well output plain text or UML for example.
PHP-CS-Fixer (PHP Coding Standards Fixer)
Let’s begin by the cause of long meetings, hatred behavior and murder impulses: code formatting rules. A great example of Parkinson’s Law of Triviality.
Personally I don’t have any preferences regarding code formatting. What I care about is to have a consistent one:
- It’s easier to read
- It frees your mind for more important questions
PHP-CS-fixer is a simple tools which allows you to format your code automatically. By default PSR-1 and PSR-2 rules are used but you can define your own formatting rules.
With the following command you can format an entire codebase:
$ php-cs-fixer fix src/
You have as well the possibility to preview the modifications without applying them (--diff
option) or you can precise the rules (--rules
option) you want to use.
PHPCS (PHP CodeSniffer)
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: phpcs
to output the actual coding standards flaws, and phpcbf which can fix some errors for you.
You can type for example:
$ phpcs src/
The output will look like that:
FILE: /home/superCoolUser/mySuperProject/src/Model/SuperModel.php
------------------------------------------------------------------------------------------
FOUND 6 ERRORS AND 1 WARNINGS AFFECTING 7 LINES
------------------------------------------------------------------------------------------
2 | ERROR | [ ] Missing file doc comment
14 | ERROR | [ ] Missing @category tag in class comment
20 | ERROR | [ ] Missing doc comment for function __construct()
34 | WARNING | [ ] Line exceeds 85 characters; contains 93 characters
57 | ERROR | [x] Opening parenthesis of a multi-line function call must be the last content on the line
60 | ERROR | [ ] Expected "if (...) {\n"; found "if(...) {\n"
63 | ERROR | [x] Closing parenthesis of a multi-line function call must be on a line by itself
----------------------------------------------------------------------------
PHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------------
As you can see phpcbf can fix automatically two errors for you by typing:
$ phpcbf src/Model/SuperModel.php
You can use the default coding standard shipped with PHP Code Sniffer or you can easily implement your own.
PHPMD (PHP Mess Detector)
PHPMD will display the possible bugs and misuses of the language in your application.
Here how to do the magic:
$ phpmd src/ text cleancode
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 html
or xml
output by replacing the text
option in the command line above.
In this example we use the cleancode
ruleset but you can obviously change it or create your own.
You want to output the errors in a file? Easy:
$ phpmd src/ html cleancode --reportfile ~/phpmd.html
If you choose xml
as output you will have more information regarding the rule set as following:
<file name="/home/mySuperUser/mySuperProject/src/randomClass.php">
<violation beginline="61" endline="61" rule="BooleanArgumentFlag" ruleset="Clean Code Rules" externalInfoUrl="http://phpmd.org/rules/cleancode.html#booleanargumentflag" priority="1">
The method notThatCoolMethod has a boolean flag argument $badBoolean, which is a certain sign of a Single Responsibility Principle violation.
</violation>
<violation beginline="102" endline="104" rule="ElseExpression" ruleset="Clean Code Rules" externalInfoUrl="http://phpmd.org/rules/cleancode.html#elseexpression" priority="1">
The method superMethod uses an else expression. Else is never necessary and you can simplify the code to work without else.
</violation>
</file>
You can see for example the priority of the rules violated. You can then refine your result by using the --minimumpriority
option for example.
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.
Your boss will be so happy he will increase your salary by 200%. Guaranteed.
PHPStan (PHP Static Analysis Tool)
PHPStan is another tool to have in your toolbox. It aims? Output errors like a compiled language would display during compilation. It’s a good complement to PHPMD.
You can run it as follow:
$ phpstan analyse src/ --level=7
You can precise the strictness of PHPStan with the level option. The minimum is level 0
, the maximum level 7
.
To give you an idea here an example of output:
------ -----------------------------------------------------------------------
Line src/MySuperModels/RandomModel
------ -----------------------------------------------------------------------
78 Instantiated class App\Service\Api\InvalidArgumentException not found.
82 Instantiated class App\Service\Api\InvalidArgumentException not found.
93 Method App\Service\Api\Client\ClientInterface::post() invoked with 3 parameters, 4 required.
103 Casting to string something that's already string.
------ -----------------------------------------------------------------------
Like the other tools, you can create your own rules.
PHPUnit and the CRAP metric
This article is not about unit test. I assume you know that unit testing your code is far more important than anything present on this article.
PHPUnit can as well display a very interesting information: the CRAP metric.
CRAP uses the cyclomatic complexity with the code coverage of your code to display what might be the code difficult to change in your application.
More the CRAP index is high, more you code will be considered as “crappy”.
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’t 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.
To display the CRAP metrics, you need to produce a code coverage report:
$ phpunit phpunit --coverage-html ./tempFolder
This will create HTML files in the tempFolder
directory. You can open the index.html
in there and click on the dashboard link to finally contemplate the CRAP indicator.
Journey to the center of the CRAP
Please remember however: code coverage doesn’t mean that your code is well tested. This is an entirely different topic I will keep for another article.
Checking Your PHP Code Deeper
I use the following tools to make sure that the project I work on goes to the right direction. They can help you seeing the big picture.
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.
PhpLoc
PhpLoc is a very good tool to get an idea of the size of a project.
You can execute on your codebase:
$ phploc src
This will output something like that:
Size
Lines of Code (LOC) 61
Comment Lines of Code (CLOC) 0 (0.00%)
Non-Comment Lines of Code (NCLOC) 61 (100.00%)
Logical Lines of Code (LLOC) 23 (37.70%)
Classes 17 (73.91%)
Average Class Length 17
Minimum Class Length 17
Maximum Class Length 17
Average Method Length 3
Minimum Method Length 1
Maximum Method Length 7
Functions 0 (0.00%)
Average Function Length 0
Not in classes or functions 6 (26.09%)
Cyclomatic Complexity
Average Complexity per LLOC 0.26
Average Complexity per Class 7.00
Minimum Class Complexity 7.00
Maximum Class Complexity 7.00
Average Complexity per Method 2.20
Minimum Method Complexity 1.00
Maximum Method Complexity 4.00
Dependencies
Global Accesses 0
Global Constants 0 (0.00%)
Global Variables 0 (0.00%)
Super-Global Variables 0 (0.00%)
Attribute Accesses 7
Non-Static 7 (100.00%)
Static 0 (0.00%)
Method Calls 14
Non-Static 14 (100.00%)
Static 0 (0.00%)
Structure
Namespaces 1
Interfaces 0
Traits 0
Classes 1
Abstract Classes 0 (0.00%)
Concrete Classes 1 (100.00%)
Methods 5
Scope
Non-Static Methods 5 (100.00%)
Static Methods 0 (0.00%)
Visibility
Public Methods 3 (60.00%)
Non-Public Methods 2 (40.00%)
Functions 0
Named Functions 0 (0.00%)
Anonymous Functions 0 (0.00%)
Constants 1
Global Constants 0 (0.00%)
Class Constants 1 (100.00%)
Those data can give you already some clues about the project:
Comment lines of code
is never good. Get rid of it without a second thought.- Too high
Average Class length
is usually not good either. Split the god classes. - Too high
Average Method length
is again not good. For the sack of your colleagues, split them. Cyclomatic complexity
can indicate a bit everything and anything. Trusting something like CRAP might be wiser.- Avoid unnecessary
Dependencies
. Don’t forget thatglobals accesses, constants and variables
can bring you many problems. - Avoid
abstract classes
as much as possible: remember, composition over inheritance.
In a nutshell: a very simple and valuable tool.
Conclusion
Many open source projects, including WordPress and Drupal, use PHP_CodeSniffer to analyse PHP source code. Other frameworks also often come with their own sniffs for different coding standards, such as Symfony! Code Style and the Google C++ Style Guide. The advantage of using a PHP_CodeSniffer is that you’re not confined to one standard-setter’s rules—you can mix and match from a large library of community-created rulesets from all over.