PHP
Article

Visualize Your Code’s Quality with PhpMetrics

By Bruno Skvorc

We had been looking into code quality checking tools for a while here on SitePoint – most recently in a series on Jenkins, but none of those could do what a project I’ve only recently found out about can.

PhpMetrics uses D3 and some sophisticated analysis algorithms to scan your application’s code and output intricate reports about it.

phpmetrics-maintenability

Installing and Using PhpMetrics

It’s a bit hard to talk about it without seeing a proper example, so let’s install and run it, then explain every part.

Environment

To test it, we’ll need an isolated environment. As usual, we’ll be using our trusty Homestead Improved Vagrant box, making sure all readers have the same environment to test on.

Installing PhpMetrics

Like with any modern PHP project, installing is very simple. We’ll install it globally, making it available to all projects on the machine.

sudo composer global require 'halleck45/phpmetrics'

Fetching the Code

We’ll test PhpMetrics on two code-heavy projects: Laravel and Symfony, in framework, not project form. That means we won’t be using the create-project command from Composer, but the bare source of each framework.

git clone https://github.com/symfony/symfony symframe
git clone https://github.com/laravel/framework lframe

We do this to avoid any and all dependency testing, and to stay away from non-framework related code.

Using PhpMetrics on a Code-Heavy Project

Now that we’ve got the projects downloaded, let’s run PhpMetrics on them.

mkdir Laravel
mkdir Laravel/public
phpmetrics --report-html=/Laravel/public/report_symfony.html symframe
phpmetrics --report-html=/Laravel/public/report_laravel.html lframe

Never mind the fact that we’re using “Laravel” folders here for the reports, they’re just Homestead’s defaults and we can just reuse them for our small example to reduce the configuration steps. This lets us easily access the reports at the following URLs:

homestead.app:8000/report_symfony.html
homestead.app:8000/report_laravel.html

Here’s what Laravel’s report gets us:

01

and here’s what we get by analyzing Symfony:

02

Analysis

PhpMetrics offers a plethora of metrics. Let’s demystify those circles and graphs and find out what we’re looking at!

Color coding

As per the how to read the report guide, we can immediately notice Symfony is a bit heavy on the orange-red side, while the grass is greener on Laravel’s side. One important thing to notice, however, is how many more files Symfony contains as opposed to Laravel – you can see this clearly by comparing the density of circles.

PhpMetrics was built with color blind people in mind, so the “color blind” checkbox changes the colors in the circles from green, yellow, orange to stripes at different angles:

03

The color coding is the first aspect you can look at, and the first place to look for hints at problems.

Cyclomatic Complexity and Maintainability Index

The circles, when looked at carefully, represent the CC and MI, and, as the documentations says, large red circles will probably be very hard to maintain.

Both are easily Googleable, but let me spare you the wiki skimming and explain them in layman terms.

Cyclomatic Complexity essentially measures the number of paths to take through a script’s logic. The more paths can be taken, the more complex a file is. A good way to avoid high CC is to make sure your code is as modular and atomic as possible, which becomes second nature when you’re following SOLID principles.

Like Wikipedia says, the Maintainability Index is calculated with certain formulae from lines-of-code measures, McCabe measures and Halstead complexity measures. Lines-of-code measures are self-explanatory – literally counting the number of lines of code. McCabe measures, much as it sounds like a USA political promise, is actually just another name for Cyclomatic Complexity. Halstead complexity is a set of formulae which try to look at the syntax of the file’s code and deduce attributes such as difficulty, code vocabulary, effort, etc. If you’re interested in the specific formulae, check the Wikipedia article out.

Taking all these into effect, the circles are sized and color coded, indicating the sum of all standard metrics for code complexity and maintainability.

Tables

If you’d like to see all the data in a more tabular form, you can check the “Explore” tab in the report file:

05

This table will include all the above and more – from lines of code to number of classes and more – both per folder and file. This incredibly detailed report is what you should refer to when looking for highly precise information about your code all in one place.

Custom Chart

The middle area in the report’s overview screen contains the custom chart.

06

