PHP Code Quality – Realistic NPath Complexity Over Sixteen Octillion

code-qualityPHP

I have just measured a large chunk of PHP code (1153 lines) using PHPMD (http://phpmd.org/) and it tells me the code has an NPath complexity of 16244818757303403077832757824.

That looks like a crazily big number to me, suggesting that perhaps PHPMD has broken in some way. Is it even possible for a piece of code written by humans to have such a high NPath complexity? The cyclomatic complexity is 351.

Two possibly important details –

  1. This was procedural code, mixed in with HTML, and PHPMD will only measure object-oriented code. To get around this, I wrapped the whole file in a class with a single function – this is representative of how it's used.

  2. The file consists of a series of nested switch statements, and inside those there are lots of if..else statements – so it's certainly pretty complicated.

Edit

I want to clarify that I'm not questioning whether PHPMD is lying to me. I know that the code is an awful mess, I just wonder if it's possible for any code to be really that bad. It seems like the answer is yes, it's very possible.

Best Answer

This is entirely possible. Let's assume we have 35 switch-case constructs of 10 cases each, which would give us a rough cyclomatic complexity of 350 when each switch occurs one after the other. The first switch gives us 10 paths. The second switch gives us another independent 10 paths, so that we have 10·10 paths until here. With the third switch, we get 10·10·10=10³ paths, and so on until we get 1035 paths in total! This is even higher than your result of 1.6·1028 paths, which is probably due to a different branching factor, and due to nested control flow statements which reduce the number of paths through your code.

As a worst case scenario for a given cyclomatic complexity c, we can have a maximum of 2c acyclic paths through the code (here: 2351 = 4.6·10105).

The tool's judgement is clear: the code you are dealing with is a convoluted, untestable, and unmaintainable mess. Consider splitting it into smaller, independent functions, and abstracting away repetition. E.g. you could separate HTML generation from the main logic of your PHP script.