This post was updated 613 days ago and some of the ideas may be out of date.
直接上代码
function getAllClassesInFile(string $file)
{
$classes = [];
$tokens = token_get_all(file_get_contents($file));
$count = count($tokens);
// 兼容php7和php8
$tNamespace = version_compare(PHP_VERSION, '8.0.0', '>=') ? [T_NAME_QUALIFIED, T_STRING] : [T_STRING];
$namespace = '';
for ($i = 2; $i < $count; $i++) {
// 扫描到命名空间
if ($tokens[$i - 2][0] === T_NAMESPACE && $tokens[$i - 1][0] === T_WHITESPACE) {
// 清空命名空间
$namespace = '';
// 不是命名空间跳过
if (!in_array($tokens[$i][0], $tNamespace)) {
continue;
}
// 获取命名空间
$tempNamespace = $tokens[$i][1] ?? '';
for ($j = $i + 1; $j < $count; $j++) {
// 如果是分号或者大括号,说明命名空间结束
if ($tokens[$j] === '{' || $tokens[$j] === ';') {
break;
}
if ($tokens[$j][0] === $tNamespace) {
// 命名空间拼接
$tempNamespace .= '\\' . $tokens[$j][1];
}
}
$namespace = $tempNamespace;
// 扫描到类
} else if ($tokens[$i - 2][0] === T_CLASS && $tokens[$i - 1][0] === T_WHITESPACE && $tokens[$i][0] === T_STRING) {
// 拼接命名空间和类名
$classes[] = ($namespace ? $namespace . '\\' : '') . $tokens[$i][1];
}
}
return $classes;
}
测试一下效果
<?php
/**
* Created by PhpStorm.
* User: LinFei
* Created time 2022/11/29 14:16:39
* E-mail: fly@eyabc.cn
*/
declare (strict_types=1);
namespace App\Controllers {
class IndexController
{
}
}
namespace {
class Index
{
}
}
namespace App\Rpc {
class IndexRpc
{
}
}
namespace {
var_dump(getAllClassesInFile(__FILE__));
}
输出结果
array(3) {
[0]=>
string(31) "App\Controllers\IndexController"
[1]=>
string(5) "Index"
[2]=>
string(16) "App\Rpc\IndexRpc"
}
参与讨论