Must have tools to improve the quality of your PHP Code

In this article, I want to showcase you a number of essential proper testing tools that will aid to improve the quality of your PHP code.

Prerequisites

I assume that you are familiar with PHP 7.1 syntax, you use Composer and follow PSR-4 for autoloading and PSR-1 & PSR-2 for coding standards.

Build Tool

I am going to use a few different testing tools, so it’s good to have something that would run them all with just one script. PHing provides us with an excellent solution to this problem. PHing is similar to Apache Ant and allows to easily automate tasks using XML configuration.

You install it by running

composer require --dev phing/phing

Then you create some basic build.xml file in your project’s root directory.

<?xml version="1.0" encoding="UTF-8"?>
<project name="MyProject" default="run">
</project>

In next steps we will add some targets to run by PHing.

Static Code Analysis

I recommend the first thing you can do to improve your code quality at almost no cost is setting up static code analysers. They will check your code for mistakes by just reading it without really running it. It’s like having a code-review done in a few seconds by a robot.


PHPCS (PHP Code Sniffer)

phpcs – PHP Code Sniffer: Code is much more maintainable when it is written using proper styling. Everybody knows that (if you don’t, you should at least start reading “Clean Code” by Robert C. Martin). PHP CodeSniffer is a very good tool to output the coding standards violations you have in your codebase. This tool automates this task.

You can install it by running

composer require --dev squizlabs/php_codesniffer

Then add a target for running it in build.xml. Your build.xml should now look like this:

<?xml version="1.0" encoding="UTF-8"?>
<project name="MyProject" default="run">
    <target name="phpcs" description="Check code style with PHP_CodeSniffer">
        <exec executable="bin/phpcs" passthru="true" checkreturn="true">
            <arg line="--standard=PSR1,PSR2 -extensions=php src"/>
        </exec>
    </target>
    <target name="run" depends="phpcs"/>
</project>

Now you can run ./bin/phing and phpcs will automatically check if you have any mistakes against PSR-1 and PSR-2 coding standards.

Many frameworks, like Symfony, define their own rules for code style and thanks to the community we can have those checked automatically as well. Eg. if you are using Symfony framework, check https://github.com/leaphub/phpcs-symfony2-standard for information on how to check Symfony’s standards with PHPCS. Two command line scripts can be used: phpcs to output the actual coding standards flaws and phpcbf which can fix some errors for you.

Example output of a wrongly formatted file:

No alt text provided for this image
No alt text provided for this image

As you can see phpcbf can fix automatically two errors for you by typing:

$ phpcbf src/Model/SuperModel.php


PHPCPD (Copy/Paste Detector)

 PHPCPD – PHP Copy/Paste Detector. Duplicated code is bad, everybody knows it. Sometimes we create such code by mistake and we never notice it. Sometimes we do because we are lazy. It’s better to be equipped with a tool which will prompt about this at build time.

 You install it by running

composer require --dev sebastian/phpcpd

Then you just add target to your build.xml:

<target name="phpcpd" description="Generate pmd-cpd.xml using PHPCPD">
    <exec executable="bin/phpcpd" passthru="true">
        <arg line="src"/>
    </exec>
</target>
...
<target name="run" depends="phpcs,phpcpd"/>


PHPMD (PHP Mess Detector)

PMD will display the possible bugs and misuses of the language in your application.

Here how to do the magic:

$ phpmd vendor/ 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.

Example output of a duplicated code check run on vendors directory:

No alt text provided for this image

If you want to output the errors in a file? Easy:

Example output of a duplicated code check run on vendors directory:

$ phpmd src/ html cleancode --reportfile ~/phpmd.html

If you choose xml as output you will have more information regarding the rule set as following:

No alt text provided for this image

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.


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. If you are starting your project from scratch you should take a look at Phan – it’s a really powerful code analyser which will make your code beautiful. Check it out at https://github.com/phan/phan

You install it by running

composer require --dev phan/phan

Then create a config file .phan/config.php with content:

<?php
return [
   'target_php_version' => '7.1',
   'directory_list' => [
       'src',
       'vendor/symfony/console',
   ],
   "exclude_analysis_directory_list" => [
       'vendor/'
   ],
];

