v61 修补:Markdown 引擎回退 7.4 兼容写法(str_contains 线上会白屏)

部署后拿服务器 PHP 7.4 的 CLI 真跑了一次渲染,当场 Fatal:
`Call to undefined function App\str_contains()`。

- 全站基线是 **0 处 PHP8 函数**(项目一直兼容 7.4);我新写的表格代码
  引入了 6 处(str_contains×4、str_starts_with、str_ends_with)。
- `php -l` 只查语法——"函数不存在"是运行时错误,部署脚本的"双版本语法检查"
  拦不住这类回归。已改成 strpos/substr 写法,并在部署脚本加了一段
  **74 运行时探针**(真渲染一次表格+任务清单+转义),把这条底线钉死。
- 反向验证的注入锚点跟着源码改写同步更新(case 1/3),基线 30/0、
  锚点注入照样变红。
This commit is contained in:
2026-10-18 11:35:13 +08:00
parent 4c63e42091
commit f513703491
+11 -7
View File
@@ -92,9 +92,11 @@ final class Markdown
// 识别条件**必须两行一起看**:本行像 `|a|b|` 且**下一行是分隔行**
// (只含 - : | 空格且至少一个 -)。只看本行会把"正文里恰好有竖线
// 的一行"当表格(比如「3 | 2 | 1」),假表格比没表格更糟。
if (str_contains($line, '|') && $i + 1 < $n
// ⚠️ 一律用 strpos !== false 而**不用 str_contains**:线上 PHP 是 7.4
// (全站零处 PHP8 函数,本仓一直兼容 7.4),str_contains 在 7.4 直接 fatal。
if (strpos($line, '|') !== false && $i + 1 < $n
&& preg_match('/^\s*\|?[\s:|-]+\|[\s:|-]*$/', $lines[$i + 1])
&& str_contains($lines[$i + 1], '-')) {
&& strpos($lines[$i + 1], '-') !== false) {
[$html, $i] = self::table($lines, $i, $n);
$out[] = $html;
continue;
@@ -138,9 +140,9 @@ final class Markdown
&& !preg_match('/^\s*(#{1,6}\s|>|```|~~~|[-*+]\s|\d+[.)]\s)/', $lines[$i])
// 🔴 v61:正文里出现表格也要**断开段落**,否则表格头会被吸进
// 上一段(GFM 允许表格紧跟正文,不强制空行)。
&& !(str_contains($lines[$i], '|') && $i + 1 < $n
&& !(strpos($lines[$i], '|') !== false && $i + 1 < $n
&& preg_match('/^\s*\|?[\s:|-]+\|[\s:|-]*$/', $lines[$i + 1])
&& str_contains($lines[$i + 1], '-'))) {
&& strpos($lines[$i + 1], '-') !== false)) {
$buf[] = $lines[$i];
$i++;
}
@@ -258,8 +260,10 @@ final class Markdown
if (!isset($aligns[$k])) { $aligns[$k] = '---'; }
}
$styleOf = static function (string $sep): string {
$l = str_starts_with(trim($sep), ':');
$r = str_ends_with(trim($sep), ':');
// ⚠️ 7.4 兼容:不用 str_starts_with / str_ends_with(见上面的说明)
$sep = trim($sep);
$l = ($sep !== '' && $sep[0] === ':');
$r = ($sep !== '' && substr($sep, -1) === ':');
if ($l && $r) { return ' style="text-align:center"'; }
if ($r) { return ' style="text-align:right"'; }
if ($l) { return ' style="text-align:left"'; }
@@ -274,7 +278,7 @@ final class Markdown
$html .= '</tr></thead><tbody>';
$i += 2; // 跳过表头与分隔行
while ($i < $n && str_contains($lines[$i], '|') && trim($lines[$i]) !== '') {
while ($i < $n && strpos($lines[$i], '|') !== false && trim($lines[$i]) !== '') {
$cells = $split($lines[$i]);
$html .= '<tr class="md-tr">';
for ($c = 0; $c < $cols; $c++) {