json_encode () unikając ukośników

165

Pobieram JSON z Instagrama:

$instagrams = json_decode($response)->data;

Następnie analizuje zmienne w tablicy PHP w celu zmiany struktury danych, a następnie ponownie koduje i buforuje plik:

file_put_contents($cache,json_encode($results));

Kiedy otwieram plik pamięci podręcznej, wszystkie moje ukośniki „/” są zmieniane:

http:\/\/distilleryimage4.instagram.com\/410e7...

Wychodzę z moich wyszukiwań, że json_encode()automatycznie robi to ... czy istnieje sposób, aby to wyłączyć?

Michael C.
źródło
2
Jest opcjonalne: „znaki, które muszą zostać zmienione: cudzysłów, odwrócone solidus i znaki sterujące (od U ​​+ 0000 do U + 001F). Każdy znak może zostać zmieniony”.
ThiefMaster

Odpowiedzi:

285

czy jest sposób, aby to wyłączyć?

Tak, wystarczy użyć JSON_UNESCAPED_SLASHESflagi.

! ważne przeczytaj wcześniej: https://stackoverflow.com/a/10210367/367456 (wiedz, z czym masz do czynienia - poznaj swojego wroga)

json_encode($str, JSON_UNESCAPED_SLASHES);

Jeśli nie masz pod ręką PHP 5.4, wybierz jedną z wielu istniejących funkcji i zmodyfikuj je do swoich potrzeb, np. Http://snippets.dzone.com/posts/show/7487 (kopia archiwalna) .

Przykładowe demo

<?php
/*
 * Escaping the reverse-solidus character ("/", slash) is optional in JSON.
 *
 * This can be controlled with the JSON_UNESCAPED_SLASHES flag constant in PHP.
 *
 * @link http://stackoverflow.com/a/10210433/367456
 */    

$url = 'http://www.example.com/';

echo json_encode($url), "\n";

echo json_encode($url, JSON_UNESCAPED_SLASHES), "\n";

Przykładowe dane wyjściowe:

"http:\/\/www.example.com\/"
"http://www.example.com/"
hakre
źródło
2
Ta odpowiedź jest wdzięczna, ale kodowanie JSON jako standard należy pozostawić jako uciekłe, a następnie w końcu odzyskującym cofnąć uciekające php strip_slashesi dla JS phpjs.org/functions/stripslashes
Barkermn01
1
@MartinBarker: To mógł być problem tylko z PHP 5.2.1: 3v4l.org/0AahO - JSON jest poprawny w obu przypadkach.
hakre
@MartinBarker Z jakiegoś dziwnego powodu ukośnik nie był usuwany na końcu odbierającym za pomocą stripslashes (), str_replace () lub preg_replace (). Zanim znalazłem tę odpowiedź, zhakowałem sposób na pozbycie się ukośnika, używając urlencode (), a następnie zastępując% 2F. Używam PHP7 w systemie Windows. Nie jestem pewien, czy w jakimś miejscu jest błąd, ale magiczne cudzysłowy nie są nawet zawarte w PHP7, więc lepiej uniknąć hakerów, po prostu wyłączając ukośniki.
Sami Fouad
@SamiFouad: Nawet z ukośnikiem jest to poprawny JSON i nie powinien powodować żadnych problemów (chyba że odbiornik nie obsługuje poprawnie JSON, patrz json.org , szczególnie opis znaku po prawej stronie, który wyraźnie określa \/jako prawidłową sekwencję ucieczki /) , zobacz również stackoverflow.com/a/10210367/367456 .
hakre
Brzydki PHP! JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHESdomyślna musi być, a nie (dziwne) opcja ... Jak to powiedzieć do php-deweloperów?
Peter Krauss,
45

Tak , ale nie rób tego - unikanie cięć do przodu to dobra rzecz . W przypadku używania <script>tagów JSON wewnątrz tagów konieczne jest, aby </script>gdziekolwiek - nawet wewnątrz ciągu znaków - zakończył tag skryptu.

W zależności od tego, gdzie jest używany JSON, nie jest to konieczne, ale można je bezpiecznie zignorować.

ThiefMaster
źródło
5
Czy javascript automatycznie usunie ukośniki odwrotne, gdy pobierze json, czy to coś, co muszę określić?
Michael C.
5
Automatycznie sobie z tym poradzi. Podobnie jak w wielu innych językach, unikanie znaków bez specjalnego znaczenia w języku pozostawia te znaki w spokoju.
ThiefMaster
19
@MichaelC. W formacie JSON wartość ciągu "\/"jest dokładnie taka sama jak wartość ciągu "/"- i działający parser JSON potraktuje ją jako taką. Ta sama zasada dotyczy ciągów javascript, więc podawanie JSON jako kodu javascript również nie sprawi żadnych problemów. Dziwię się, że PHP ma nawet JSON_UNESCAPED_SLASHESflagę.
Esailija
4
Ale co, jeśli ktoś koduje dane w formacie JSON, a następnie przechowuje je w kolumnie bazy danych? Jeśli program ma jakiś mechanizm zmiany znaczenia znaków ze względu na bazę danych, czy ta funkcja nie byłaby bardzo niewygodna, ponieważ teraz ukośniki są znakowane podwójnie?
Xavier_Ex
5
Wrzucanie kodu JSON do tagów skryptu bez etapu kodowania przy założeniu, że implementacja JSON unikała ukośników, wydaje się praktyką, która z pewnością Cię ugryzie.
Ryan
3

Z drugiej strony miałem problem z potwierdzaniem przez PHPUNIT, że adresy URL były zawarte w adresie URL, który był kodowany w formacie json_encoded lub równe temu -

moje oczekiwane:

http://localhost/api/v1/admin/logs/testLog.log

zostanie zakodowany do:

http:\/\/localhost\/api\/v1\/admin\/logs\/testLog.log

Jeśli chcesz zrobić porównanie, przekształcając adres URL za pomocą:

addcslashes($url, '/')

pozwoliło na prawidłowe wyjście podczas moich porównań.

Eskadry
źródło
0

Musiałem zmierzyć się z sytuacją jako taką i po prostu z

str_replace("\/","/",$variable)

zadziałało dla mnie.

Anton De Rose
źródło
-1

Nie musisz uciekać przed ukośnikami! HTML5 i JS pozwalają na użycie „cudzysłowu” oraz „cudzysłowu”. Więc w JSON wpisuję:

    "index4":{"<a href='http://example.com'>example</a>"}

Zobacz stronę internetową ev.bingo jako roboczy przykład: "v4": ["Audi e-tron Q4 Sportback w pełni wykorzystuje modułową platformę napędu elektrycznego MEPP, która jest wspólna dla Grupy Volkswagen"],

mcc
źródło