PHP无法直接读取BH1750传感器数据,因其无原生I²C驱动能力,file_get_contents()等函数不能访问I²C总线,需依赖Linux系统调用i2c-tools或内核模块配合解析原始数据。

PHP 本身不能直接读取 BH1750 这类 I²C 接口的光照传感器数据——它没有原生 I²C 驱动能力,也不直接访问硬件总线。必须借助底层系统(如 Linux)和外部工具/扩展协同完成。
为什么 PHP 不能直接用 file_get_contents() 或 fopen() 读 BH1750
BH1750 是 I²C 设备,地址通常为 0x23 或 0x5C,它的寄存器不映射到普通文件路径;Linux 下需通过 /dev/i2c-X 设备节点 + ioctl 控制,而 PHP 标准函数无法发起 I²C 读写请求。
- 尝试读取类似
/sys/class/i2c-adapter/i2c-1/1-0023/light的路径?该路径不存在——BH1750 内核驱动默认不提供 sysfs 接口,除非你手动加载了bh1750模块且内核配置支持 - 用
exec("i2cget -y 1 0x23 0x00")?可能失败:权限不足、i2c-tools未安装、PHP 运行用户(如 www-data)不在i2c用户组 - 即使命令成功,返回的是原始 2 字节十六进制值,还需按 BH1750 数据手册做左移、除法换算(如
lux = (high )
可行方案:用 Python 脚本封装 I²C 读取,PHP 调用它
这是最稳定、无需编译扩展的方式。Python 的 smbus2 库可直接操作 I²C,PHP 只需执行并解析结果。
先确保环境就绪:
立即学习“PHP免费学习笔记(深入)”;
- 树莓派等 Linux 设备已启用 I²C:
sudo raspi-config → Interface Options → I2C → Yes - 安装依赖:
sudo apt install python3-pip && pip3 install smbus2 - 将运行 PHP 的用户(如 www-data)加入 i2c 组:
sudo usermod -a -G i2c www-data,然后重启 web 服务
#!/usr/bin/env python3 # save as /opt/read_bh1750.py import smbus2 import sysdef read_lux(): bus = smbus2.SMBus(1) # 使用 I2C-1 总线 addr = 0x23 try:
发送测量命令(连续高分辨率模式)
bus.write_byte(addr, 0x10) time.sleep(0.120) # 等待测量完成 # 读取 2 字节数据 data = bus.read_i2c_block_data(addr, 0x00, 2) lux = ((data[0] << 8) | data[1]) / 1.2 print(f"{lux:.2f}") except Exception as e: print("ERROR") finally: bus.close()if name == "main": read_lux()
PHP 中调用:
如果坚持用 PHP 扩展:必须用
php-smbus(仅限 Linux)这是一个 C 编写的 PHP 扩展,封装了
linux/i2c-dev.h,但维护少、PHP 8+ 兼容性差,且需手动编译。
- GitHub 项目:
https://github.com/mikeryan/php-smbus(注意 fork 活跃度) - 编译前确认已安装
php-dev、libi2c-dev - 启用后函数为
smbus_open(1)、smbus_read_word_data($fd, $addr, 0x00),返回值仍是原始整数,仍需自己换算 lux - 常见报错:
Permission denied(没加组)、Invalid argument(地址或寄存器错)、Resource temporarily unavailable(总线忙)
真正卡住的点往往不是代码,而是 I²C 总线权限、传感器物理连接(上拉电阻是否接 4.7kΩ 到 3.3V)、以及 BH1750 是否处于正确测量模式(单次/连续)。建议先用 i2cdetect -y 1 确认设备在线,再用 i2cget -y 1 0x23 0x00 w 手动验证原始值,最后才让 PHP 参与。











