2010-12-31 13 views
14

W PHP, jeśli posiadasz zmienną z danymi binarnymi, w jaki sposób otrzymujesz określone bajty z danych? Na przykład, jeśli mam jakieś dane o długości 30 bajtów, w jaki sposób mogę uzyskać pierwsze 8 bajtów?Obsługa bajtów w PHP

Teraz jestem traktując go jak struna, używając substr() funkcję:

$data = //... 
$first8Bytes = substr($data, 0, 8); 

jest to bezpieczne w użyciu substr z danych binarnych?

Czy są inne funkcje, których powinienem używać?

+0

To znaczy, jeśli są to dane binarne? – BoltClock

+0

@BoltClock Tak, zgadza się. – Michael

Odpowiedz

6

Ogólnie wszystkie funkcje napisów w PHP są bezpieczne w użyciu z surowymi bajtami. Problem, który w większości pojawiają się, to puste bajty, ale tylko dla funkcji systemu plików: http://php.net/manual/en/security.filesystem.nullbytes.php

Twój substr() jest całkowicie w porządku, aby używać go z ciągami binarnymi. Niektóre inne funkcje, takie jak strtok i ereg są jednak interfejsem C, gdzie znak "\ 0" staje się problemem.

+0

Dzięki, jedyną funkcją napisu, której używam, jest 'substr'. Co jeśli PHP jest skonfigurowane do używania UTF-16 dla jego ciągów, gdzie każdy znak ma> 1 bajt? – Michael

+0

@MichaelAngstadt. Uznałbym to za błędną konfigurację, a nie za ostrożność. O ile warto "mb_substr" ("\ 0 \ 0 \ 0 \ 0", 0, 2) "wydaje się działać dla UTF-8. W przypadku UTF-16 zwraca jednak dwukrotnie większy rozmiar, zgodnie z oczekiwaniami. Tak więc bardziej prawdopodobne jest, że nie powiedzie się przetwarzanie kontynuacji w tych warunkach. – mario

+0

Oh, więc 'substr' będzie ZAWSZE przyjmować 1 znak jako 1 bajt, podczas gdy' mb_substr' uwzględnia kodowanie znaków? Brzmi jakbym był bezpieczny używając 'substr' bez względu na kodowanie znaków. – Michael

3

brzmi dobrze od PHP zajmuje łańcuchy (wewnętrznie) "jak" C char * (1byte = 1char)

Z drugiej strony, może być uszkodzony, jeśli łańcuch znaków w kodowaniu Unicode (2 bajtów = 1 znak)

Uwaga: można również grać z paczki() i rozpakować(), aby manipulować „prawdziwy” bajty

+0

@Stef Dzięki, tak, to jedna rzecz, o którą się martwiłem ... co jeśli PHP jest skonfigurowane tak, aby obsługiwać coś takiego jak UTF-16 dla jego ciągów? – Michael

+1

@Michael: Nie postawiłbym na to. – BoltClock

+0

Tak, ja też, ale kto wie, może być w 2011 słynny php 6.0;) – Stef

9

Jeśli mbstring extension jest zainstalowany i mbstring overloading jest włączona, a następnie za pomocą substr może sprawić kłopoty. Przeciążenie Mbstring spowoduje automatyczne wywołanie mb_substr za każdym razem, gdy wywoływane jest substr (jeśli mbstring jest zainstalowany i przeciążenie mbstringa to wyłączone, to substr będzie poprawnie pobierać bajty). Poniższy kod będzie używał mb_substr, jeśli mbstring jest zainstalowany i substr, jeśli tak nie jest. Użyte zostanie kodowanie znaków "8bit", które potraktuje każdy znak jako 1 bajt i zignoruje terminatory kończące ("\ 0").

if (function_exists('mb_substr')) { 
    $bytes = mb_substr($string, 0, 8, '8bit'); 
} else { 
    $bytes = substr($string, 0, 8); 
} 

Thanks to ircmaxell

+0

Czy możesz wyjaśnić, co masz na myśli przez "zignoruje terminatory kończące". Byłby to przełom w manipulowaniu danymi, gdyby był prawdziwy. Zrobiłem kilka testów i nie widzę, żeby ignorowało \ 0 znaków. (Edytuj) Och, właśnie czytam czat. Masz na myśli "ascii". Zatem użycie "8bit" ** nie ** zignoruje terminatorów o wartości zerowej. – Phil

Powiązane problemy