PHP不能直接控制水泵,需通过串口、HTTP、MQTT等中间层驱动下位机;常见方案包括shell_exec调用USB继电器工具、cURL触发ESP32 HTTP接口、或树莓派GPIO操作;PHP仅作指令中转,实时控制必须由嵌入式端完成。
PHP 本身不能直接控制物理水泵——它没有硬件 I/O 能力。所谓“PHP 控制水泵”,本质是 PHP 作为服务端逻辑,触发某个中间层(如串口、GPIO、HTTP 接口或 MQTT 指令)去操作下位机(单片机、树莓派、PLC 或智能继电器模块),最终由该设备驱动水泵电源通断。
常见低成本方案:USB 接口的固态继电器模块(如 QMK、DigiSpark 或国产 CH340 类型),附带可执行命令行工具(如 usbrelay 或厂商提供的 relayctl)。PHP 通过 shell_exec() 调用这些工具。
dmesg | grep -i usb 查看是否挂载为 /dev/ttyUSB0 等设备usermod -a -G dialout www-data(Debian/Ubuntu),然后重启 apache2 或 php-fpm
shell_exec() 前加 set_time_limit(5),并用 @ 抑制警告usbrelay --device /dev/ttyUSB0 --relay 1 --on
if (isset($_GET['action']) && $_GET['action'] === 'on') {
set_time_limit(5);
$output = shell_exec('usbrelay --device /dev/ttyUSB0 --relay 1 --on 2>&1');
echo $output ?: '已发送开启指令';
} elseif ($_GET['action'] === 'off') {
$output = shell_exec('usbrelay --device /dev/ttyUSB0 --relay 1 --off 2>&1');
echo $output ?: '已发送关闭指令';
}
更可靠、跨平台的方案:用 ESP32 烧录 MicroPython 或 Arduino 固件,接继电器,暴露一个简单 HTTP 接口(如 /control?state=on)。PHP 只需发起 GET/POST 请求。
file_get_contents() 或 curl_init() 更可控(可设超时、检查返回码)http_build_query() 构造参数,防止注入{"status":"ok","relay":1,"state":"on"},PHP 需校验 json_last_error()
$url = 'http://192.168.1.123/control?' . http_build_query(['state' => $_GET['action'] ?? 'off']);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code === 200 && !empty($response)) {
$data = json_decode($response, true);
if (json_last_error() === JSON_ERROR_NONE && $data['status'] === 'ok') {
echo "水泵已{$data['state']}";
}
}
树莓派上可通过 sysfs 或 libgpiod 控制物理引脚。PHP 直接写 /sys/class/gpio/gpioXX/value 是最简方式,但风险高。
echo 17 > /sys/class/gpio/export(17 是 BCM 编号),再设方向:echo out > /sys
/class/gpio/gpio17/direction
gpio 组,或用 sudo(不推荐);更安全做法是用 systemd service 封装 GPIO 操作,PHP 仅向其 socket 发指令value
PHP 是请求响应模型,无常驻进程、无定时器精度、无硬件中断支持。一旦网络延迟、Apache 子进程卡死或 PHP 超时,水泵可能失控(比如该关没关,导致水溢出)。
硬件控制里最危险的不是“不会写”,而是“以为写对了”。每次改动 GPIO 或串口指令前,先用终端手动验证通路;上线前至少做一次断电恢复测试——看水泵是否默认保持关闭状态。