In the example above, we’re comparing the ratio of CC (mentioned above) and Lcom (lack of cohesion in methods) for each file, but you just as easily switch out the X or Y axis value for something else. For example, here’s a comparison of Difficulty per Lines of Code – you can notice that Laravel’s trend is somewhat proportional – with more LoC, more Difficulty is assumed, while Symfony tends to be all over the place with certain files.

07

For example, the Symfony file BinaryNode.php has a very high difficulty for its 150 lines of code, while Response.php in its whopping 1275 lines of code has a very low difficulty score. Explore the files that produce curious results, and see what you can find out from these insights.

Abstractness / Instability

This chart is very well explained here, but in a nutshell, the average diagonal line is called the balance line, or, the Main Sequence. The goal is to have your classes as close to the line as possible, because this means they’re balanced between being abstract and concrete enough. I do encourage you to read the content at the link above – it’s an easy read and should clear things up.

For some reason, I couldn’t get A/I to work on my local environment properly with Laravel and Symfony.

Evaluation

Evaluation is a web chart which takes the average of various attributes of your entire project, compares these numbers to the standard of other projects the tool has learned so far, and then superimposes your values over those. This is purely cosmetic and carries no real value, as the disclaimer on the Evaluation page says.

08

09

While the tool believes both frameworks are equally maintainable, its not such a shocking conclusion here that Laravel is more new-developers friendly and far more simplistic in algorithms, not to mention less voluminous.

Relations Map

The relations map is more useful for smaller projects – it lets you see the relations between classes. If a class extends or implements another, the relations map will show it. Due to the brutal number of classes in both of these projects and their connections, the map is less than useful here – in fact, it doesn’t even load for Symfony for me. But if you go ahead and try it out on a test project with a smaller number of classes, you’re bound to see the benefits.

Repartition

Finally, the repartition screen sums up all the data in a format much simpler than the Explore tab, listing out some totals only:

Symfony:

10

Laravel:

11

Comparison Results

So, what’s to be concluded from these results? Without looking into it too much, we can easily conclude that:

  1. Laravel is more friendly to new developers, simpler in algorithms and less bloated in file size.
  2. Laravel is drastically more lightweight. Symfony has at least three times more anything than Laravel – methods, classes, files, lines of code… it’s three times more massive.
  3. Symfony is more relatively complex (middle column on the Repartition screen)
  4. Laravel is much more stable in complexity across files – they have the same ratio of difficulty and lines of code, while Symfony can vary wildly.
  5. Symfony could use some work in making some of the more complex files more atomic – the big red circles are taking over its circle graph.

See what else you can learn by playing with the charts and data yourself, then let us know!

Conclusion

PhpMetrics is another in a long line of code quality analyzers, but one with a twist. Rather than looking at the typical code standard issues we’ve come to expect, it looks at a whole set of new attributes and explains your code to you in beautiful math, as soon as you learn its language. To find out what each attribute means, consult the chart.

Will you be using PhpMetrics to scan your projects? Would you install it into your IDE? Is it something you might see as a permanent addition to your CI process? Let us know your thoughts in the comments!

Free Guide:

7 Habits of Successful CTOs

"What makes a great CTO?" Engineering skills? Business savvy? An innate tendency to channel a mythical creature (ahem, unicorn)? All of the above? Discover the top traits of the most successful CTOs in this free guide.

Comments
freakyrag

PhpMetrics seems to be relatively new. Does it use PHP_Depend or does it implement its own code analyzer? There is not a lot of information available on this tool.

As of now I use SonarQube as Continuous Inspection tool. In combination with Jenkins it is absolutely invaluable. SonarQube just needs the report XML files from PhpUnit, PHP_Depend etc. If PhpMetrics has an XML report file it should be possible to integrate it with SonarQube in order to have tracking of code quality metrics over time.

swader

According to a basic repo search, there's no reference of PHP_Depend.

Halleck45

Hi,

First, congratulations @swader for this article which is very comprehensive !

Does it use PHP_Depend or does it implement its own code analyzer?

PhpMetrics doesn't use PhpDepend, and has his own parser. My first idea was to create a new renderer for PhpDepend, but the philosophies of these tools are not the same, and many metrics essential to me are not provided by PhpDepend

If PhpMetrics has an XML report file it should be possible to integrate it with SonarQub

