在 PHP 中,chr() 是一个非常基础但常用的函数:它接受一个整数(0–255)并返回对应的单字节字符。例如 chr(65) 返回 "A"。不过在处理“特殊字符”——比如控制字符、二进制字节序列、或多字节(UTF-8)字符(例如中文、表情)时,需要理解 chr() 的局限并配合其他方法来生成期望的字符串。
下面分几个场景说明常见做法与注意事项,并给出可直接复制运行的示例。
chr() 最擅长的就是生成单字节字符:可用于生成换行、制表符、不可见控制字符或者任意 0–255 的字节值。
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// 大写 A</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">65</span></span><span>); </span><span><span class="hljs-comment">// 输出 A</span></span><span>
</span><span><span class="hljs-comment">// 换行(LF)</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"line1"</span></span><span> . </span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">10</span></span><span>) . </span><span><span class="hljs-string">"line2"</span></span><span>;
</span><span><span class="hljs-comment">// 制表符(TAB)</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"col1"</span></span><span> . </span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">9</span></span><span>) . </span><span><span class="hljs-string">"col2"</span></span><span>;
</span><span><span class="hljs-comment">// 生成二进制数据片段</span></span><span>
</span><span><span class="hljs-variable">$bytes</span></span><span> = </span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">0x00</span></span><span>) . </span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">0xFF</span></span><span>) . </span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">0x7A</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">var_dump</span></span><span>(</span><span><span class="hljs-variable">$bytes</span></span><span>); </span><span><span class="hljs-comment">// string(3) "\x00\xFFz"</span></span><span>
</span></span>
提示:当你处理二进制协议、文件头或网络包时,chr() 非常方便来构造任意字节。
如果要一次性构造多个连续的字节,pack() 比大量拼接 chr() 更简洁且性能好一些。
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// 用 pack 生成三个字节:0x01 0x02 0x03</span></span><span>
</span><span><span class="hljs-variable">$bin</span></span><span> = </span><span><span class="hljs-title function_ invoke__">pack</span></span><span>(</span><span><span class="hljs-string">'C*'</span></span><span>, </span><span><span class="hljs-number">0x01</span></span><span>, </span><span><span class="hljs-number">0x02</span></span><span>, </span><span><span class="hljs-number">0x03</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">bin2hex</span></span><span>(</span><span><span class="hljs-variable">$bin</span></span><span>); </span><span><span class="hljs-comment">// 输出 "010203"</span></span><span>
</span><span><span class="hljs-comment">// 拼接 chr 方式(等价)</span></span><span>
</span><span><span class="hljs-variable">$bin2</span></span><span> = </span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">1</span></span><span>) . </span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">2</span></span><span>) . </span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">3</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">bin2hex</span></span><span>(</span><span><span class="hljs-variable">$bin2</span></span><span>); </span><span><span class="hljs-comment">// "010203"</span></span><span>
</span></span>
chr() 只返回单字节。UTF-8 多字节字符(代码点 > 0xFF)不能直接由 chr() 生成。常用替代方法包括:
对已知 Unicode 码点(如 U+1F600 表情)可通过 HTML 实体转换为 UTF-8:
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// 使用 HTML 实体生成表情(例如 ?? U+1F600)</span></span><span>
</span><span><span class="hljs-variable">$emoji</span></span><span> = </span><span><span class="hljs-title function_ invoke__">html_entity_decode</span></span><span>(</span><span><span class="hljs-string">'&#x1F600;'</span></span><span>, ENT_NOQUOTES, </span><span><span class="hljs-string">'UTF-8'</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$emoji</span></span><span> . PHP_EOL;
</span></span>
如果服务器启用了 ext-intl,可以直接按 Unicode 代码点生成字符:
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// 需要 ext-intl</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title class_">IntlChar</span></span><span>::</span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">0x4E2D</span></span><span>); </span><span><span class="hljs-comment">// 输出 "中"</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title class_">IntlChar</span></span><span>::</span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">0x1F600</span></span><span>); </span><span><span class="hljs-comment">// 输出 ??(表情)</span></span><span>
</span></span>
已知字符的 UTF-8 十六进制字节序列时,可直接构造字节串:
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// "中" 的 UTF-8 编码是 E4 B8 AD</span></span><span>
</span><span><span class="hljs-variable">$zh</span></span><span> = </span><span><span class="hljs-title function_ invoke__">hex2bin</span></span><span>(</span><span><span class="hljs-string">'e4b8ad'</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$zh</span></span><span>; </span><span><span class="hljs-comment">// 输出 中</span></span><span>
</span><span><span class="hljs-comment">// 表情 ?? 的 UTF-8 编码是 F0 9F 98 80</span></span><span>
</span><span><span class="hljs-variable">$emoji</span></span><span> = </span><span><span class="hljs-title function_ invoke__">hex2bin</span></span><span>(</span><span><span class="hljs-string">'f09f9880'</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-variable">$emoji</span></span><span>; </span><span><span class="hljs-comment">// 输出 ??</span></span><span>
</span></span>
注意:这里 hex2bin() 直接写出 UTF-8 的字节值,适用于你已知字节序列的情况(例如来自规范或网络抓包)。
如果你有一个整数码点,需要通用函数把它转成 UTF-8 字符(不依赖额外扩展),可以自己实现简单的转换(下面为示例实现):
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">codepoint_to_utf8</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-keyword">int</span></span></span><span> </span><span><span class="hljs-variable">$cp</span></span><span>): </span><span><span class="hljs-title">string</span></span><span> {
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$cp</span></span><span> <= </span><span><span class="hljs-number">0x7F</span></span><span>) {
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-variable">$cp</span></span><span>);
} </span><span><span class="hljs-keyword">elseif</span></span><span> (</span><span><span class="hljs-variable">$cp</span></span><span> <= </span><span><span class="hljs-number">0x7FF</span></span><span>) {
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">0xC0</span></span><span> | (</span><span><span class="hljs-variable">$cp</span></span><span> >> </span><span><span class="hljs-number">6</span></span><span>)) .
</span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">0x80</span></span><span> | (</span><span><span class="hljs-variable">$cp</span></span><span> & </span><span><span class="hljs-number">0x3F</span></span><span>));
} </span><span><span class="hljs-keyword">elseif</span></span><span> (</span><span><span class="hljs-variable">$cp</span></span><span> <= </span><span><span class="hljs-number">0xFFFF</span></span><span>) {
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">0xE0</span></span><span> | (</span><span><span class="hljs-variable">$cp</span></span><span> >> </span><span><span class="hljs-number">12</span></span><span>)) .
</span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">0x80</span></span><span> | ((</span><span><span class="hljs-variable">$cp</span></span><span> >> </span><span><span class="hljs-number">6</span></span><span>) & </span><span><span class="hljs-number">0x3F</span></span><span>)) .
</span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">0x80</span></span><span> | (</span><span><span class="hljs-variable">$cp</span></span><span> & </span><span><span class="hljs-number">0x3F</span></span><span>));
} </span><span><span class="hljs-keyword">elseif</span></span><span> (</span><span><span class="hljs-variable">$cp</span></span><span> <= </span><span><span class="hljs-number">0x10FFFF</span></span><span>) {
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">0xF0</span></span><span> | (</span><span><span class="hljs-variable">$cp</span></span><span> >> </span><span><span class="hljs-number">18</span></span><span>)) .
</span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">0x80</span></span><span> | ((</span><span><span class="hljs-variable">$cp</span></span><span> >> </span><span><span class="hljs-number">12</span></span><span>) & </span><span><span class="hljs-number">0x3F</span></span><span>)) .
</span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">0x80</span></span><span> | ((</span><span><span class="hljs-variable">$cp</span></span><span> >> </span><span><span class="hljs-number">6</span></span><span>) & </span><span><span class="hljs-number">0x3F</span></span><span>)) .
</span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">0x80</span></span><span> | (</span><span><span class="hljs-variable">$cp</span></span><span> & </span><span><span class="hljs-number">0x3F</span></span><span>));
}
</span><span><span class="hljs-keyword">throw</span></span><span> </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">InvalidArgumentException</span></span><span>(</span><span><span class="hljs-string">'Invalid Unicode code point'</span></span><span>);
}
</span><span><span class="hljs-comment">// 使用</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">codepoint_to_utf8</span></span><span>(</span><span><span class="hljs-number">0x4E2D</span></span><span>); </span><span><span class="hljs-comment">// 中</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">codepoint_to_utf8</span></span><span>(</span><span><span class="hljs-number">0x1F600</span></span><span>); </span><span><span class="hljs-comment">// ??</span></span><span>
</span></span>
这个函数内部仍然使用 chr() 构造每个 UTF-8 字节,是一种纯 PHP 的通用方案。
chr() 的参数范围:只适用于单字节(0–255)。传入大于 255 的值会发生截断(取低 8 位),这通常不是你想要的行为。
编码环境:在处理多字节字符时确保字符串编码为 UTF-8 并且相关函数(例如 json_encode、strlen)时注意使用 mb_* 系列或指定正确编码。
显示与传输:某些环境(终端、HTTP 头、数据库列)对编码敏感。构造好 UTF-8 字符后,记得在输出或存储时声明正确编码(例如 HTML 页面加上 <meta charset="utf-8"> 或设置 Content-Type: text/html; charset=utf-8)。
首选工具:如果你只需要处理 Unicode 代码点,优先使用 IntlChar::chr()(若可用)或 mb_* / 转换函数,因为它们语义明确并少出错。
<span><span><span class="hljs-comment">// 单字节字符</span></span><span>
</span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">65</span></span><span>); </span><span><span class="hljs-comment">// "A"</span></span><span>
</span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">10</span></span><span>); </span><span><span class="hljs-comment">// LF 换行</span></span><span>
</span><span><span class="hljs-comment">// 多字节 / Unicode 替代</span></span><span>
</span><span><span class="hljs-title function_ invoke__">html_entity_decode</span></span><span>(</span><span><span class="hljs-string">'&#x1F600;'</span></span><span>, ENT_NOQUOTES, </span><span><span class="hljs-string">'UTF-8'</span></span><span>); </span><span><span class="hljs-comment">// ??</span></span><span>
</span><span><span class="hljs-title class_">IntlChar</span></span><span>::</span><span><span class="hljs-title function_ invoke__">chr</span></span><span>(</span><span><span class="hljs-number">0x4E2D</span></span><span>); </span><span><span class="hljs-comment">// "中"(需 ext-intl)</span></span><span>
</span><span><span class="hljs-title function_ invoke__">hex2bin</span></span><span>(</span><span><span class="hljs-string">'e4b8ad'</span></span><span>); </span><span><span class="hljs-comment">// "中"(直接用 UTF-8 十六进制字节)</span></span><span>
</span><span><span class="hljs-comment">// 自己把代码点转换为 UTF-8(见上面的 codepoint_to_utf8)</span></span><span>
</span></span>
chr() 在生成单字节(0–255)字符和二进制数据时非常简单直接;但面对多字节的 Unicode 字符(中文、emoji)时,需要配合 IntlChar::chr()、HTML 实体转换、hex2bin() 或自定义的码点到 UTF-8 转换函数来实现可靠的结果。根据你的具体场景(网络协议、文件处理、网页输出)选择合适的方法并注意编码一致性,就能稳定生成各种“特殊字符”的字符串。