从文件获取类名 [英] Get class name from file

查看:77
本文介绍了从文件获取类名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个仅包含一个类的php文件.我怎么知道文件名呢?我知道我可以用regexp匹配做一些事情,但是有没有标准的php方式? (该文件已经包含在试图找出类名的页面中).

I have a php file which contains only one class. how can I know what class is there by knowing the filename? I know I can do something with regexp matching but is there a standard php way? (the file is already included in the page that is trying to figure out the class name).

推荐答案

对此问题有多种解决方案,每种都有其优点和缺点.在这里,要决定要哪个.

There are multiple possible solutions to this problem, each with their advantages and disadvantages. Here they are, it's up to know to decide which one you want.

此方法使用令牌生成器并读取文件的各个部分,直到找到类定义为止.

This method uses the tokenizer and reads parts of the file until it finds a class definition.

优势

  • 不必完全解析文件
  • 快速(仅读取文件的开头)
  • 几乎没有误报的机会

缺点

  • 最长的解决方案

代码

$fp = fopen($file, 'r');
$class = $buffer = '';
$i = 0;
while (!$class) {
    if (feof($fp)) break;

    $buffer .= fread($fp, 512);
    $tokens = token_get_all($buffer);

    if (strpos($buffer, '{') === false) continue;

    for (;$i<count($tokens);$i++) {
        if ($tokens[$i][0] === T_CLASS) {
            for ($j=$i+1;$j<count($tokens);$j++) {
                if ($tokens[$j] === '{') {
                    $class = $tokens[$i+2][1];
                }
            }
        }
    }
}

正则表达式

使用正则表达式解析文件的开头,直到找到类定义为止.

Regular expressions

Use regular expressions to parse the beginning of the file, until a class definition is found.

优势

  • 不必完全解析文件
  • 快速(仅读取文件的开头)

缺点

  • 误报的可能性很高(例如:echo "class Foo {";)

代码

$fp = fopen($file, 'r');
$class = $buffer = '';
$i = 0;
while (!$class) {
    if (feof($fp)) break;

    $buffer .= fread($fp, 512);
    if (preg_match('/class\s+(\w+)(.*)?\{/', $buffer, $matches)) {
        $class = $matches[1];
        break;
    }
}

注意:regex可能可以改进,但是没有一个regex可以完美地做到这一点.

此方法使用get_declared_classes()并查找包含之后定义的第一个类.

This method uses get_declared_classes() and look for the first class defined after an include.

优势

  • 最短的解决方案
  • 没有误报的机会

缺点

  • 必须加载整个文件
  • 必须将内存中的整个类列表加载两次
  • 必须将类定义加载到内存中

代码

$classes = get_declared_classes();
include 'test2.php';
$diff = array_diff(get_declared_classes(), $classes);
$class = reset($diff);

注意:您不能像其他人建议的那样简单地执行end().如果该班级包括另一个班级,您将得到错误的结果.

Note: You cannot simply do end() as others suggested. If the class includes another class, you will get a wrong result.

这是 Tokenizer 解决方案,已修改为包含包含类名称空间的 $ namespace 变量(如果适用):

This is the Tokenizer solution, modified to include a $namespace variable containing the class namespace, if applicable:

$fp = fopen($file, 'r');
$class = $namespace = $buffer = '';
$i = 0;
while (!$class) {
    if (feof($fp)) break;

    $buffer .= fread($fp, 512);
    $tokens = token_get_all($buffer);

    if (strpos($buffer, '{') === false) continue;

    for (;$i<count($tokens);$i++) {
        if ($tokens[$i][0] === T_NAMESPACE) {
            for ($j=$i+1;$j<count($tokens); $j++) {
                if ($tokens[$j][0] === T_STRING) {
                     $namespace .= '\\'.$tokens[$j][1];
                } else if ($tokens[$j] === '{' || $tokens[$j] === ';') {
                     break;
                }
            }
        }

        if ($tokens[$i][0] === T_CLASS) {
            for ($j=$i+1;$j<count($tokens);$j++) {
                if ($tokens[$j] === '{') {
                    $class = $tokens[$i+2][1];
                }
            }
        }
    }
}

假设您有此类:

namespace foo\bar {
    class hello { }
}

...或其他语法:

namespace foo\bar;
class hello { }

您应该得到以下结果:

var_dump($namespace); // \foo\bar
var_dump($class);     // hello

您还可以使用上述方法检测文件声明的名称空间,而不管文件是否包含类.

You could also use the above to detect the namespace a file declares, regardless of it containing a class or not.

这篇关于从文件获取类名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