tags:

views:

969

answers:

4

Given that each php file in our project contains a single class definition... any suggestions for determining what class was defined within the file?

I know I could just regex the file for class statements, but I'd prefer to do something that's more efficient.

Suggestions?

Thanks

+3  A: 

Use PHP's function get_declared_classes(). This returns an array of classes defined in the current script.

James Skidmore
So, I'd need to compare this with the list of classes from before the include... or can you think of something more efficient?
Allain Lalonde
If you're loading the files via an include, that's the most efficient method I can think of.
James Skidmore
If you want to find out what classes are in a file, this won't do it. You can't compare get_declared_classes() before and after an include because the file may already be included/autoloaded/required.
cletus
Correct. This is assuming that it hasn't already been included.
James Skidmore
include_once will return true if the file has already been included, so you could check if the file has been included already before using get_declared_classes
Andrei Serdeliuc
Yes but that doesn't help you determine what the classes are if it already has been loaded.
cletus
+5  A: 

If you just want to check a file without loading it use token_get_all():

<?php
header('Content-Type: text/plain');
$php_file = file_get_contents('c2.php');
$tokens = token_get_all($php_file);
$class_token = false;
foreach ($tokens as $token) {
  if (is_array($token)) {
    if ($token[0] == T_CLASS) {
       $class_token = true;
    } else if ($class_token && $token[0] == T_STRING) {
       echo "Found class: $token[1]\n";
       $class_token = false;
    }
  }       
}
?>

Basically, this is a simple finite state machine. In PHP the sequence of tokens will be:

  • T_CLASS: 'class' keyword;
  • T_WHITESPACE: space(s) after 'class';
  • T_STRING: name of class.

So this code will handle any weird spacing or newlines you get just fine because it's using the same parser PHP uses to execute the file. If token_get_all() can't parse it, neither can PHP.

By the way, you use token_name() to turn a token number into it's constant name.

Here is my c2.php:

<?php
class MyClass {
  public __construct() {
  }
}

class MyOtherClass {
  public __construct() {
  }
}
?>

Output:

Found class: MyClass
Found class: MyOtherClass
cletus
+7  A: 

I needed something like this for a project I am working on, and here are the functions I wrote:

function file_get_php_classes($filepath) {
  $php_code = file_get_contents($filepath);
  $classes = get_php_classes($php_code);
  return $classes;
}

function get_php_classes($php_code) {
  $classes = array();
  $tokens = token_get_all($php_code);
  $count = count($tokens);
  for ($i = 2; $i < $count; $i++) {
    if (   $tokens[$i - 2][0] == T_CLASS
        && $tokens[$i - 1][0] == T_WHITESPACE
        && $tokens[$i][0] == T_STRING) {

        $class_name = $tokens[$i][1];
        $classes[] = $class_name;
    }
  }
  return $classes;
}
Venkat D.