PHP: detect undefined variables

Published in category Programming and Productivity
on Christian Mayer's Weblog.

PhpStorm has a nice built-in feature: detecting undefined variables.

I’m not a PhpStorm user. I use Sublime Text 2 and I’m not planing to switch to PhpStorm. So I need to detect undefined variables in my code in a different way.

PHPMD can detect undefined variables. Consider this PHP script, FooBar.php:

<?php
class FooBar{
	public function fooBar(){
		print 'foo'.$bar;
	}
}

You can test it with PHPMD like this:

$ phpmd FooBar.php text unusedcode
FooBar.php:4	Avoid unused local variables such as '$bar'.

But think about this:

<?php
class FooBar{
	public function fooBar(){
		print 'foo'.$bar;
		print 'foo'.$bar;
	}
}

PHPMD will not detect $bar as an undefined variable. I used $bar twice but it’s still undefined. PHPMD is not smart enough for this trick. PHP code can be smart. Even if a variable is not defined.

There is another better tool to test PHP code called PHP CodeSniffer.

Add the following lines to your composer.json file to use PHP CodeSniffer with Composer:

"require-dev": {
	"squizlabs/php_codesniffer": "~2.6"
}

You can even install custom plugins for PHP CodeSniffer. To detect undefined variables with PHP CodeSniffer I use the VariableAnalysis plugin.

Install VariableAnalysis:

  1. First clone from GitHub to phpcs_variable_analysis:

     $ git clone git@github.com:illusori/PHP_Codesniffer-VariableAnalysis.git phpcs_variable_analysis
    
  2. Change into phpcs_variable_analysis directory and run:

     $ ./install.sh -d /path/to/code_sniffer
    

    The path /path/to/code_sniffer can differ. Under OS X and PHP CodeSniffer 2.6.2 the directory is located under /usr/local/Cellar/php-code-sniffer/2.6.2/CodeSniffer. If you like to use it project-based use /path/to/project/vendor/squizlabs/php_codesniffer/CodeSniffer.

    For example:

     $ mkdir -p /usr/local/etc/php-code-sniffer/Standards/Generic/Sniffs/CodeAnalysis
     $ ./install.sh -d /usr/local/etc/php-code-sniffer
     Installing Sniffs to /usr/local/etc/php-code-sniffer/Standards/Generic/Sniffs/CodeAnalysis
    
  3. Add VariableAnalysis to the ruleset, ruleset.xml file:

     <rule ref="Generic.CodeAnalysis.VariableAnalysis" />
    

    Unfortunately the whitelist property validUnusedVariableNames isn’t working for closure functions. This can be annoying if you use a lot $this variables. Using @codingStandardsIgnoreLine for the appropriate lines can fix this problem.

Testing the same script as above with PHP CodeSniffer warnings appear:

$ phpcs FooBar.php

FILE: FooBar.php
------------------------------------------------
FOUND 0 ERRORS AND 2 WARNINGS AFFECTING 2 LINES
------------------------------------------------
 4 | WARNING | [ ] Variable $bar is undefined.
 5 | WARNING | [ ] Variable $bar is undefined.
------------------------------------------------

That’s what I want, warnings.

More Resources

Recent Posts

About the Author

Christian is a professional software developer living in Vienna, Austria. He loves coffee and is strongly addicted to music. In his spare time he writes open source software. He is known for developing automatic data processing systems for Debian Linux.