PHP에서 함수가 바이너리 안전하다는 것은 무엇을 의미합니까?


120

에서 PHP무엇 함수가 됨으로써 의미합니까 binary-safe?

그것들을 특별하게 만드는 것은 무엇이며 일반적으로 어디에 사용됩니까?

답변:


106

이는 임의의 이진 데이터 (예 : 비 ASCII 바이트 및 / 또는 널 바이트를 포함하는 문자열)를 전달할 때 함수가 올바르게 작동 함을 의미합니다.

예를 들어, 바이너리 안전이 아닌 함수는 null로 끝나는 문자열을 예상하는 C 함수를 기반으로 할 수 있으므로 문자열에 null 문자가 포함 된 경우 함수는 그 이후의 모든 것을 무시합니다.

이것은 PHP가 문자열과 이진 데이터를 명확하게 분리하지 않기 때문에 관련이 있습니다.


2
이진 안전 문자열에 길이가 1 바이트 인 "문자"만 포함된다는 의미입니까?
Charlie Parker

3
@CharlieParker : 아니요, 거꾸로 가져 왔습니다. 바이너리 안전성은 모든 문자열을 올바르게 처리한다는 것을 의미 하는 함수 의 속성입니다 . 반대로 ASCII 문자 만 포함 하고 널 문자는없는 문자열이됩니다. 이러한 문자열은 모든 함수에서 올바르게 처리되어야합니다.
Michael Borgwardt

"대량 문자열"에 대한 redis 프로토콜을 읽고 "단일 이진 바이너리 안전"문자열을 나타낸다고해서 혼란 스러웠을 것입니다. 이제 귀하의 게시물을 올바르게 이해 한 것 같습니다. 그러나 문자열이 "이진 안전"이라고 말하는 것이 합리적입니까 (제가 제공 한 예에서와 같이)?
Charlie Parker

93

다른 사용자가 이미 언급 한 내용 binary safe 일반적인 의미를 했습니다.

PHP에서 의미는 더 구체적이며 Michael이 예로 든 것만 언급합니다.

PHP의 모든 문자열에는 길이가 연결되어 있으며, 이는이를 구성하는 바이트 수입니다. 함수가 문자열을 조작 할 때 다음 중 하나를 수행 할 수 있습니다.

  1. 그 길이의 메타 데이터에 의존하십시오.
  2. 문자열로 끝나는 문자열에 의존합니다. 즉, 실제로 문자열의 일부인 데이터 뒤에 값 0이 있는 바이트 가 나타납니다.

엔진이 조작하는 모든 문자열 PHP 변수도 null로 끝나는 것도 사실입니다. 2에 의존하는 함수의 문제는 문자열 자체에 value가있는 바이트가 포함되어 있으면이를 0조작하는 함수는 문자열이 해당 지점에서 끝났다고 생각하고 그 이후의 모든 것을 무시한다는 것입니다.

예를 들어, PHP가 strlen 함수가 C 표준 라이브러리처럼 작동 과 같은 strlen결과는 잘못된 것입니다.

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

15
마지막으로 예!
Raffaele

5
PHP 7.0의 테스트에서 strlen () 함수는 바이너리 안전 함수입니다.
linjie

@Artefacto : 내장 된 PHP 함수 strlen()바이너리 안전 함수라는 말입니까? 함수 에 대한 PHP 매뉴얼 페이지 strlen()에서 바이너리 안전 함수인지 바이너리아닌 안전한 함수 인지에 대해 언급되지 않았기 때문에 확인 했습니다 . PHP 매뉴얼 에서 유일하게 빠진 것은 내 마음에 혼란을 일으키는 것이므로 확인하고 싶습니다. 나는 당신의 대답을 간절히 기다리고 있습니다. 감사합니다.
PHPLover

@PHPLover yes 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.
Charlie Parker

또한 이러한 기능은 어떻게 구현됩니까? 바이너리가 안전한지 확인하는 정규식이 있습니까? 아니면 다른 방법을 사용합니까?
Charlie Parker

@Subscriberius : 내장 함수는 strlen() 바이너리 안전 합니까?
PHPNut
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.