老系统维护实录:用 PHP 正则 + CSS 绝对定位,优雅搞定面单打印"缝隙插针"需求
大家好,我是"世界上最好的语言"的使用者------一名 PHPer。
最近在维护公司内部的一个 WMS(仓储管理系统)时,接到了一个让人头秃的需求。业务方要求在现有的商品标签(面单)上,增加一个"定制文案"的展示。
听起来很简单对吧?但在十年前写的老系统里,这简直是灾难。今天分享一下我是如何在不动用 DOM 解析库的情况下,用 PHP 原生能力解决这个问题的。
😱 业务场景与痛点
现有的面单打印逻辑非常古老,模版不是像现在的 Blade 或 Smarty 那样渲染的,而是直接在后端拼接了一大坨带有 style 内联样式的 HTML 字符串,存放在数据库里,取出来后直接吐给前端打印组件。
需求具体是这样的:
- 位置刁钻:要在"平台SKC编号"和"平台海外仓多属性"这两个字段中间,插入一个新的字段。
- 空间有限 :这个新字段最多只能展示 6 个字符的宽度,超长必须截断,不能换行。
- 不能动老结构 :原有的 HTML 结构是通过绝对定位(
position: absolute)排版的,坐标写死在style里的,牵一发而动全身。
面对着那一坨杂乱的 HTML 字符串,使用 DOMDocument 或 SimpleHTMLDom 解析不仅慢,还容易因为 HTML 标签不规范导致报错。这时候,PHP 强大的正则处理能力就派上用场了。
🛠️ 解决方案:PHP 正则手术刀
我的思路是:找到"SKC编号"的闭合 </div> 标签,在它后面无缝拼接我们要插入的新 div。
1. 正则表达式的构建
最关键的一步是如何精准定位。原有的 HTML 标签混杂着各种属性和换行符。
php
$pattern = '/(<div[^>]*?data-title="平台SKC编号"[^>]*?>.*?<\/div>)/is';
这里有几个知识点值得分享:
[^>]*?:非贪婪匹配,确保我们匹配的是当前的div开始标签,防止跨越到下一个标签。data-title="...":利用业务特有的属性作为锚点,比用 class 靠谱,因为 class 可能会变,但业务标识一般不变。/is修饰符 :这是重点!i:忽略大小写。s:让点号.可以匹配换行符。因为 HTML 源码中往往包含大量的换行和空格,如果不加这个修饰符,正则会直接失效。
2. CSS 布局的魔法
后端插入了 HTML 只是第一步,前端展示还得对齐。由于原有的布局是 absolute,我们新插入的元素也必须"悬浮"在指定坐标。
业务要求"最多展示6个字符",这里我用了一个 CSS 小技巧:em 单位。
width: 6em:大约就是 6 个字符的宽度(取决于字体大小)。overflow: hidden:物理截断,防止内容撑破版面。white-space: nowrap:强制不换行。z-index: 99:确保新内容浮在最上层,不被背景遮挡。
3. 最终代码实现
直接上代码,干净利落:
css
<?php
// 模拟原始 HTML 字符串(一坨乱糟糟的代码)
$str = $originalHtmlFromDb;
// 假设这是从订单数据中获取的定制文案
$customText = "Lukas, 67";
// 构建要插入的 HTML 代码
// 注意 style 设置:
// 1. position: absolute; top: 4px; (与左右元素高度对齐)
// 2. left: 110px; (大致位于左侧和右侧元素中间,需要微调)
// 3. width: 6em; (限制宽度约为6个字符)
$insertHtml = sprintf(
'<div class="dropitem" data-title="定制文案" style="position: absolute; top: 4px; left: 110px; width: 6em; height: 15px; text-align: center; overflow: hidden; white-space: nowrap; z-index: 99;">
<span class="detail" style="font-size: 10px; line-height: 10px; font-weight: 700;">%s</span>
</div>',
$customText
);
// 正则替换:将捕获到的 $1 (即 SKC 编号的 div) 放回去,并在后面追加我们的新 div
$result = preg_replace(
'/(<div[^>]*?data-title="平台SKC编号"[^>]*?>.*?<\/div>)/is',
'$1' . $insertHtml,
$str
);
// 输出或保存结果
echo $result;
💡 总结
虽然现在流行前后端分离,但在处理 ERP、WMS 这种涉及硬件打印、老旧报表系统的业务时,PHP 的字符串处理能力依然是"神"一般的存在。
通过 preg_replace 配合 /s 模式,我们可以在不动用繁重 DOM 解析库的情况下,像外科手术一样精准修改 HTML 结构。再配合一点点 CSS 的 em 和 overflow 技巧,完美满足了业务方"既要又要"的需求。
PHP 不死,它只是在闷声发大财(解决实际问题)。
如果你也遇到过这种老系统维护的坑,欢迎在评论区一起吐槽交流!👋
标签: #PHP #正则表达式 #后端开发 #踩坑记录 #CSS