需结合 sql-parser 解析 SQL 获取表字段依赖,用 PHP-Parser 静态分析变量流,补充视图 DDL 和人工元数据,并统一跨栈命名语义以保障血缘连贯性。

怎么用 PHP 解析 SQL 提取表和字段依赖
PHP 本身不带 SQL 行级血缘分析能力,得靠解析 SQL 文本还原「谁读了谁」。核心是识别 SELECT 中的字段来源(FROM/JOIN 的表 + 别名映射 + AS 重命名),不是正则硬匹配,而是用语法树更稳。
推荐用 sql-parser 库(GitHub 上活跃的轻量解析器),它能把 SELECT a.id, b.name FROM users a JOIN orders b ON a.id = b.user_id 拆成明确的字段源:a.id → users.id、b.name → orders.name。
- 别直接
preg_match字段名——遇到子查询、CTE、函数包裹(如COALESCE(u.name, ''))就漏掉源头 -
sql-parser支持 MySQL/PostgreSQL 基础语法,但不处理存储过程或动态拼接 SQL(比如"SELECT * FROM ".$table) - 字段别名必须显式解析:若写
SELECT u.name AS user_name,要记录user_name → users.name,否则下游报表查不到映射
PHP 如何把 ETL 脚本里的变量赋值链串起来
很多数据加工逻辑藏在 PHP 脚本里:从数据库查出数组,用 array_map 改字段,再 foreach 拼新结构——这种非 SQL 路径容易被血缘工具忽略。
关键不是“运行时追踪”,而是静态扫描变量流向。例如识别 $order_data = db_query(...) → $enriched = add_user_info($order_data) → $report_row['revenue'] = $enriched['amount'] * 0.9 这条链。
立即学习“PHP免费学习笔记(深入)”;
- 用 PHP-Parser 扩展做 AST 分析,比字符串搜索准:能区分
$a = $b和if ($a == $b) - 注意引用传递陷阱:
process(&$data)修改原数组,但 AST 里看不到字段级变化,得人工标注或约定注释(如// @propagates user_id, amount) - 第三方函数(如 Laravel 的
collect())需单独建映射规则,否则血缘会断在$c->map(...)这一层
为什么字段血缘在报表层经常对不上
前端报表(比如 PHP+Vue 渲染的表格)常做最后一层字段处理:四舍五入、状态码转文字、空值兜底——这些操作会让字段“失真”,血缘图里显示「报表用了 status」,实际展示的是 status_text。
- 不要只扫 PHP 模板里的
{{ $row.status }},检查是否有formatStatus($row['status'])调用,该函数是否改变了语义 - JavaScript 端二次处理(如
moment().fromNow())完全脱离 PHP 血缘体系,得用 sourcemap 或约定前缀(如js:time_ago)打标 - 同一个字段在不同报表中含义可能不同:订单表的
total在销售看板是含税,在财务看板是税前,血缘系统得支持上下文标签,不能只存“来源=orders.total”
MySQL 视图和物化表怎么让 PHP 血缘不丢链
视图(CREATE VIEW)在 PHP 里看起来就是一张表,但它的字段可能来自多层嵌套查询;物化表(如 ClickHouse 的 MATERIALIZED VIEW)更是把计算逻辑藏在引擎里——PHP 解析 SQL 时根本看不到底层依赖。
- 必须提前把视图 DDL 加入血缘分析输入源,用
SHOW CREATE VIEW取出定义,再喂给 SQL 解析器 - 避免用
SELECT * FROM view_x:字段增减会导致血缘映射错位,强制要求明确列出字段(SELECT id, name FROM view_x) - 物化表如果依赖 Kafka 或外部 API,PHP 层只能标记“外部源头”,无法自动解析,得靠人工录入元数据(如配置文件里写
"mv_orders": {"source": "kafka:orders_v2"})
字段级血缘最难的不是解析 SQL,而是跨技术栈对齐语义——数据库字段名、ETL 变量名、API 返回 key、前端展示 label,四者稍有不一致,整条链就变成断头路。留个心眼:每次加新报表,先确认这四个地方的命名是否真正指向同一业务概念。



















