优化获取类名兼容性

pull/446/head
Karson 2023-07-06 17:31:21 +08:00
parent 7f28eaa570
commit a9003ecce4
1 changed files with 50 additions and 56 deletions

View File

@ -98,13 +98,13 @@ class Api extends Command
foreach ($files as $name => $file) { foreach ($files as $name => $file) {
if (!$file->isDir() && $file->getExtension() == 'php') { if (!$file->isDir() && $file->getExtension() == 'php') {
$filePath = $file->getRealPath(); $filePath = $file->getRealPath();
$classes[] = $this->get_class_from_file($filePath); $classes[] = $this->getClassFromFile($filePath);
} }
} }
} else { } else {
foreach ($controller as $index => $item) { foreach ($controller as $index => $item) {
$filePath = $moduleDir . Config::get('url_controller_layer') . DS . $item . '.php'; $filePath = $moduleDir . Config::get('url_controller_layer') . DS . $item . '.php';
$classes[] = $this->get_class_from_file($filePath); $classes[] = $this->getClassFromFile($filePath);
} }
} }
@ -129,67 +129,61 @@ class Api extends Command
} }
/** /**
* get full qualified class name * 从文件获取命名空间和类名
* *
* @param string $path_to_file * @param string $filename
* @return string * @return string
* @author JBYRNE http://jarretbyrne.com/2015/06/197/
*/ */
protected function get_class_from_file($path_to_file) protected function getClassFromFile($filename)
{ {
//Grab the contents of the file $getNext = null;
$contents = file_get_contents($path_to_file); $isNamespace = false;
$skipNext = false;
//Start with a blank namespace and class $namespace = '';
$namespace = $class = ""; $class = '';
foreach (\PhpToken::tokenize(file_get_contents($filename)) as $token) {
//Set helper values to know that we have found the namespace/class token and need to collect the string values after them if (!$token->isIgnorable()) {
$getting_namespace = $getting_class = false; $name = $token->getTokenName();
switch ($name) {
//Go through each token and evaluate it as necessary case 'T_NAMESPACE':
foreach (token_get_all($contents) as $token) { $isNamespace = true;
break;
//If this token is the namespace declaring, then flag that the next tokens will be the namespace name case 'T_EXTENDS':
if (is_array($token) && $token[0] == T_NAMESPACE) { case 'T_USE':
$getting_namespace = true; case 'T_IMPLEMENTS':
} $skipNext = true;
break;
//If this token is the class declaring, then flag that the next tokens will be the class name case 'T_CLASS':
if (is_array($token) && $token[0] == T_CLASS) { if ($skipNext) {
$getting_class = true; $skipNext = false;
} } else {
$getNext = strtolower(substr($name, 2));
//While we're grabbing the namespace name... }
if ($getting_namespace === true) { break;
case 'T_NAME_QUALIFIED':
//If the token is a string or the namespace separator... case 'T_NS_SEPARATOR':
if (is_array($token) && in_array($token[0], [T_STRING, T_NS_SEPARATOR])) { case 'T_STRING':
case ';':
//Append the token's value to the name of the namespace if ($isNamespace) {
$namespace .= $token[1]; if ($name == ';') {
} elseif ($token === ';') { $isNamespace = false;
} else {
//If the token is the semicolon, then we're done with the namespace declaration $namespace .= $token->text;
$getting_namespace = false; }
} } elseif ($skipNext) {
} $skipNext = false;
} elseif ($getNext == 'class') {
//While we're grabbing the class name... $class = $token->text;
if ($getting_class === true) { $getNext = null;
break 2;
//If the token is a string, it's the name of the class }
if (is_array($token) && $token[0] == T_STRING) { break;
default:
//Store the token's value as the class name $getNext = null;
$class = $token[1];
//Got what we need, stope here
break;
} }
} }
} }
//Build the fully-qualified class name and return it return $namespace . '\\' . $class;
return $namespace ? $namespace . '\\' . $class : $class;
} }
} }