Also create phan target in your build.xml:

<target name="phan" description="Check code with phan">
   <exec executable="bin/phan" passthru="true" checkreturn="true"/>
</target>
...
<target name="run" depends="phpcs,phpcpd,phan"/>

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:

No alt text provided for this image

Phan is magical – it reads your whole code and performs multiple checks on it, including comparing phpdoc declarations with real usage of variables, methods, classes, etc. You can check the whole list of features on https://github.com/phan/phan#features


PhpCodeFixer

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 install it by running:

composer global require friendsofphp/php-cs-fixer

you can create a config file as explained here https://github.com/FriendsOfPHP/PHP-CS-Fixer

For example:

<?php
return PhpCsFixer\Config::create()
->setRules([
    '@Symfony' => true,
    'array_syntax' => ['syntax' => 'short'],
]);

If you've created a config file, you have to configure its path in the plugin's settings.

In Menu -> Preferences -> Package Settings -> PHP CS Fixer -> Settings - user

{
    "config": "/path/to/.phpcsfixer"
}

When using multiple projects with different configurations, it's possible to configure the path relative to the Sublime project folder:

{
    "config": "${folder}/.php_cs.dist"
}

It's also possible to specify multiple config paths. In that case, the first readable file is used:

{
    "config": [
        "${file_path}/.php_cs",
        "${file_path}/.php_cs.dist",
        "${folder}/.php_cs",
        "${folder}/.php_cs.dist",
        "/path/to/.phpcsfixer"
    ]
}


You can precise the version of PHP you work with and your main codebase directory as follow:

$ phpcf --target 7.1 src

And here the usual possible output:

No alt text provided for this image


PHPUnit and the CRAP metric

Probably most common way of testing software is writing unit tests. They serve the purpose of testing particular units of the code, basing on the assumption that everything else works as expected.

In order to be able to write proper unit tests our code should follow some basic design rules. We should especially focus on SOLID principles.

In unit tests we really want to replace all dependant services with mock objects, so we only test one class at a time. But what are mocks? They are objects implementing the same interface as some other object, but behaving in a controlled way. For example, let’s say we are creating a price comparison service and we utilize another service to fetch current exchange rates. During testing our comparator we could use a mock object configured to return specific rates for specific currencies, so our test would neither be dependant nor call the real service.


You can it install by running:

composer require --dev phpunit/phpunit

Then, if you are using PHing configured in first part of the article, you add build target to build.xml:

 <target name="test">
  <phpunit printsummary="true" haltonfailure="true"><batchtest><fileset dir="./tests"><include name="*Test.php"/></fileset></batchtest></phpunit></target>
...
<target name="run" depends="phpcs,phpcpd,phan,phpunit"/>

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.

No alt text provided for this image


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 install it by running:

composer global require dephpend/dephpend:dev-master


You can use it as follow:

$ dephpend metrics src/

This output will then appear magically:

No alt text provided for this image

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.


Configuring PHPStorm

Here are some handly links to Jetbrain’s documentation:

要查看或添加评论,请登录

Mark Coley的更多文章

  • How browsers resolve competing CSS styles

    How browsers resolve competing CSS styles

    We style our websites using CSS, which stands for Cascading Style Sheets. But what does Cascading really mean? The CSS…

  • Information Security - Slack Initiates Mass Password Reset

    Information Security - Slack Initiates Mass Password Reset

    The popular workspace collaboration platform Slack is in the middle of asking tens of thousands of users to reset their…

  • OWASP- Top 10 Vulnerabilities in web applications

    OWASP- Top 10 Vulnerabilities in web applications

    Introduction OWASP (Open web application security project) community helps organizations develop secure applications…

  • A Guide to Improving DevOps Performance

    A Guide to Improving DevOps Performance

    There are two aspects of the DevOps services - ensuring continuous software development, implementation and delivery…

  • MySQL Optimization Tips

    MySQL Optimization Tips

    Benefits The primary advantage of identifying performance driving factor for database allows you to avoid…

    1 条评论

社区洞察

其他会员也浏览了