Отправить как hex в PHP

Я немного пытаюсь отправить шестнадцатеричное значение на устройство, подключенное к моему серверу PHP-сокетов.

У меня есть этот код:

<?PHP

# 7e hex = 126 decimal

$str1 = "\x7e\x00MyData";
sendToDevice($str1); // works :-)
# will send "~<NUL>MyData" and the device sends expected result back

$dec = 126;
$hex = dechex($dec);
$str2 = $hex . "\x00MyData";
sendToDevice($str2); // does not work :-/
# will send "7eMyData" and the device sends nothing back

$dec = 126;
$hex = dechex($dec);
$str3 = "\x$hex\x00MyData";
sendToDevice($str3); // does not work :-/
# will send "\x7e<NUL>MyData" and the device sends error report back

?>

Как я могу отправить его, чтобы он работал как с $ str1?

2 ответа

Решение

Это связано с тем, как PHP анализирует строки. Когда PHP анализирует первую строку, он видит "\x7e" и говорит: "Мне нужно преобразовать это в символ, код которого равен 7e в шестнадцатеричном формате. В других сценариях он видит"\x"и пытается преобразовать это прежде чем он получит "7e", поэтому он не знает, что делать.

PHP не анализирует строки во второй раз.

В этой ситуации вам нужно преобразовать свое число в символьное представление, а не в шестнадцатеричный код. Что вам нужно, так это функция chr(). Вы должны быть в состоянии сделать что-то вроде этого:

$dec = 127;
$str2 = chr($dec) . "\x00MyData";
sendToDevice($str2);

Обратите внимание, что он вообще пропускает шестнадцатеричное преобразование. Также обратите внимание, что это работает, только если ваше значение $dec <= 255. Если у вас есть более высокие значения, вам нужно создать свою собственную функцию, чтобы разбить ее на несколько символов.

Третий подход не так далеко. Но остающаяся проблема заключается в том, что \x будет интерпретироваться как escape-последовательность в строках с двойными кавычками. Обход проблемы: используйте одинарные кавычки:

$dec = 127;
$hex = dechex($dec);
$str3 = '\x' . $hex . '\x00MyData';
sendToDevice($str3);

Более простое решение, которое не нужно dechex() будет использовать sprintf() так как он имеет внутреннюю поддержку для преобразования десятичных значений в шестнадцатеричные значения. Теперь это может быть даже однострочник

sendToDevice(sprintf('\x%x\x00MyData', $dec));
Другие вопросы по тегам