跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

php串口通信如何发送十六进制数据_php pack函数打包hex数据发送【解答】

PHP发送十六进制数据需用pack("H*", "a1b2c3")转二进制,再写入串口设备;Linux可用file_put_contents直写/dev/ttyUSB0(需stty配置和权限),Windows需php_serial扩展或fwrite;PHP 8已弃用该扩展,推荐用Python/Node.js处理串口。 PHP 本身不直接支持串口通信,必须借助外部扩展(如
php_serial
)或系统命令(如
stty
+
echo
),而发送十六进制数据的关键在于:先用
pack()
将 hex 字符串转为二进制 字节 流,再原样写入串口设备文件(如
/dev/ttyUSB0
或
COM3
)。 如何用
pack()
把十六进制字符串转成可发送的二进制
pack()
不接受形如
"A1B2C3"
的字符串直接转换,必须先拆分成字节对,再用
"H*"
或
"H2"
格式打包。常见错误是误用
hex2bin()
(PHP ≥ 5.4.0 才有)却忽略其对非法字符的严格校验。
pack("H*", "a1b2c3")
→ 正确:把整个 hex 字符串按两位一组解析为字节
pack("H2", "a1", "b2", "c3")
→ 错误:
"H2"
每次只取一个参数的前两位,多参数会截断或报错
hex2bin("a1b2c3")
→ 可用,但遇到空格、非十六进制字符(如
"A1 B2"
)会返回
false
,需提前
str_replace(" ", "", $hex)
和
ctype_xdigit()
校验 Linux 下绕过扩展,用
file_put_contents()
直写串口设备 前提是串口设备已配置好(波特率、停止位等由
stty
设置),且 PHP 进程有设备文件写权限(常需加到
dialout
用户组)。此时发送就是写二进制流,和普通文件无异。
file_put_contents("/dev/ttyUSB0", pack("H*", "02010400ff")); // 发送 6 字节:0x02 0x01 0x04 0x00 0xff
必须确保
/dev/ttyUSB0
已被
stty -F /dev/ttyUSB0 9600 cs8 -cstopb -parenb
配置好,否则数据会乱或丢 写入后建议
usleep(10000)
等待硬件发出,尤其对低速设备(如 1200bps) Windows 下对应路径是
COM3
,但需用
fopen("COM3", "wb")
,且不能用
file_put_contents()
直写(会失败) Windows 下用
php_serial
扩展发送 hex 数据的典型流程 该扩展已多年未更新,仅兼容 PHP 5.x 和旧版 VC 编译器,PHP 7+ 基本不可用。若强行使用,核心是:打开 → 配置 →
sendMessage()
传入
pack()
结果。 PHP 8.5.5 PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。 下载 立即学习 “ PHP免费学习笔记(深入) ”;
$serial = new phpSerial(); $serial->deviceSet("COM3"); $serial->confBaudRate(9600); $serial->confParity("none"); $serial->confCharacterLength(8); $serial->confStopBits(1); $serial->deviceOpen(); $serial->sendMessage(pack("H*", "aa5500ff")); // 发送 4 字节 $serial->deviceClose();
扩展内部未做二进制安全处理,若
pack()
结果含
\x00
,可能被 C 层截断(因误判为字符串结尾) 更稳妥做法是用
fwrite()
替代
sendMessage()
:获取资源句柄后
fwrite($fp, pack("H*", "aa55"))
PHP 8 完全放弃该扩展,推荐改用 Python/Node. js 处理串口,PHP 只做业务逻辑 真正容易卡住的地方不是
pack()
用法,而是串口设备的硬件层配置是否生效、权限是否到位、以及发送后有没有等待足够时间让设备完成物理传输——这些在脚本里看不见,却决定数据发没发出去。

相关文章