← PHP chop()函数:从字符串右端移除空白与指定字符教程 PHP chunk_split()函数:把字符串按固定长度切分成块 →

PHP chr()函数:由ASCII码值生成单字节字符教程

著
原创 2026-10-10 PHP 已有人查阅

一、chr()做了什么

chr()接收一个整数,返回该整数对应ASCII码值的一个字符。返回值是一个单字节字符串。

语法:

string chr ( int $bytevalue )
参数 说明 是否必填
bytevalue ASCII码值,整数 必填

核心逻辑很直接:给一个数字,还一个字符。它是ord()的逆操作,ord()把字符转成ASCII码值,chr()把码值还原成字符。

这里有一个容易被忽略的点:chr()返回的是单字节字符串。ASCII范围是0到255,超出这个范围的值会被按256取模处理。也就是说,chr(300)等价于chr(300%256),结果是chr(44),即逗号。这一点在多字节字符场景下会带来困惑——你不能用chr()生成一个汉字,因为汉字在UTF-8下占3个字节。

关键词提示:PHPchr函数、ASCII转字符、ord逆操作、单字节字符串。

二、参数的三种进制写法

PHP的整数支持十进制、八进制、十六进制三种字面量写法,chr()的参数同样适用。不同写法传入的是同一个数值,结果一致。

十进制写法

<?php
$char = 52;
echo "原始数值:" . $char . "<br>";
echo "chr() 结果:" . chr($char);
?>

输出:

原始数值:52
chr() 结果:4

十进制52对应字符4。

八进制写法

八进制以0开头。

<?php
$char = 052;
echo "原始数值:" . $char . "<br>";
echo "chr() 结果:" . chr($char);
?>

输出:

原始数值:42
chr() 结果:*

注意这里的输出细节:$char=052是八进制写法,PHP在字符串拼接时会把它按十进制显示为42。八进制52等于十进制42,对应字符*。如果不了解进制前缀规则,看到输出42却得到*,会感到莫名其妙。

十六进制写法

十六进制以0x开头。

<?php
echo "原始数值:0x52<br>";
echo "chr() 结果:" . chr(0x52);
?>

输出:

原始数值:0x52
chr() 结果:R

十六进制0x52等于十进制82,对应字符R。

三种写法汇总:

写法 字面量 十进制值 对应字符
十进制 52 52 4
八进制 052 42 *
十六进制 0x52 82 R

踩坑经历:早期在解析一个协议文档时,文档里写的是0x0A,我顺手写成chr(0A),结果PHP把0A当成八进制解析,报语法错误。十六进制必须带0x前缀,八进制是前导0,十进制不带前缀,这个规则在chr()参数上同样适用,写的时候多看一眼。

三、用chr()拼接可读输出

chr()的一个实用场景是生成那些键盘上不好直接输入、或者需要动态计算的字符。

<?php
$plus = chr(43);   // +
$equal = chr(61);  // =
echo "2 $plus 2 $equal 4";
?>

输出:

2 + 2 = 4

ASCII43是加号,61是等号。这种写法在生成表达式、构造动态提示文本时可以用,但说实话,能用字面量'+'和'='直接写的地方,没必要绕一圈用chr()。chr()的价值在于数值是动态计算出来的时候,而不是写死一个已知字符。

更合理的用法是这样:

<?php
// 根据数值动态生成对应的字母
for ($i = 65; $i <= 70; $i++) {
    echo chr($i) . " ";
}
?>

输出:

A B C D E F

ASCII65到90是大写字母A到Z,97到122是小写字母a到z。需要按序号生成字母时,chr()比维护一个字母表数组更省事。

四、chr()与ord()的互逆关系

ord()返回字符串第一个字节的ASCII码值,是chr()的反向操作。

<?php
$char = 'A';
$code = ord($char);
echo "字符 A 的 ASCII 码值:" . $code . "<br>";
echo "码值 65 还原为字符:" . chr($code);
?>

输出:

字符 A 的 ASCII 码值:65
码值 65 还原为字符:A

两者的对照关系:

函数 输入 输出
ord() 字符(取首字节) ASCII码值
chr() ASCII码值 单字节字符

注意ord()只取第一个字节。对于UTF-8中文,ord("中")返回的是第一个字节的值,不是完整的码点。要处理多字节字符,需要用mb_ord()配合mb_chr(),这是另一组函数。

个人建议:单字节场景用chr()/ord(),多字节场景用mb_chr()/mb_ord()。混用会导致中文处理出问题,这个分界线要划清楚。

五、项目场景

场景一:生成控制字符

换行、制表符、回车这些控制字符,可以用chr()生成,也可以用转义序列\n、\t、\r。两者等价,但动态场景下chr()更灵活。

<?php
$lf = chr(10);   // \n 换行
$tab = chr(9);   // \t 制表符
echo "第一行" . $lf . "第二行" . $tab . "制表位";
?>

在拼接来自配置文件的控制字符码值时,chr()让代码保持数值驱动。

场景二:按码值表生成字符集

验证码字符集、测试数据生成器等场景,需要按ASCII区间批量产出字符。

<?php
$chars = '';
for ($i = 48; $i <= 57; $i++) {
    $chars .= chr($i);
}
echo "数字字符集:" . $chars;
?>

输出:

数字字符集:0123456789

ASCII48到57是数字0到9。

场景三:协议数据构造

在拼接自定义二进制协议时,某些字段需要按字节值填充。

<?php
$header = chr(0x02) . chr(0x01) . chr(0x00);
echo "协议头 hex:" . bin2hex($header);
?>

输出:

协议头 hex:020100

用chr()生成字节,再用bin2hex()观察结果,是调试协议数据的常见组合。这里chr()配合bin2hex()比直接拼字符串更可控。

反思:曾经在一个串口通信项目里,同事直接把数值强转成字符串拼接,0x02变成了字符"2",协议解析全乱。字节值要用chr()生成,不能用数值的字符串形式,这个区别在处理二进制协议时必须分清。

六、本节课程知识要点

  1. chr()由ASCII码值返回单字节字符,是ord()的逆操作。

  2. 参数支持十进制、八进制(前导0)、十六进制(0x前缀)三种写法。

  3. 超出0-255范围的值按256取模处理。

  4. chr()只生成单字节,多字节字符需用mb_chr()。

  5. 动态生成字母、数字、控制字符时用chr()比维护字符表更简洁。

  6. 处理二进制协议字节时,用chr()生成而非数值强转字符串。

七、常见问题

Q:chr(0)返回什么?

A:返回NUL字节,是一个长度为1的字符串,不是空字符串。strlen(chr(0))等于1。这个区别在比较和拼接时要注意。

Q:为什么chr(300)不报错?

A:PHP对超出范围的值按256取模,chr(300)等价于chr(44),返回逗号。这是历史行为,不是错误。

Q:chr()能生成中文吗?

A:不能直接生成。UTF-8下一个汉字占3个字节,需要拼接3次chr()或者用mb_chr()。直接用chr()传一个汉字的Unicode码点,结果不会正确。

chr()是PHP中处理单字节字符与码值转换的基础函数,逻辑简单,但进制写法、取模行为、单字节限制这几个边界需要清楚。它适合动态生成字母、数字、控制字符以及协议字节,配合ord()可以完成字符与码值的双向转换。遇到多字节字符时,切换到mb_chr()/mb_ord()这一组函数。写代码时先判断场景是单字节还是多字节,再选函数,能避免不少隐蔽问题。

← PHP chop()函数:从字符串右端移除空白与指定字符教程 PHP chunk_split()函数:把字符串按固定长度切分成块 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号