PHPでは、関数がバイナリセーフであるとはどういう意味ですか?


120

PHP、それが機能することによって何を意味しているのbinary-safe

何が特別で、どこで通常使用されるのですか?

回答:


106

これは、任意のバイナリデータ(ASCII以外のバイトやnullバイトを含む文字列)を渡した場合に、関数が正しく機能することを意味します。

たとえば、非バイナリセーフ関数は、nullで終了する文字列を予期するC関数に基づいている場合があるため、文字列にnull文字が含まれている場合、関数はその後のすべてを無視します。

PHPは文字列とバイナリデータを明確に分離しないため、これは重要です。


2
これは、バイナリセーフ文字列に長さが1バイトの「文字」しか含まれていないということですか。
チャーリーパーカー、

3
@CharlieParker:いいえ、その逆です。バイナリセーフティは関数のプロパティであり文字列を正しく処理ます。逆はASCII文字のみを含む文字列になりますなしヌル文字-などの文字列は、任意の関数によって正しく処理されなければなりません。
Michael Borgwardt 2014

「バルク文字列」のredisプロトコルを読んでいて、「シングルバイナリバイナリセーフ」文字列を表すと言っていたため、混乱したかもしれません。私はあなたの投稿を正しく理解したと思います。しかし、文字列が「バイナリセーフ」であると(私が提供した例のように)意味がありますか?
チャーリーパーカー

93

他のユーザーはすでにbinary safe一般的な意味を述べました。

PHPでは、その意味はより具体的であり、Michaelが例として挙げたものにのみ言及しています。

PHPのすべての文字列には長さが関連付けられています。これは、それを構成するバイト数です。関数が文字列を操作するとき、次のいずれかを実行できます。

  1. その長さのメタデータに依存します。
  2. 文字列がnullで終了することに依存します。つまり、実際に文字列の一部であるデータの後に、値0を持つバイトが表示されます。

エンジンによって操作されるすべての文字列PHP変数もnullで終了することも事実です。2.に依存する関数の問題は、文字列自体にvalueを含むバイトが含まれている場合、0それを操作する関数は、文字列がその時点で終了したと見なし、その後のすべてを無視することです。

たとえば、PHPのstrlen関数がC標準ライブラリのように機能した場合、strlenここでの結果は正しくありません。

$str = "abc\x00abc";
echo strlen($str); //gives 7, not 3!

15
ついに例!
ラファエレ2012

5
PHP 7.0でのテストでは、strlen()関数はバイナリセーフ関数です。
linjie

@Artefacto:組み込みのPHP関数strlen()バイナリセーフな関数だと言っていますか?PHPマニュアルページでは、関数strlen()バイナリセーフ関数であるか非バイナリセーフ関数であるかについて言及されていないため、確認します。PHPマニュアルに欠けているのは、私の心に混乱をもたらしているため、確認させていただきます。ご返信を心よりお待ちしております。ありがとうございました。
PHPLover

@PHPLoverはいstrlen()はバイナリセーフです。実行php -r 'var_dump("\x00\x00\x00");'を確認するために、しかし、PHPのstrlen関数は、のためにバイナリセーフとなっている非常に(つまり「mb_overload」と呼ばれる醜態がある、と述べたが、ちょうどそれが存在していないふりをすることができます少なくともPHP 4.xのために、長い時間- php.net /manual/en/mbstring.overload.php
hanshenrik

62

その他の例:

<?php

    $string1 = "Hello";
    $string2 = "Hello\x00World";

    // This function is NOT ! binary safe
    echo strcoll($string1, $string2); // gives 0, strings are equal.

    // This function is binary safe
    echo strcmp($string1, $string2); // gives <0, $string1 is less than $string2.

?>

\x16進表記を示します。参照:PHP文字列

0x00 = NULL
0x04 = EOT (End of transmission)

ASCII文字リストを表示するためのASCIIテーブル


私が理解したことを確認するためだけに、関数がバイナリセーフである場合Hello\r\nWORLDと同じであってはなりませんHelloよね?
チャーリーパーカー、

また、そのような機能はどのように実装されていますか?バイナリが安全であることを確認する正規表現はありますか、それとも別のメソッドを使用していますか?
チャーリーパーカー

@Subscriberius:組み込み関数はstrlen() バイナリセーフですか?
PHPNut 2019
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.