Calculating the complexity of PHP

Not only is the question of calculating the cyclomatic complexity showing up in our mailinglist and bugtracker, it is also showing up on other mailing-lists! This shows that the time has come to introduce a solution to this problem based on PHP-Front:
(indeed, yet another creative name :)

This tool is added to the PHP-Tools project as of revision 421. The implementation is not very big, the code that does the actually work is about 20 lines, but it relies heavily on PHP-Front. Thats where libraries are for, right?

So what does it do? The tool basically counts the number of branches that exists in your code. This is done for the main-flow and separately for each function. By default, each function (and the main-flow) starts with a complexity of 1 since there is always a minimal path through the code. For each construct that introduces a branch within the control-flow, for example if-, for- and while-statements, the complexity is increased by 1. In the end the number represents the number of paths that exists from the start until the end of the function (or main-flow). The higher the number, the more difficult it becomes to understand and test the block of code.

The complete list of constructs that increase the complexity can be found at the bottom of the source. I think that the list is understandable, even though it uses 'Sorts'. If this is not the case please let me know, and I will put up a list using php-syntax.

As you can see the complexity is increased by logical operators. This is because the semantics of the code:
if($foo || $bar){ //code }
is equal to the following code:
if($foo) {  
} elseif($bar){
in other words, we can rewrite a logical expression as a set of if-else-statements. Since they share the same semantics they should share the same complexity.

One last note, the tool actually calculates the minimum complexity of a function. Even though php-cyco is capable of including files, using the usual --*-inclusion flags, it might encounter situation in which it cannot resolve a filename. In this case the calculated complexity can be lower than the actual complexity because the included file could contain some of the complexity-increasing constructs.

So if you are curious to know which function within your php-project has the largest complexity I suggest you download the PHP-Tools project and start analyzing your code!

Please let me know if you have any comments or feedback.

No comments: