1

I have many PHP files and I would like to check if all classes used in the source code exists. For example, let's suppose that we have the following code:

use MyProject\Logger;
use MyProject\Libraires\Form;


class MyClass 
{

        public function startup()
        {
                Logger::addTrace("()"); << check that class '\MyProject\Logger' class exists 
                parent::startup();

                $this->requirePermittedIp();

                $form = new Form(); // << check that class \MyProject\Libraries\Form exists

                $utils = new Utils(); // << check that \Utils class exists

                Logger::addTrace("(-)");
        }
}

I know that I can use token_get_all() function. I actually tried that but I think that somebody certainly solved this kind of problem.

MartyIX
  • 27,828
  • 29
  • 136
  • 207
  • This will never be possible fully. Because how do you want to check dynamically imported/instantiated classes? By the way, must it have to be programmatically? Why dont you use an IDE that supports code analysis (like IDEA) ? – Christopher Will Feb 27 '14 at 18:47
  • I intend to use it as a tool to check my codebase (or codebases from other vendors). It may help reduce a number of potential bugs in future because I may not be able to guarantee that each developer working on the codebase uses IDEA or any other IDE. Static code analysis seems like a good idea how to check the codebase. It is perfectly all right that the static analysis does not cover everything because we write unit tests and Selenium tests but not everything is covered by unit tests. – MartyIX Feb 27 '14 at 18:52
  • OK, did you find this SO post already? http://stackoverflow.com/questions/378959/is-there-a-static-code-analyzer-like-lint-for-php-files – Christopher Will Feb 27 '14 at 18:59
  • I did not. Thanks. I've found this package https://github.com/nikic/PHP-Parser. It seems that it's what I need. – MartyIX Feb 27 '14 at 19:06
  • Take your autoload function, modify it to generate a report on if the class exists or not, then use `token_get_all()` and parse out all of the class names and run them through your modified autoloaders. – Sammitch Feb 27 '14 at 19:06
  • @Sammitch: That's what I tried. However, the problem is in the phase "parse out all of the class names". – MartyIX Feb 27 '14 at 19:15

2 Answers2

0

What about regular expression? My example its work fine for declaration of New Class.

 function checkClassExists($string) {
     if (!is_string($string)) {
         return 'string required';
     }
     preg_match_all('/new\s+[A-Za-z\\\]+\((.)*\);/', $string, $classes);
     foreach ($classes[0] as $key => $class) {
         $classPrototype = str_replace('new', '', strstr($class, '(', true));
         $className = trim(str_replace(';', '', $classPrototype));
         echo (class_exists($className, true)) ? 'class ' . $className . ' exists <br/>' : 'class ' . $className . ' not exists <br/>';
     }
  }


 include_once 'framework/classes/ClassLoader.php'; // before usage function need some calss loader
 $autloader = new Classes\ClassLoader;
 spl_autoload_register(array($autloader, 'handle'));


 $stringTest = '<php? new  \framework\classes\Application();
  $a = new  \framework\classes\ClassLoader($a,$b); 
  if($a instanceof \framework\classes\ClassLoader){
          echo "helloworld";
  }else{

    $test = new \framework\classes\Application(array());
    $result = $test->some();
    foreach($result as $key => $value){
         echo $key;
    }
  }new  \framework\classes\Application($exception);

 ?>';



 checkClassExists($stringTest);

output:

 class \framework\classes\Application exists 
 class \framework\classes\ClassLoader exists 
 class \framework\classes\Application exists 
 class \framework\classes\Application exists 

function was tested on namespaced classes and you shuold develop function to match static`s method with "::"

ZiupeX
  • 338
  • 3
  • 13
  • Well, I don't think it is a good idea to use regular expressions. It may work in simple cases but I guess it will horribly fail in some scenarios. I need to be able to rely on the results of the static analysis. (It reminds me the answer http://stackoverflow.com/a/1732454/99256) – MartyIX Feb 27 '14 at 21:34
0

I used https://github.com/nikic/PHP-Parser. Moreover, it is very easy to work with.

MartyIX
  • 27,828
  • 29
  • 136
  • 207