PHP解包()的意外行为 测验 $x=sprintf(“foo\x00bar\x00baz”); $y=拆包('afoo/abar/abaz',$x); 印刷品(元);; $x=sprintf(“foo\x00bar\x00baz”); $y=拆包('a*foo/a*bar/a*baz',$x); 印刷品(元);; 结果 笔记

PHP解包()的意外行为 测验 $x=sprintf(“foo\x00bar\x00baz”); $y=拆包('afoo/abar/abaz',$x); 印刷品(元);; $x=sprintf(“foo\x00bar\x00baz”); $y=拆包('a*foo/a*bar/a*baz',$x); 印刷品(元);; 结果 笔记,php,unpack,Php,Unpack,我知道我可以使用explode获得类似的结果。我不是在问其他选择,我只是想了解a格式字符(如doc所说的“NUL填充字符串”)背后的逻辑 “NULL”值在哪里涉及到这一切?原始答案 “NULL”值在哪里涉及到所有这些?” 没有 我非常确定PHP pack()/unpack()的文档需要更新。基本上,无论您在哪里看到它引用以NULL结尾的字符串,文档都是从Perl版本的代码中获取的,并不是PHP中发生的事情的反映 基本上,Perl有C风格的字符串,可以以null结尾,让您知道字符串的结尾在哪里。在

我知道我可以使用
explode
获得类似的结果。我不是在问其他选择,我只是想了解
a
格式字符(如doc所说的“NUL填充字符串”)背后的逻辑

“NULL”值在哪里涉及到这一切?

原始答案 “NULL”值在哪里涉及到所有这些?”

没有

我非常确定PHP pack()/unpack()的文档需要更新。基本上,无论您在哪里看到它引用以NULL结尾的字符串,文档都是从Perl版本的代码中获取的,并不是PHP中发生的事情的反映

基本上,Perl有C风格的字符串,可以以null结尾,让您知道字符串的结尾在哪里。在PHP中,没有空字符的概念。e、 g

$test1 = "Test".NULL."ing";
$test2 = "Testing";

if(strcmp($test1, $test2) == 0){
    echo "The strings are the same";
}
else{
    echo "They are different.";
}
function strToHex($string){
    $hex='';
    for ($i=0; $i < strlen($string); $i++)
    {
        $hex .= dechex(ord($string[$i]));
    }
    return $hex;
}

$binarydata = "foo\x00bar\x00baz";

echo "binarydata is ";

var_dump($binarydata);
$y = unpack( 'a3foo/a3bar/a3baz' , $binarydata);
var_dump( $y );

echo strToHex($y['foo'])."\r\n";
echo strToHex($y['bar'])."\r\n";
echo strToHex($y['baz'])."\r\n";
将打印“字符串相同”

顺便说一句: “foo\x00bar\x00baz”

可能没有做你认为它在做的事情。它不会在foo+bar和bar+baz之间的字符串中放置“NULL”字符,因为没有NULL字符。取而代之的是字符“0”,它恰好在大多数字符集中没有打印出来,但作为一个字符没有特殊意义

我知道您提到使用explode而不是unpack,但如果您知道字符串长度,则可以使用:

unpack( 'a3foo/a3bar/a3baz' , $binarydata);
为清晰起见,添加 赛勒斯写道:

“空字节”是指值为0的字节:

我不确定字符串“foo\x00bar\x00baz”是从哪里来的,但是:

i) 它必须来自支持由零表示的空字符的语言。PHP不支持空字符,如果调用 包装(“A*A*A*”、“foo”、“bar”、“baz”); 它不会生成包含零的字符串

ii)解包的PHP版本不支持空字符(因为PHP不支持空字符),并将十六进制值为0的字符视为另一个字符。e、 g

$test1 = "Test".NULL."ing";
$test2 = "Testing";

if(strcmp($test1, $test2) == 0){
    echo "The strings are the same";
}
else{
    echo "They are different.";
}
function strToHex($string){
    $hex='';
    for ($i=0; $i < strlen($string); $i++)
    {
        $hex .= dechex(ord($string[$i]));
    }
    return $hex;
}

$binarydata = "foo\x00bar\x00baz";

echo "binarydata is ";

var_dump($binarydata);
$y = unpack( 'a3foo/a3bar/a3baz' , $binarydata);
var_dump( $y );

echo strToHex($y['foo'])."\r\n";
echo strToHex($y['bar'])."\r\n";
echo strToHex($y['baz'])."\r\n";

i、 e.它提取前三个字符,即值0x66、0x6f、0x6f。然后提取接下来的三个字符,即0x0、0x62、0x61。最后,它提取值0x72、0x0、0x62。

如果您不知道字符串长度,我不知道如何使用unpack。它在Perl中受支持,但显然不是PHP,所以我问了一个问题,我同意这些糟糕的文档。。。但是请注意,<代码>“test \x00 ing”和<代码>“test”。NULL“ING”绝对不是同一事物。是的,我的观点是,它们都不会导致中间有空的字符串,所以当您说“注意null字节总是存在”时,您可能将字符0与NULL混淆。我指的是值为0的字节:
php-r'echo“foo\x00bar\x00baz”;'高清
function strToHex($string){
    $hex='';
    for ($i=0; $i < strlen($string); $i++)
    {
        $hex .= dechex(ord($string[$i]));
    }
    return $hex;
}

$binarydata = "foo\x00bar\x00baz";

echo "binarydata is ";

var_dump($binarydata);
$y = unpack( 'a3foo/a3bar/a3baz' , $binarydata);
var_dump( $y );

echo strToHex($y['foo'])."\r\n";
echo strToHex($y['bar'])."\r\n";
echo strToHex($y['baz'])."\r\n";
binarydata is string(11) "foobarbaz"
array(3) {
  ["foo"]=>
  string(3) "foo"
  ["bar"]=>
  string(3) "ba"
  ["baz"]=>
  string(3) "rb"
}
666f6f
06261
72062