Unexpectedly, I didn’t find information in Russian about such a great HipHop feature as
static code analysis for PHP, and therefore see a review that Rasmus’s presentation on DevConf gave me.
And how is it at all?
Static code analysis is a very useful thing, because otherwise we will not see the error until the function containing it is called. How does HipHop do this? It translates PHP in C ++!
Thus, we are able to statically analyze C ++ code, which, in general, hasn't surprised anyone for a long time, and then apply this information to PHP (of course automatically).
')
So, let's begin.
Environment
For tests, I picked up a new server Centos 5.8 x64
HipHop installed on it
rpm -ivh http://epel.osuosl.org/5/x86_64/epel-release-5-4.noarch.rpm rpm -ivh http://dl.iuscommunity.org/pub/ius/stable/Redhat/5/x86_64/ius-release-1.0-10.ius.el5.noarch.rpm rpm -ivh http://pkg.tag1consulting.com/hphp/x86_64/hphp-release-1.0-2.el5.noarch.rpm yum install hiphop-php -y
Added an environment variable (for some reason, the RPM itself did not do this)
export HPHP_HOME=/usr/lib64/hphp
And created a folder for reports
mkdir /var/reports export SRC_DIR=/var/www/ export OUTPUT_DIR=/var/reports
Now the environment is ready and you can begin to experiment.
Preparation for analysis
First you need to make a list of files that we will analyze.
I analyzed one test file, but if you want to check your entire project at once, you can do this:
find $SRC_DIR -name '*.php' > $OUTPUT_DIR/files.txt
After the file list has been compiled, it is necessary to feed it to HipHop with the following parameters:
--target = analyze - why did we call HipHop?
--input-list = $ OUTPUT_DIR / files.txt - list of files to check
--input-dir = $ SRC_DIR - where are the files to be checked?
--output-dir = $ OUTPUT_DIR - where to save the test results?
--gen-stats = 1 - create a file with statistical information about errors
--log = 3 - log level, which is displayed in the console (3 - optimal)
--force = 1 - ignore errors found and continue analysis
--parse-on-demand = 0 - do not touch files that are not in the list
Analysis
Go!
$HPHP_HOME/src/hphp/hphp --input-list=$OUTPUT_DIR/files.txt --input-dir=$SRC_DIR --output-dir=$OUTPUT_DIR --gen-stats=1 --log=3 --force=1 --parse-on-demand=0 --target=analyze
By the way, if in the process of parsing you get errors like
"Unable to parse file: /var/www/user.php\n (Line: 14, Char: 23):
This means that there is a syntax error in the file and it does not work at all, so pay attention to it!
Analysis result
When hphp has completed its work (and this is amazingly fast!), Two files appear in the / var / reports / folder:
CodeError.js and
Stats.jsThe content of the latter is interpreted like this:
Array ( [FileCount] => 125 [LineCount] => 11784 [CharCount] => 433255 [FunctionCount] => 350 [ClassCount] => 17 [TotalTime] => 0 [AvgCharPerLine] => 36 [AvgLinePerFunc] => 33 [SymbolTypes] => Array ( [Array] => 64 [Boolean] => 43 [Double] => 30 [Int32] => 68 [Int64] => 2208 [Numeric] => 23 [Object] => 11 [Object - Specific] => 58 [Primitive] => 31 [Sequence] => 2 [String] => 221 [Variant] => 1458 [_all] => 4217 [_strong] => 2703 [_weak] => 1514 ) [VariableTableFunctions] => Array ( ) )
In my opinion, everything is clear and there is nothing to explain.
But
CodeError.js should be considered in more detail.
It is also in JSON format and contains information about all the errors that HipHop found.
And he is looking for the following types of faults:
- Missing files for require \ include
- Calls to undefined functions / methods
- Appeal to indefinite variables, classes, constants
- Override constants
- Same argument names in function definition
- Required arguments after optional in the function definition
- Insufficiency \ redundancy of arguments when calling a function
- Code that will not be executed under any circumstances
- Methods and functions that return void
- Using $ this in static methods
And much moreBadPHPIncludeFile, PHPIncludeFileNotFound, UnknownClass, UnknownBaseClass, UnknownFunction, UseEvaluation, UseUndeclaredVariable, UseUndeclaredGlobalVariable, UseUndeclaredConstant, UnknownObjectMethod, InvalidMagicMethod, BadConstructorCall, DeclaredVariableTwice, DeclaredConstantTwice, BadDefine, RequiredAfterOptionalParam, RedundantParameter, TooFewArgument, TooManyArgument, BadArgumentType, StatementHasNoEffect, UseVoidReturn, MissingObjectContext, MoreThanOneDefault, InvalidArrayElement, Invalidoption, InvalidOne, ReligionToothMedium, ReligionToothsmithing
JSON in the file is an array, in the first element of which the number of errors found is indicated, and in the second, the list itself is sorted into groups.
In order to see all the errors in a readable format, you can use the
script from Patrick Allaert or write something beautiful and with buns =)
Example
There is such a terrible file
<?php ini_set('display_errors', 0); require("$a.php"); define('CONSTANT', 1); function myfunc($arg1 = 'optional', $arg2) { echo $missing_var; } define('CONSTANT', 1);
Run the test on it, and then try to see the errors
./CodeErrorFormatter.php /var/report/CodeError.js
Oops, PHP gave me a getopt error, but I just entered the path to the file with handles and got the following output:
CodeErrorFormatter 1.1.0 by Patrick Allaert.
UseUndeclaredVariable
================================================================================
/var/www/index.php
9:9 -> 9:21 details: $missing_var
4:9 -> 4:11 details: $a
DeclaredConstantTwice
================================================================================
/var/www/index.php
12:0 -> 12:21 details: define('CONSTANT', 1)
RequiredAfterOptionalParam
================================================================================
/var/www/index.php
8:16 -> 8:41 details: $arg2
As you can see, for each error, the type, the file address, the name of the unnatural function \ variable, its string and position in the file are indicated. What to do next with them - think for yourself (either an automatic bug report, or correct it yourself, or something else).
Conclusion
In general, the topic of static analysis for PHP is not new, but there are
few Russian-language articles on this topic and none of them touches HipHop.
I urge everyone to just try it. Of course, you should not think that it is a “silver bullet”, but the analysis shows those things that are very difficult for a person to catch.
I hope this review will benefit someone, or maybe someone else will write a visual to test the code from the browser nicely?
===================
Facebook
HipHop Project
CodeError.js
CodeFormatterRasmus Lerdorf's presentation at DevConf 2012
talks.php.net/show/devconf/ - must-see!