PhMetrics can interact with Sonar (or Jenkins) with the --report-xml and --violations-xml parameters.

There is not a lot of information available on this tool

I hope it will come : my english is really poor, and I need help for documentation and translation from French. Any help is welcome smile

swader

@Halleck45 great to have you here, welcome to the forums!

Your English isn't bad at all judging from what I've seen so far, but I think you can count on the community's help, even in terms of translating to other languages - just try and make a good "contributing to documentation" guide section and I'm sure we'll get right on it. Is the documentation on Github, too?

MatsSvensson

Based on the info here and on the project-site, i have zero idea how to use this.

For example:

*On the "download"-page, there is no download-link, just something that looks like a bunch of DOS-commands.

  • The "about"-page is just an exact copy of the useless "download"-page.

  • The "documentation" immediately assumes that you already know how to use the thing.
    No trace of any "get started", or "read me first", etc.

I'm guessing this is some Linux-stuff.
that usually the case, when the builder assumes everyone can read his mind.

JFC...

swader

The installation procedure is described in the post. Get a vagrant box up and running and enter the composer commands.

Composer works on any OS, and is the basis of modern PHP development when using third party libraries and packages. For an introduction, and to make things clear, see this.

JulienTant

It looks like a great tool, easier to install than Jenkins stuck_out_tongue

Just a quick note on the results Laravel/Symfony2; it's important the remind that Laravel uses a lot of Symfony2 components, so I guess if you count them into the codebase of Laravel, which makes sense because Laravel wouldn't work without those components, Laravel would become heavier.

Note to haters : i'm a huge Laravel fan, and creator of Laravel.fr ; so don't get pissed off by my comment ^_^

MatsSvensson

Oh, so It all runs on Perkins, that is a version of Burke, that needs JinXXxx, that has to be installed using Gurkha, that requires a functional "palinDrome"-box, with you can run inside a Charleston-container, that you can compile using "wonderful 2.0" , and so on, etc...?

And who have guessed that such a delicious soup could have been made from only a simple lump of rock?

swader

While I understand your frustration as caused by your failing to keep up, you can also avoid all this, and install it just via the command line with the first three lines on the landing page, into any PHP installation of any type. What I listed above are merely best practices.

wget https://github.com/Halleck45/PhpMetrics/raw/master/build/phpmetrics.phar
chmod +x phpmetrics.phar
mv phpmetrics.phar /usr/local/bin/phpmetrics

If you don't understand this (which is multiplatform, btw - on Windows, you get these commands through Git Bash), I'm sorry but I don't know how to help beyond recommending a "basics of terminal" course because without even the most basic terminal knowledge you'll never get a serious web development job, I guarantee this.

MatsSvensson

Nope.

wget?
chmod?

Like the people behind this tool, you assume that everyone is running the exact same system as you.

Michael_Morris

It doesn't run on OSX Mavericks. A pity.

swader

I do no such thing.

chmod +x means "give execute permission to this file", which, in Windows environments, can be replaced by simply running PhpMetrics as this:

php phpmetrics.phar

Another approach is just opening the file properties window, since you're obviously of the GUI type, and just select "executable file" as a permission, or your system's equivalent.

How do you mean? It works for me.

Michael_Morris

My employer demands I use MAMPP instead of the inbuilt PHP and Apache webserver. That's likely the culprit.

swader

You run your development environment unvirtualized?

Michael_Morris

Unfortunately. I'm not allowed to do otherwise in order "to stay consistent with the other developers"

oddz

That sucks.

I would definitely just run what I want (vb + vagrant). So long as you have sudo no one can really stop you…

Not to mention running nfs w/ php5-fpm with apache 2.4 is blazing fast even for a vm.

It boggles my mind that some people don't understand and/or are to stubborn to use a vm. I quite frankly just won't stand for it – easier to ask for forgiveness than permission.

I'm curious to run this on Magento EE 1.14.1 also Drupal 7 and 8.

swader

You can stay consistent while virtualized. Just install the same versions of PHP / Apache, whatever, into the VM and you have the exact same environment in a VM, and none's the wiser. What's more, you now have a fully destructible and rebuildable environment which you can tear down, rework, and experiment with at will with zero consequences.

