Я немного стараюсь отправить шестнадцатеричное значение устройству, подключенному к моему серверу сокетов 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 ?
Это связано с тем, как PHP анализирует строки. Когда PHP анализирует первую строку, он видит «\ x7e» и говорит: «Мне нужно преобразовать это в символ, код которого равен 7е в шестнадцатеричном формате. В других сценариях он видит« \ 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));