PHP tokenizer有哪些实际用途?

时间:2011-04-20 09:08:37

标签: php tokenize

PHP Tokenizer的实际和日常使用示例是什么?

有没有人用过这个?

8 个答案:

答案 0 :(得分:17)

我使用PHP_CodeSniffer编码样式合规性,它是在tokeniser上构建的。此外,一些框架(例如Symfony 2)使用tokeniser来生成PHP代码的缓存文件或中间类文件。也可以使用tokeniser来构建源代码格式化程序或语法高亮显示器。

基本上,只要您将PHP代码用作数据,就可以使用tokeniser。尝试使用正则表达式或其他字符串处理函数解析PHP代码更加可靠。

答案 1 :(得分:16)

我个人已经用它来构建PHP sandbox,它试图为执行PHP脚本创建一个更安全的环境。

此外,我做了很多实验来预处理PHP,例如我有一个(不完整的)PHP 5.3模拟器,用于PHP 5.2,名为prephp

许多其他类似工具,例如源代码分析器(用于security auditingcode style分析,...)也使用Tokenizer。

但即使对于较小的东西,Tokenizer也可能很方便。不仅仅是大规模的代码分析器。例如,如果您接受PHP数组并想要检查它是否是恶意的,您可以do so using the Tokenizer

PS:目前我正在切换到实际解析PHP,而不仅仅是使用我最近发布的PHP parser written in PHP来标记它(它有效,但实际上还没有实用)。

答案 2 :(得分:11)

有趣的问题。

我自己还没有在任何生产项目中使用过标记器,但是有一些关于Stack Overflow的问题,令牌化器是(或至少一个)正确答案。

答案 3 :(得分:3)

一个非常基本的用法是语法高亮。

foreach(token_get_all($source) as $token) {
    if (is_array($token))
    {
        $map = "token_name";
        echo "<span class={$map($token[0])}>$token[1]</span>";
    }
    else {
        echo "<span class=T_RAW>$token</span>";
    }
}

当然,令牌编号通常会转换为更好的CSS类名,但您只需制作一个仅包含.T_COMMENT,.T_ARRAY,.T_ELSEIF,.T_FUNCTION ...类的样式表。

答案 4 :(得分:3)

我使用了tokenizer来查找回调复杂性数字以及回调的其他一些代码指标:

if ((isset($reflection) === true) && ($reflection->getFileName() !== false))
{
    if (($source = file($reflection->getFileName(), FILE_IGNORE_NEW_LINES)) !== false)
    {
        $source = implode("\n", array_slice($source, $reflection->getStartLine() - 1, $reflection->getEndLine() - ($reflection->getStartLine() - 1)));
        $result[$key]['source'] = array
        (
            'ccn' => 1,
            'statements' => 0,
            'lines' => array
            (
                'logical' => array(),
                'physical' => substr_count($source, "\n"),
            ),
        );

        if (is_array($tokens = token_get_all(sprintf('<?php %s ?>', $source))) === true)
        {
            $points = array_map('constant', array_filter(array
            (
                'T_BOOLEAN_AND',
                'T_BOOLEAN_OR',
                'T_CASE',
                'T_CATCH',
                'T_ELSEIF',
                'T_FINALLY',
                'T_FOR',
                'T_FOREACH',
                'T_GOTO',
                'T_IF',
                'T_LOGICAL_AND',
                'T_LOGICAL_OR',
                'T_LOGICAL_XOR',
                'T_WHILE',
            ), 'defined'));

            foreach ($tokens as $token)
            {
                if (is_array($token) === true)
                {
                    if ((in_array($token[0], array(T_CLOSE_TAG, T_COMMENT, T_DOC_COMMENT, T_INLINE_HTML, T_OPEN_TAG), true) !== true) && (strlen(trim($token[1])) > 0))
                    {
                        if (in_array($token[0], $points, true) === true)
                        {
                            ++$result[$key]['source']['ccn'];
                        }

                        array_push($result[$key]['source']['lines']['logical'], $token[2]);
                    }
                }

                else if (strncmp($token, '?', 1) === 0)
                {
                    ++$result[$key]['source']['ccn'];
                }

                else if (strncmp($token, ';', 1) === 0)
                {
                    ++$result[$key]['source']['statements'];
                }
            }

            $result[$key]['source']['lines']['logical'] = max(0, count(array_unique($result[$key]['source']['lines']['logical'])) - 1);
        }
    }
}

答案 5 :(得分:2)

我的一位朋友写了Überloader(PHP5的蛮力自动加载器。),它在索引类文件时使用了这种技术。来自它的_check_file() method将是您特别感兴趣的。

Überloader专为未计划或考虑其类命名约定或文件结构的遗留项目而设计。

我每天都会在正在修理或翻新的旧项目中使用该课程。

答案 6 :(得分:2)

来自comment in the PHP manual

  

令牌化器功能非常好   强大。例如,你可以   检索给定的所有方法   使用如下算法的类:

     每个令牌

:如果令牌是T_FUNCTION   如果缓冲区启动,则启动缓冲区   然后将当前字符串添加到   如果令牌是缓冲区(停止缓冲区

)      

最棒的是班级   方法会有正确的情况,所以   这是一个很好的方式绕过   get_class_methods的限制   返回小写方法名称。也   因为你使用类似的算法   可以读取函数的参数   你可以实现类似反射   PHP4的功能。

     

最后,您可以将其用作更简单的方法   从一个提取Javadoc的方法   用于生成文档的类文件。   util / MethodTable.php类   AMFPHP(http://www.amfphp.org)使用   tokenizer函数创建一个   所有的方法表   参数,描述,返回类型,   等等,从那个方法表中就可以了   生成与之匹配的ActionScript   PHP,但它也适合   生成JavaScript,文档   文件,或基本上你放的任何东西   你的想法。我也可以看到这个   可能是一个班级的基础 - &gt; WSDL   文件生成器。

您可以用于收集有关某些PHP代码的各种信息,例如所有已定义的类,方法,变量,生成文档和类似任务。

答案 7 :(得分:0)

我正在研究Symfony 1.2遗留应用程序,并使用tokenizer来获取sfConfig::get()sfConfig::set()的所有调用。

所以基本上我记录了我的应用程序的所有配置参数。