У PHP що це означає, що функція є бінарною?


120

У PHPчому ж це значить функцією бути binary-safe?

Що робить їх особливими і де вони зазвичай використовуються?

Відповіді:


106

Це означає, що функція буде правильно працювати при передачі їй довільних двійкових даних (тобто рядків, що містять не-ASCII байти та / або нульові байти).

Наприклад, небінарна безпечна функція може базуватися на функції C, яка очікує нульових кінцевих рядків, тому якщо рядок містить нульовий символ, функція буде ігнорувати що-небудь після неї.

Це актуально, оскільки PHP не чітко відокремлює рядкові та двійкові дані.


2
Чи означає це, що бінарні безпечні рядки містять лише "символи" довжиною 1 байт?
Чарлі Паркер

3
@CharlieParker: Ні, це ви отримали назад. Бінарна безпека - це властивість функцій, що означає, що вони обробляють будь-який рядок правильно. Зворотним може бути рядок, який містить лише символи ASCII і не має нульових символів - такий рядок повинен бути оброблений правильно будь-якою функцією.
Майкл Боргвардт

можливо, я заплутався, тому що я читав протокол redis для "масових рядків", і він сказав, що вони представляють собою "єдиний бінарний бінарний безпечний" рядок. Я думаю, що зараз я правильно розумію ваш пост. Однак чи має сенс говорити, що рядок є "бінарним безпечним" (як у прикладі, який я надав)?
Чарлі Паркер

93

Інші користувачі вже згадували, що binary safeозначає взагалі.

У PHP значення більш конкретне, посилаючись лише на те, що Майкл наводить як приклад.

Усі рядки в PHP мають пов’язану довжину, яка є кількістю байтів, що їх складають. Коли функція маніпулює рядком, вона може:

  1. Спирайтеся на метадані цієї довжини.
  2. Розраховуйте на те, що рядок з нульовим завершенням, тобто після того, що після даних, які є фактично частиною рядка, з'явиться байт зі значенням 0.

Правда також, що всі струнні PHP-змінні, якими маніпулює двигун, також недійсні. Проблема з функціями, які покладаються на 2., полягає в тому, що якщо сам рядок містить байт зі значенням 0, функція, яка ним маніпулює, подумає, що рядок закінчився в цій точці і проігнорує все після цього.

Наприклад, якщо strlenфункція PHP працювала як стандартна бібліотека C strlen, результат тут був би неправильним:

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

15
Нарешті приклад!
Раффаеле

5
У моєму тесті на PHP 7.0, функція strlen () є бінарною безпечною функцією.
linjie

@Artefacto: Ви хочете сказати, що вбудована функція PHP strlen()є бінарною безпечною функцією? Я підтверджую, що на сторінці керівництва PHP щодо функції strlen()не було зазначено, що це бінарно безпечна функція або небінарна безпечна функція. Ця єдина річ, що відсутня в Посібнику PHP , створює плутанину в моїй свідомості, тому я хочу підтвердити це від вас. Я з нетерпінням чекаю вашої відповіді. Спасибі.
PHPLover

@PHPLover так strlen () є бінарним безпечним. запустіть, php -r 'var_dump("\x00\x00\x00");'щоб перевірити, але strlen у strp був бінарним безпечним дуже довгий час, оскільки принаймні php 4.x (що говорив, є гидота під назвою "mb_overload", але дозволяє просто робити вигляд, що її немає - 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.

?>

\xвказує на шістнадцяткові позначення. Дивіться: Рядки PHP

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

Таблиця ASCII, щоб побачити список символів ASCII


Просто для того, щоб я зрозумів, Hello\r\nWORLDце не повинно бути таким же, як Helloякщо функція є бінарною безпечною, правда?
Чарлі Паркер

Також, як реалізується така функція? Чи є регулярний вираз, який перевіряє, чи є його бінарний сейф чи він використовує інший метод?
Чарлі Паркер

@Subscriberius: Чи вбудована функція бінарно strlen() безпечна ?
PHPNut
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.