PHP 不能直接控制硬件引脚。因其运行在 Web 服务器进程(如 Apache/PHP-FPM)中,默认无权限访问 /dev/gpiomem 或 /sys/class/gpio;即使调用 exec() 执行 shell 命令也常因 www-data 权限不足、安全模块拦截或函数被禁用而失败。
不能。PHP 是服务端脚本语言,运行在 Web 服务器进程里(如 Apache 或 PHP-FPM),默认没有权限访问底层硬件设备(如 /dev/gpiomem 或 /sys/class/gpio)。强行用 exec("echo 1 > /sys/class/gpio/gpio17/value") 会失败——不是语法错,是权限拒绝或路径不存在。
常见原因有三个:www-data 用户没权限、SELinux/AppArmor 拦截、PHP 禁用了危险函数。检查方法:
exec 在 disable_functions 中未被禁用(查 phpinfo() 或 php -i | grep disable_functions)www-data 加入 gpio 组(sudo usermod -a -G gpio www-data),并确保 /sys/class/gpio 可写(树莓派需启用 gpiomem 内核模块)sudoers 白名单授权特定命令(更安全)例如,在 /etc/sudoers 末尾加一行:
www-data ALL=(ALL) NOPASSWD: /usr/bin/gpio, /bin/sh -c echo * > /sys/class/gpio/gpio*/value
把硬件操作拆出来,用独立脚本执行,PHP 只负责发指令和展示状态。这样既安全又易调试。
/var/www/html/control.py,用 RPi
.GPIO 或 gpiozero 控制引脚,接收参数如 python3 control.py led on
exec("sudo /usr/bin/python3 /var/www/html/control.py led on 2>&1", $output, $return) 调用$_POST['action'] 分发命令sudo chmod +x /var/www/html/control.py
Web 是无状态的,用户狂点按钮会导致多次执行。解决办法:
/tmp/led.state 存 on 或 off),PHP 每次先读再决定是否执行硬件响应慢时,别依赖 JS 回调判断结果——GPIO 操作可能成功但 LED 实际没亮(接触不良、电流不足),得靠真实传感器反馈或超时重试逻辑,这点容易被忽略。