tokenizer - 解析器
简介:
tokenizer函数提供了一个内嵌在Zend引擎的"PHP tokenizer"的调用接口。使用这些函数,你可以写出你自己的PHP源码分析或者修改工具,而无需处理词法分析级别上的语言规范。仅包含2个函数:
token_get_all(string $source)1.token_get_all() 解析提供的 source 源码字符,然后使用 Zend 引擎的语法分析器获取源码中的 PHP 语言的解析器代号
2.$source - 需要解析的php源码
3.返回值:返回源码解析后的所有token标志符数组。
4.每个单独的token标志符,有2种形式:
1>单个字符,例如:: ; , .
2>一个包含3个元素的数组,0-token索引(可调用token_name()来获取字面量) | 1-token源码字符串 | 2-行号
5.实例:
$tokens = token_get_all('<?php echo "dongxuemin"; echo "zhangrui";?>');
解析后:
Array
(
[0] => Array
(
[0] => 379
[1] => 1
)
[1] => Array
(
[0] => 328
[1] => echo
[2] => 1
)
[2] => Array
(
[0] => 382
[1] =>
[2] => 1
)
[3] => Array
(
[0] => 323
[1] => "dongxuemin"
[2] => 1
)
[4] => ;
[5] => Array
(
[0] => 382
[1] =>
[2] => 1
)
[6] => Array
(
[0] => 328
[1] => echo
[2] => 1
)
[7] => Array
(
[0] => 382
[1] =>
[2] => 1
)
[8] => Array
(
[0] => 323
[1] => "zhangrui"
[2] => 1
)
[9] => ;
[10] => Array
(
[0] => 381
[1] => ?>
[2] => 1
)
)
token_name(int $token)
1.获取提供的 PHP 解析器代号的符号名称
2.$token - 解析器代号的值。接收的是 token_get_all()解析出来的token数组中的第一个元素(token索引),是个int类型
3.返回值:提供的token的符号名
4.实例:
token_name(328); // 返回 'T_OPEN_TAG'
解析器代号列表
1.PHP 语言的不同部分在内部被表示为类似 T_SR 的类型。PHP 在解析错误时输出这样的标识符,例如 "Parse error: unexpected T_SR, expecting ',' or ';' in script.php on line 10."。2.应该知道 T_SR 的含义。对于所有不知道的人,下表列出了这些标识符,PHP 语法和在手册中适当位置的参考。
3.注意:T_*常量的使用
所有下面列出的token,也被定义为PHP常量。它们的值是基于PHP底层的解析器,自动生成的。这意味着:在两个不同的PHP版本间,同样的token代表的值可能不同。例如:T_FILE常量在PHP5.3是365,在PHP5.4就是369。这也意味着:你的代码绝对不能直接依赖具体某个PHP版本的原始 'T_*' token值,去提供PHP跨版本的兼容性(就是我们不能使用token值作为版本兼容,同一token的值不同版本可能是不同的)。相反你的代码应利用自定义的值 (使用大的数字,像 10000)和适当的策略,来实现 'T_*' 的值和PHP版本兼容性。(我们得将列表中所有的token的值,重新定义,而不采用系统的)
4.不过这里有个疑问:常量的值不可重新定义,也不清楚具体该怎么做,使用变量?主要是不清楚需求...
5.通过解析器代号列表,我们就可以查找我们通过 token_name() 获取到的 token名代表的内容。
该列表,并没有列出token对应的int类型的值,就是因为上面讲的:值是自动生成的,不同版本相同的token是不同的值
上面几点,就是手册上涉及的几个重要概念,我们大概也了解到了,就是:解析php源代码,然后我们自己实现自己的逻辑,接下来,写几个实例(参照别人的博客,或其他地方资料):
1.源码高亮展示,php自带的相关方法有 highlight_string(),highlight_file(),我顺便对这2个方法进行了查看,总结,可参照:php的语法高亮函数,highlight_string和highlight_file(别名是:show_resource),以及highlight在php.ini中的配置
2.压缩php代码,去除不要的换行、空白以及注释,转载别人的博客,可参照:
PHP Tokenizer 学习笔记
有人指出了 'php_strip_whitespace' 可做相同的事情,就研究下这个函数,看了下手册,里面有个评论,也写了一个压缩php的代码,干脆再写篇文章了
PHP的php_strip_whitespace函数描述,以及手册中写的代码压缩函数-可看看函数是怎么实现的
3.上面博客有人评论说:可做一个能列出某php文件所有函数名,和参数表,感觉这个想法不错,只要和源码相关的,我们都可以想着做
4.在stackoverflow.com上查看了个类似的问题,有人回答,参照链接:
tokenizer的一些实用实例:http://stackoverflow.com/questions/5727951/what-are-some-practical-uses-of-php-tokenizer
1>有的框架用tokenizer生成缓存文件或中间class类文件
2>源代码格式化、高亮显示
3>可收集所有定义的class,methods,variables,文档,注释等
4>一些安全检测等,保证代码更安全。不允许使用的php函数,反正各种安全检测。。。
5>基本上,能使用php代码作为数据的任何地方,我们都可以使用tokennizer。它比使用正则表达式,或其他处理函数,来解析php代码都更可靠。
5.如何在php文件中,查看是否定义了某个类?上面评论里的问题,挺有意思:
1>当可以使用include命令时:
$before = get_declared_classes();
include "myfile.php";
$after = get_declared_classes();
$new_classes = array_diff($before, $after); // 取差集
print_r($new_classes); // Outputs all classes defined in myfile.php
对比加载该文件前后,已经定义的类
2>当不可以使用include命令时(有可能因为该文件定义了一个同名的类,会报错!)
可以使用tokenizer分析出该文件所有的class
总结下:
偶然的在dedecms中看源码,看到使用了这个tokenizer函数,就引申出一连串的东西,对手册等函数,一些扩展,稍微底层点的东西,必需都了解!与大家共勉!