我有一个自定义算法来加载类 . 有 $sourcePaths -es,自动加载器查看其中的所有.php文件,并从文件中收集类,接口 . 然后它存储在一个关联数组 $classes[class name] => absoule path 中 . 稍后,当自动加载发生时,它会查看该类是否在数组中,如果不存在该类则不存在 . 到目前为止还可以 . 但这里有名称空间 . 让我们看一个命名空间 Doctrine\ORM\Query; 和一个类 Parameter { .... } 的情况 . 首先,我只是处理它,因为它是Doctrine \ ORM \ Query \ Parameter ...所以命名空间类名 . 但是后来仍然没有找到这个 . 什么是在命名空间内查找类的正确算法?

收集的课程:

foreach ($sourcePaths as $dir)
{
    foreach (new DirectoryIterator($dir) as $fileinfo)
    {
        if (substr($fileinfo->getFilename(), -4) == '.php')
        {
            $absPath = str_replace('\\', '/', $dir.'/'.$fileinfo->getFilename());
            foreach (getPhpClasses($absPath) as $item)
            {
                $autoloadClassPaths[$item] = $absPath;
            }
        }
    }
}

这个函数从php代码中获取东西:

function getPhpClasses ($filename)
{
    $output = array();
    $namespace = '';
    $tokens = token_get_all(file_get_contents($filename));
    for ($i = 2; $i < sizeof($tokens); $i++)
    {
        if (($tokens[$i - 2][0] == T_NAMESPACE) && $tokens[$i - 1][0] == T_WHITESPACE && $tokens[$i][0] == T_STRING)
        {
            $j = 0;
            do
            {
                $namespace .= $tokens[$i + $j][1];
                $j++;
            } while ($tokens[$i + $j] != ';');
            $namespace .= '\\';
        }

        if (($tokens[$i - 2][0] == T_CLASS || $tokens[$i - 2][0] == T_INTERFACE) && $tokens[$i - 1][0] == T_WHITESPACE && $tokens[$i][0] == T_STRING)
        {
            $output[] = $namespace.$tokens[$i][1];
        }
    }
    return $output;
}