~/notes / php-serial-port-exec

2026-02-24🐘 PHP1 мин0 просм.

PHP и COM-порт: читаем данные с устройства через exec

Когда это нужно

Иногда legacy-система написана на PHP и нужно добавить чтение данных с COM-порта — например, с весов или сканера штрихкодов. Переписывать всё на Python нет времени.

Настройка порта через stty

Перед чтением нужно настроить параметры порта:

stty -F /dev/ttyUSB0 9600 cs8 -cstopb -parenb raw

Это можно сделать прямо из PHP:

exec('stty -F /dev/ttyUSB0 9600 cs8 -cstopb -parenb raw');

Чтение данных

$port = fopen('/dev/ttyUSB0', 'r+b');
if (!$port) {
    throw new RuntimeException('Cannot open port');
}

stream_set_timeout($port, 2);
$data = fread($port, 256);
fclose($port);

echo trim($data);

Права доступа

Пользователь www-data должен быть в группе dialout:

sudo usermod -aG dialout www-data
sudo systemctl restart php8.2-fpm

Через Python как посредник

Лучший вариант для сложных протоколов — написать маленький Python-скрипт и вызывать его из PHP:

$output = shell_exec('/usr/bin/python3 /srv/scripts/read_scale.py 2>&1');
$weight = json_decode($output, true)['weight'];

Так PHP остаётся веб-слоем, а Python занимается работой с железом.

Безопасность

Никогда не передавай пользовательский ввод напрямую в exec/shell_exec. Всегда валидируй через escapeshellarg(). Лучше вообще не использовать пользовательские данные в системных командах.