我正在遍历目录中的所有文件。现在我想要得到每个函数中定义的所有函数和类。从那里,我可以使用ReflectionClass进一步检查它们。我不知道如何在一个文件中定义所有的函数和类。
ReflectionExtension看起来最接近我想要的,除了我的文件不是扩展的一部分。有什么类或函数我忽略了吗?
问得好。get_declared_classes
和get_defined_functions
是一个很好的起点。在试图确定给定文件中的内容时,您必须注意已经定义了哪些类/函数。
同样,不确定你的最终目标是什么,但是像PHP Depend或PHP Mess Detector这样的工具可能会做一些类似于你想要的东西。我建议大家也去看看。
这是我能想到的最好的(礼貌):
function trimds($s) {
return rtrim($s,DIRECTORY_SEPARATOR);
}
function joinpaths() {
return implode(DIRECTORY_SEPARATOR, array_map('trimds', func_get_args()));
}
$project_dir = '/path/to/project/';
$ds = array($project_dir);
$classes = array();
while(!empty($ds)) {
$dir = array_pop($ds);
if(($dh=opendir($dir))!==false) {
while(($file=readdir($dh))!==false) {
if($file[0]==='.') continue;
$path = joinpaths($dir,$file);
if(is_dir($path)) {
$ds[] = $path;
} else {
$contents = file_get_contents($path);
$tokens = token_get_all($contents);
for($i=0; $i<count($tokens); ++$i) {
if(is_array($tokens[$i]) && $tokens[$i][0] === T_CLASS) {
$i += 2;
$classes[] = $tokens[$i][1];
}
}
}
}
} else {
echo "ERROR: Could not open directory '$dir'n";
}
}
print_r($classes);
希望我不必解析文件并像这样循环遍历所有令牌。
忘记前面的解决方案阻止我使用我想要的反射。新的解决方案:
$project_dir = '/path/to/project/';
$ds = array($project_dir);
while(!empty($ds)) {
$dir = array_pop($ds);
if(($dh=opendir($dir))!==false) {
while(($file=readdir($dh))!==false) {
if($file[0]==='.') continue;
$path = joinpaths($dir,$file);
if(is_dir($path)) {
$ds[] = $path;
} else {
try{
include_once $path;
}catch(Exception $e) {
echo 'EXCEPTION: '.$e->getMessage().PHP_EOL;
}
}
}
} else {
echo "ERROR: Could not open directory '$dir'n";
}
}
foreach(get_declared_classes() as $c) {
$class = new ReflectionClass($c);
$methods = $class->getMethods();
foreach($methods as $m) {
$dc = $m->getDocComment();
if($dc !== false) {
echo $class->getName().'::'.$m->getName().PHP_EOL;
echo $dc.PHP_EOL;
}
}
}