Michael_Morris

Preaching to the choir man, preaching to the choir. I'm trying to convince him, but since workstation layouts do get spot checked I'd rather not risk incurring any wrath.

swader

Spot checked? Someone actually sits down at your station and inspects it? Cause other than that, a Vagrant powered VM is undetectable, it just runs in the background after you run a terminal command. To detect it, someone would have to inspect running processes, there's literally no other simpler way.

No offense, but it sounds like you work in some kind of totalitarian regime.

Michael_Morris

No, they're just set in their ways. Also, ad agency - coding is a necessity of the business with the rise of the Internet, not something the uppermost management had in mind when the place was founded. I'll look into Vagrant - if I can come up with something that streamlines processes more than we have than I can certainly get the ear of the powers that be.

By the by, if I was going to do a VM I would like to have one that matches Media Temple's Grid Server environments as closely as possible since that's what the majority of our deployments are to.

And yeah, the admin can ssh into our boxes at any time and has been known to do it.

swader

You can configure a Vagrant box how ever you see fit - install everything and anything on it and then spread it among other devs so everyone has an identical environment. Configure it to match 100% of your production server, and you have even more parity - instant cloned production environment inside the company, but ready for development and experimentation. Screwed up? Just vagrant destroy and vagrant up a new instance, you're back where you started with zero code lost, only a reset environment.

Also SSHing into your environment still won't reveal you running Vagrant. He'd have to get sudo privileges of your computer and scan the process list that way, which, if it's done regularly, is not only detrimental to morale and productivity, but also to your station's performance. Seems like a draconian workplace in any case. The only inspection a dev should be subject to is code review.

Mittineague

Maybe a "personal" zip drive that you could plug in could work?

Michael_Morris

Maybe. I'd rather not end run them though. I like my job.

benfavre

Something is wrong when you have to use MAMP to stay consistent.
Sit down over the weekend, get a vagrant box sorted out for them, show them how wrong they were and get a rise.

MatsSvensson

Nope it does not.

On a system that doesn't have the command "chmod"
chmod +x doesn't mean shit.

Using linux-commands as shorthand for English in tutorials, is a bad idea.

....oh never-mind I give up.
Plus, the useless "flat design" on this new comment-system makes it really hard to see who is responding to what.

I'm sure there is some useful info somewhere here, but i don't have the time to play puzzle-master with it.

swader

You seem like a very angry person.

Michael_Morris

That's not particularly helpful however...

Don't be so pedantic. Surely you've dealt with .nix systems enough to know your OS choice's equivalent command. Unlike computers humans are capable of and expected to be able understand instructions even when somewhat poorly worded, which this wasn't.

Things will get better as more people get used to how this particular system works. As you can see from this post quoting is possible, but it isn't done the same way - it is intuitive since I stumbled into it by accident. You highlight the text you want to quote and a "quote in reply" button will appear - just click it.

Anyway what does the Discourse software have to do with the main topic?

kvashnindmitri

Great tool but it needs to be able to run on huge projects as now it can generate ~20Mb html report in one file and browser will not be able to read it.

swader

While I agree that one may end up in browser deadlock over the size of the report, I think it isn't really supposed to be used for that. I'd rather use it to check my components, modules - not entire suites. Select a part of your app you want to test, and test just that. If you've built your app well, you can probably divide it up into independently testable parts, and this is where this tool really shines, taking an incremental approach to optimization.

ChrisBaker

I signed up for an account simply to ask you to not be so condescending when you help people. It is confusing -- you show altruism by helping, but then randomly treat the people with questions like idiots. I don't get it.

Phrases like these:

your frustration as caused by your failing to keep up

without even the most basic terminal knowledge you'll never get a serious web development job, I guarantee this

You seem like a very angry person.

... completely unhelpful noise to any future reader who finds this thread through Google, and not a very good example of how peers ought to treat each other. Thanks for the article, and thanks for the discussion, but please, can you work on the tenor and tone of the interactions that follow? I'm reading this thread, wincing. Take care.

swader

You're absolutely right, I apologize to you and all future readers who run into this topic. I'll work on my skin thickness and try harder to retain composure in the future.

Recommended
Sponsors
Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in PHP, once a week, for free.