编程

PHP 8.3: highlight_file 和 highlight_string 输出 HTML 变更

415 2023-10-24 16:04:00

PHP 的 highlight_filehighlight_string 函数为 PHP 提供了语法高亮支持。他们接受包含 PHP 代码的文件或者字符串,并返回一个带有 PHP 关键词、函数和其他高亮 token 的 HTML 代码片段。语法高亮器的颜色可以通过 PHP INI 指令进行配置。

PHP 8.3 对语法高亮器做了一些修改,导致了 HTML 输出结果的改变。

<?php
function hello(): void {
    echo "Hello World";
}

hello();
echo highlight_string(string: $code, return: true);

PHP8.3 对 highlighter 处理空白的方式进行了一些更改,现在使用<pre></pre> HTML 标记包装输出。此外,它不再将换行符转换为 HTML<br/> 标记,从而产生多行高亮显示的HTML输出。

以下是 PHP 8.3 之前的 PHP 版本和 PHP 8.3 以上的 PHP 代码段的 HTML 输出的差异:

- <code><span style="color: #000000"> <span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">function&nbsp;</span><span style="color: #0000BB">hello</span><span style="color: #007700">():&nbsp;</span><span style="color: #0000BB">void&nbsp;</span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;</span><span style="color: #DD0000">"Hello&nbsp;World"</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">hello</span><span style="color: #007700">();</span> </span> </code>
+ <pre><code style="color: #000000"><span style="color: #0000BB">&lt;?php
+ </span><span style="color: #007700">function </span><span style="color: #0000BB">hello</span><span style="color: #007700">(): </span><span style="color: #0000BB">void </span><span style="color: #007700">{
+    echo </span><span style="color: #DD0000">"Hello World"</span><span style="color: #007700">;
+ }
+ 
+ </span><span style="color: #0000BB">hello</span><span style="color: #007700">();</span></code></pre>

修改详情

PHP 8.3 中内置的语法高亮器主要有 3 个方面的变更:

  1. 输出现在使用 <pre><code></code></pre> 包装
  2. 换行不再转换成 <br /> 标签
  3. 空格和 Tab 不再转换成 HTML 实体

1. 输出现在使用 <pre><code></code></pre> 标签

PHP 8.3 及其之后,highlight_filehighlight_string 输出使用 <pre><code></code></pre> 标签包装。它也删除了以前 PHP 版本中最外层的 span 标签,并为 <code> 标签添加了 style="color: 属性。

highlight_string('');
- <code><span style="color: #000000">
- </span>
- </code>
+ <pre><code style="color: #000000"></code></p 情况下re>

默认情况下,HTML <pre> 元素是块元素,这意味着使用 highlight_string/file 作为行内代码片段可能导致 HTML 输出损坏,除非 <pre> 样式也是行内(比如,在 <p> 标签内)。

2. 换行不再转换成 <br /> 标签

PHP 8.3 的 highlight_filehighlight_string 函数输出不再将换行符(\n)转换成 HTML <br> 标签。这意味着原始代码段中的换行符将被保留。

echo "Hello";
echo "World";
echo highlight_string(string: $code, return: true);
- <code><span style="color: #000000"> <span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">echo&nbsp;</span><span style="color: #DD0000">"Hello"</span><span style="color: #007700">;<br />echo&nbsp;</span><span style="color: #DD0000">"World"</span><span style="color: #007700">;</span> </span> </code>
+ <pre><code style="color: #000000"><span style="color: #0000BB">&lt;?php
+ </span><span style="color: #007700">echo </span><span style="color: #DD0000">"Hello"</span><span style="color: #007700">;
+ echo </span><span style="color: #DD0000">"World"</span><span style="color: #007700">;</span></code></pre>

3. 空格符和 Tab 不再转换成 HTML 实体

PHP 8.3 之前,高亮器(highlighter)会将空白字符转换成 &nbsp; HTML 实体,并且将 tab(\t)字符转成成四个 HTML 实体空格(&nbsp;&nbsp;&nbsp;&nbsp;)。在 PHP 8.3 及其之后,空白字符不再会改变,并且 tab 字符也会转换成 4 个标准的空白字符。

向后兼容性影响

highlight_filehighlight_string 函数的函数签名保持不变。不过请注意,使用这些函数来高亮 PHP 代码可能需要更新网络应用的 CSS,以适应这一变更,最值得注意的是<pre><code>标签对的引入。

此外,这些函数不再将换行转换成 HTML <br/> 标签。不过,由于使用了 <pre> 标签,浏览器仍然会将换行符渲染成新行。

考虑到解析 HTML 的复杂性,可能不容易地将 PHP<8.3 和 PHP>=8.3 的输出在任何一个方向上都转换成完全相同。

不过,即使在此修改后,HTML 的输出也不会有明显的不同,只要浏览器在 <pre> 标签内将换行符正确渲染,并且如果在行内高亮了 PHP 代码时,使用 CSS 渲染 <pre> 标签。以下是使用 <p> 标签让 <pre><code> 标签成为行内标签时,所推荐的一个 CSS 代码片段:

p pre {
    display: inline;
}