token_get_all 是 php 词法分析函数,将源码解析为 token 数组,含类型、文本、行号;适用于轻量扫描,如检测 eval、硬编码密码等,但无法处理作用域、动态拼接或混淆代码。

什么是 token_get_all
token_get_all 是 PHP 内置函数,用于将一段 PHP 源代码字符串解析为“词法单元(tokens)”数组。每个 token 是一个数组,包含类型(如 T_ECHO、T_VARIABLE)、原始文本(如 '$user')和行号等信息。它不执行语法校验,也不构建 AST,仅做词法分析 —— 这让它轻量、快速,适合做基础扫描。
如何用 token_get_all 提取关键结构
常见扫描目标包括:未使用的变量、硬编码密码、危险函数调用(如 eval、system)、缺失的 isset 检查等。token_get_all 能直接定位这些关键词:
- 遍历 tokens,用 is_array($token) && $token[0] === T_EVAL 判断是否含 eval
- 检测字符串字面量:is_array($token) && $token[0] === T_CONSTANT_ENCAPSED_STRING,再用 stripos($token[1], 'password') 查敏感内容
- 识别变量赋值:遇到 T_VARIABLE 后紧跟 T_EQUAL,可标记为“已定义变量”
- 跳过注释与 heredoc:忽略 T_COMMENT、T_DOC_COMMENT、T_START_HEREDOC 等非执行 token
简易扫描器实现要点
写一个基础扫描器不需要框架,核心逻辑约 50 行内可完成:
- 读取文件内容,用 file_get_contents 加载源码
- 调用 $tokens = token_get_all($code),注意传入的字符串不能含 BOM,否则可能解析失败
- 用 foreach ($tokens as $i => $token) 遍历,记录当前行号($token[2]),便于报错定位
- 对每个 token 做类型判断,匹配规则后立即记录问题(如 ['line' => $token[2], 'message' => 'Found eval()'])
- 避免误报:比如 eval 在字符串里或注释中,需结合上下文状态(如是否在 T_CONSTANT_ENCAPSED_STRING 内)过滤
局限与注意事项
token_get_all 是词法层工具,有天然边界:
- 无法识别变量作用域(如函数内定义的变量在外部不可见),所以“未使用变量”只能做粗略提示
- 不处理动态拼接(如 $func = 'sy'.'stem'; $func(...)),这类需静态分析或 AST
- PHP 8+ 新增 token(如 T_NAME_QUALIFIED)需适配版本,可用 defined('T_NAME_QUALIFIED') 判断
- 混淆代码(如 base64 编码字符串)无法识别,扫描器只看明文 token
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











