📜 ⬆️ ⬇️

Static analysis of PHP code using HipHop

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
# uname -a Linux TEST 2.6.18-308.8.1.el5xen #1 SMP Tue May 29 15:38:25 EDT 2012 x86_64 x86_64 x86_64 GNU/Linux 


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.js

The 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:



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 CodeFormatter
Rasmus Lerdorf's presentation at DevConf 2012 talks.php.net/show/devconf/ - must-see!

Source: https://habr.com/ru/post/145683/


All Articles