确定PHP类文件中定义的类

All*_*nde 38 php class

鉴于我们项目中的每个PHP文件都包含单个类定义,我如何确定文件中定义的类或类?

我知道我可以正式使用该文件来表达class语句,但我更愿意做一些效率更高的事情.

Ven*_* D. 62

对于我正在处理的项目,我需要这样的东西,这里是我写的函数:

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;
}
Run Code Online (Sandbox Code Playgroud)


cle*_*tus 16

如果您只想检查文件而不加载它,请使用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;
    }
  }       
}
?>
Run Code Online (Sandbox Code Playgroud)

基本上,这是一个简单的有限状态机.在PHP中,令牌序列将是:

  • T_CLASS:'class'关键字;
  • T_WHITESPACE:'class'之后的空格;
  • T_STRING:班级名称.

所以这段代码会处理你得到的任何奇怪的间距或换行,因为它使用了PHP用来执行文件的相同解析器.如果token_get_all()无法解析它,PHP也无法解析.

顺便说一句,您使用token_name()将令牌编号转换为常量名称.

这是我的c2.php:

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

class MyOtherClass {
  public __construct() {
  }
}
?>
Run Code Online (Sandbox Code Playgroud)

输出:

Found class: MyClass
Found class: MyOtherClass
Run Code Online (Sandbox Code Playgroud)


Ond*_*lda 6

或者您可以轻松使用Nette\Reflection中的 AnnotationsParser (可使用 Composer 安装):

use Nette\Reflection\AnnotationsParser;
$classes = AnnotationsParser::parsePhp(file_get_contents($fileName));
var_dump($classes);
Run Code Online (Sandbox Code Playgroud)

输出将是这样的:

array(1) {
  ["Your\Class\Name"] =>
  array(...) {
      // property => comment
  },
  ["Your\Class\Second"] =>
  array(...) {
      // property => comment
  },
}
Run Code Online (Sandbox Code Playgroud)

parsePhp () 方法基本上执行与其他答案中的示例类似的操作,但您不必自己声明或测试解析。


fro*_*y22 5

我需要来自带有命名空间的文件的解析类,所以我修改了代码.如果有人也需要,这就是:

public function getPhpClasses($phpcode) {
    $classes = array();

    $namespace = 0;  
    $tokens = token_get_all($phpcode); 
    $count = count($tokens); 
    $dlm = false;
    for ($i = 2; $i < $count; $i++) { 
        if ((isset($tokens[$i - 2][1]) && ($tokens[$i - 2][1] == "phpnamespace" || $tokens[$i - 2][1] == "namespace")) || 
            ($dlm && $tokens[$i - 1][0] == T_NS_SEPARATOR && $tokens[$i][0] == T_STRING)) { 
            if (!$dlm) $namespace = 0; 
            if (isset($tokens[$i][1])) {
                $namespace = $namespace ? $namespace . "\\" . $tokens[$i][1] : $tokens[$i][1];
                $dlm = true; 
            }   
        }       
        elseif ($dlm && ($tokens[$i][0] != T_NS_SEPARATOR) && ($tokens[$i][0] != T_STRING)) {
            $dlm = false; 
        } 
        if (($tokens[$i - 2][0] == T_CLASS || (isset($tokens[$i - 2][1]) && $tokens[$i - 2][1] == "phpclass")) 
                && $tokens[$i - 1][0] == T_WHITESPACE && $tokens[$i][0] == T_STRING) {
            $class_name = $tokens[$i][1]; 
            if (!isset($classes[$namespace])) $classes[$namespace] = array();
            $classes[$namespace][] = $class_name;
        }
    } 
    return $classes;
}
Run Code Online (Sandbox Code Playgroud)