Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Syntax checking pre-source control

Referring to Is there a static code analyzer [like Lint] for PHP files? -- I am looking at how to assess the content of PHP files before they are committed by developers. Whichever solution(s) are appropriate will be triggered via SVN hooks similar to the answer: Is it possible to check PHP file syntax from PHP?

I came across this Automatic Syntax checking of PHP files when checking into SVN which is the angle I'm going for, however ... php -l isn't quite sufficient.

For example, given the code:

if ($foo == 'bar') { 
     echo $foo;
}

This results in:

2012/01/15 02:51:14 [error] 694#0: *164 FastCGI sent in stderr: "PHP Notice: Undefined variable: foo

Compared to:

if (isset($foo)) { echo $foo; }

Some of this comes down to educating coders on best practices. Unfortunately, some don't learn as quickly as others, and the only way to ensure that compliance to coding standards is met, is to reduce what is going into SVN that has been untested or isn't compliant.

From the first link in this question, I have tried:

  • php -l
    • doesn't notify about the problem with $foo
  • phplint-pure-c-1.0_20110223 - PHPLint
    • doesn't notify about the problem with $foo
    if ($foo == 'bar') {
                     \_ HERE

==== /mnt/hgfs/workspace/scratch-pad/phpinfo.php:44: Warning: comparing (unknown) == (string): cannot check the comparison between unknown types

  • phpcs - PHP Code Sniffer
    • doesn't notify about the problem with $foo despite PHP Sanity Check indicating it was the right answer
  • SimpleTest
    • Is very nice, but requires the developers who are writing the bad code to write good unit tests...

All are interesting in their own way, but none are catching these problems that really are only being found at runtime.

Appreciate input / thoughts on this topic.

EDIT

There was one poster who suggested that PHPLint was the right way to go. I thought, OK! Let's try it again given that there is a new version: phplint-pure-c-1.1_20120202:

 <?php
 if ($foo == 'bar') {
     echo $foo;
 }
 ?>

Simple test .................... and, it works and reports 1 error, 1 warning. However, if the following is added BEFORE the if statement:

 <?php
 if (isset($foo) && $foo == 'bar') { echo 'man'; }
 if ($foo == 'bar') { 
     echo $foo;
 }
 ?>

it does not work, and reports 0 errors, 2 warnings.

like image 623
sdolgy Avatar asked Jan 15 '12 11:01

sdolgy


2 Answers

I think this might be a bit hard for an analyser to give warnings about. The code you've given might work with the help register_globals, for example. Also, it might be defined in some other file that is including this file. For those reasons, PHP files should be analyzed with full context of other files for this to be really reliable, and PHP/server configuration should also be either available or defined to the analyzing mechanism.

That said, are you sure phplint doesn't do what you want to?

There is an online validator that you can use to test it. Given the input:

<?php

echo $foo;

the result was:

        echo $foo;
                  \_ HERE
==== 3: ERROR: variable `$foo' has not been assigned
END parsing of test-qBlPWw
==== ?: notice: unused package `dummy.php'
==== ?: notice: unused module `standard'
Overall test results: 1 errors, 0 warnings.

whereas with isset() it didn't find any issues.

EDIT: so for this other test case:

<?php

if ($foo == 'bar') echo $foo;

On Linux Mint 8 the response is:

$ src/phplint test.php 
/home/vadmin/phplint/phplint-pure-c-1.0_20110223/test.php:3: ERROR: variable `$foo' has not been assigned
/home/vadmin/phplint/phplint-pure-c-1.0_20110223/test.php:3: Warning: comparing (unknown) == (string): cannot check the comparison between unknown types
Overall test results: 1 errors, 1 warnings.

and with this:

<?php

$foo = '1';
if ($foo == 1) echo $foo;

it is:

$ src/phplint test.php 
/home/vadmin/phplint/phplint-pure-c-1.0_20110223/test.php:6: ERROR: comparing (string) == (int)
Overall test results: 1 errors, 0 warnings.

so isn't it working like it should, and reporting the problem properly?

like image 179
eis Avatar answered Nov 11 '22 17:11

eis


You might want to combine phpcs (to adhere to coding standards) and a new project by Sebastian Bergmann: https://github.com/sebastianbergmann/hphpa This utilizes the static compiler by facebook to check for errors such as your looking for... Might be too much as a pre commit hook, but a hook into your build system might suffice?

like image 8
Gekkie Avatar answered Nov 11 '22 19:11

Gekkie