Gives metrics about PHP project and classes.
- Installation
- Bubbles chart and complete report
- Informations about OOP model
- Jenkins and PIC integration
- Metrics
- metric: Halstead complexity
- metric: Maintenablity index
- metric: Lines of code
- metric: McCaybe Cyclomatic complexity number
- metric: Myer's Interval
- metric: Card and Agresti's System complexity
- metric: Coupling and instability
- metric: Lack of cohesion of methods (LCOM)
- Use it in your code
wget https://github.com/Halleck45/PhpMetrics/raw/master/build/metrics.phar
php metrics.phar <folder or filename>
Will output:
## Bubbles chart and complete report
If you want to get the summary HTML report (with charts):
php ./bin/metrics.php --report-html=/path/of/your/choice.html <folder or filename>
You can change the depth of the summary report with the --level=<value>
option.
## Jenkins and PIC integration
You can easily export resut to XML with the --report-xml
option:
php ./bin/metrics.php --report-xml=/path/of/your/choice.xml <folder or filename>
You will find a tutorial to integrate PhpMetrics report to Jenkins here (in French).
### Read report
- Each file is symbolized by a circle
- Size of the circle represents the Cyclomatic complexity
- Color of the circle represents te Maintenability Index
- Move your cursor on a circle to have details
Large red circles will be probably hard to maintain.
### Example : Symfony2 Component
### Example : Zend Framework 2
# Metrics
## Lack of cohesion of methods
This object oriented indicator measure how well the methods of a class are related to each other. This metric indicates roughly the number of responsabilities of one class (and is correlated to the Single Responsability Principle)
If there are 2 or more components, the class should probably be split into so many smaller classes.
This indicator provides:
- Program length (N)
- Vocabulary size (n)
- Program volume (V)
- Difficulty level (D)
- Effort to implement (E)
- Time to implement, in seconds (T)
- Number of delivered bugs (B)
N = N1 + N2
n = n1 + n2
V = N * log2(n)
D = ( n1 / 2 ) * ( N2 / n2 )
E = V * D
T = E / 18
B = ( E ** (2/3) ) / 3000
## Maintenability index
According Wikipedia, Maintainability Index is a software metric which measures how maintainable (easy to support and change) the source code is. The maintainability index is calculated as a factored formula consisting of Lines Of Code, Cyclomatic Complexity and Halstead volume.
MIwoc: Maintainability Index without comments
MIcw: Maintainability Index comment weight
MI: Maintainability Index = MIwoc + MIcw
MIwoc = 171 - 5.2 * ln(Halstead Volume) - 0.23 * (Cyclomatic Complexity) - 16.2 * ln(Lines of Code))*100 / 171
MIcw = 50 * sin(sqrt(2.4 * perCM))
MI = MIwoc + MIcw
## McCaybe Cyclomatic complexity number
According Wikipedia, indicate the complexity of a program. It is a quantitative measure of logical strength of the program. It directly measures the number of linearly independent paths through a program's source code.
Method 1:
CC = E - N + 2P
P: number of disconnected parts of the flow graph (e.g. a calling program and a subroutine)
E: number of edges (transfers of control)
N: number of nodes (sequential group of statements containing only one transfer of control)
method 2:
CC = number of decisions points in code
Coupling use two metrics:
- Afferent coupling (CA): number of classes that your classes affects
- Efferent coupling (CE) : number of classes used by your class
Instability concerns the risk of your class, according coupling:
I = CE / (CA + CE)
loc: lines of code
lloc: logical lines of code
cloc: Number of comment lines of code
# Use it in your code
Halstead
$halstead = new \Hal\Halstead\Halstead(new \Token\TokenType());
$rHalstead = $halstead->calculate($filename);
var_dump($rHalstead);
McCabe
$mcCabe = new \Hal\McCaybe\McCaybe();
$rMccabe = $loc->calculate($filename);
var_dump($rMccabe);
PHPLoc
$loc = new \Hal\Loc\Loc();
$rLoc = $loc->calculate($filename);
var_dump($rLoc);
Maintenability Index
$maintenability = new \Hal\MaintenabilityIndex\MaintenabilityIndex;
$rMaintenability = $maintenability->calculate($rHalstead, $rLoc);
var_dump($rMaintenability);
OOP Extractor
Extracts OOP model of files, and map classes and files:
$extractor = new Extractor();
$rOOP = $extractor->extract($filename);
var_dump($rOOP);
Coupling
Calculate coupling.
// build class map
$classMap = new ClassMap;
foreach($files as $filename) {
$extractor = new Extractor();
$rOOP = $extractor->extract($filename);
$classMap->push($filename, $rOOP);
}
// coupling
$coupling = new Coupling;
$couplingMap = $coupling->calculate($classMap);
$rCoupling = $couplingMap->get('\My\Namespace\ClassName');
var_dump($rCoupling);
If you want to work with files instead of classes:
// reuse code above, then
$fileCoupling = new FileCoupling($classMap, $couplingMap);
$rCoupling = $fileCoupling->calculate('/path/to/file.php');
var_dump($rCoupling);
In order to run unit tests, please install dev dependencies:
curl -sS https://getcomposer.org/installer | php
php composer.phar install --dev
Then, to run the test suite:
./vendor/bin/phpunit -c phpunit.xml.dist
# Author
- Jean-François Lépine <blog.lepine.pro>
# Licence
See the LICENCE file