PHP'nin json_encode tüm JSON denetim karakterleri kaçış yok

11 Cevap php

PHP'nin json_encode işlevi bir dize tüm JSON denetim karakterleri kaçış yok herhangi bir neden var mı?

Örneğin iki satır yayılan ve onun içinde (\ r \ n "/ \) kontrol karakterleri olan bir dize atalım:

<?php
$s = <<<END
First row.
Second row w/ "double quotes" and backslash: \.
END;

$s = json_encode($s);
echo $s;
// Will output: "First row.\r\nSecond row w\/ \"double quotes\" and backslash: \\."
?>

Bu satırbaşı unutmayın ve satır karakter çıkmamış vardır. Neden?

I'm using jQuery as my JS library and it's $.getJSON() function will do fine when you fully, 100% trust incoming data. Otherwise I use JSON.org's library json2.js like everybody else. But if you try to parse that encoded string it throws an error:

<script type="text/javascript">

JSON.parse(<?php echo $s ?>);  // Will throw SyntaxError 

</script>

Ve veriler alınamıyor! Kaldırmak ya da bu dizede \ r \ n "ve \ kaçış sonra JSON.parse () hata atmak olmaz.

Kontrol karakterleri kaçan herhangi bir mevcut, iyi bir PHP fonksiyonu var. Arama ve diziler ile değiştirin basit str_replace çalışmaz.

11 Cevap

D'oh - çift kodlamak gerekir: JSON.parse elbette bir dize bekliyor:

<script type="text/javascript">

JSON.parse(<?php echo json_encode($s) ?>);

</script>
function escapeJsonString($value) {
    # list from www.json.org: (\b backspace, \f formfeed)    
    $escapers =     array("\\",     "/",   "\"",  "\n",  "\r",  "\t", "\x08", "\x0c");
    $replacements = array("\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t",  "\\f",  "\\b");
    $result = str_replace($escapers, $replacements, $value);
    return $result;
  }

Ben bir ters eğik çizgi kaçar yukarıdaki işlevini kullanıyorum (dizilerde ilk olmalı) ve (I \f sanmıyorum formfeeds ve geri al ile mücadele etmesi ve \b desteklenmektedir PHP).

Buna gerek yok JSON.parse. $s düz dize ise, sadece bunu yapabilirsiniz:

<script type="text/javascript">
var s = <?php echo json_encode($s); ?>;
</script>

Ben hala herhangi bir çözüm çözemedim str_replace ..

Bu kodu deneyin.

$json_encoded_string = json_encode(...);
$json_encoded_string = str_replace("\r", '\r', $json_encoded_string);
$json_encoded_string = str_replace("\n", '\n', $json_encoded_string);

Umarım ki olur ...

Converting to and fro from PHP should not be an issue. PHP's json_encode does proper encoding but reinterpreting that inside java script can cause issues. Like

1) orijinal dize - nnn gerçek satır karakteri () [ona nnn yeni satır ile dize]

2) json_encode will convert this to [string with "\\n" newline in it] (control character converted to "\\n" - Literal "\n"

Kullanarak bir sabit dize yine bu yazdırırken 3) Ancak php "\ \ n" sonra echo "\ n" olarak yorumlanır ve bu gönül yarası neden olur. Bir kontrol karakteri (nnn) - JSON.parse satırsonu olarak değişmez basılmış "\ n" anlayacaksınız çünkü

bu nedenle bu geçici bir çözüm bulmak için: -

A) First encode the json object in php using json_enocde and get a string. Then run it through a filter that makes it safe to be used inside html and java script.

B) use the JSON string coming from PHP as a "literal" and put it inside single quotes instead of double quotes.


<?php
       function form_safe_json($json) {
            $json = empty($json) ? '[]' : $json ;
            $search = array('\\',"\n","\r","\f","\t","\b","'") ;
            $replace = array('\\\\',"\\n", "\\r","\\f","\\t","\\b", "&#039");
            $json = str_replace($search,$replace,$json);
            return $json;
        }


        $title = "Tiger's   /new \\found \/freedom " ;
        $description = <<<END
        Tiger was caged
        in a Zoo 
        And now he is in jungle
        with freedom
    END;

        $book = new \stdClass ;
        $book->title = $title ;
        $book->description = $description ;
        $strBook = json_encode($book);
        $strBook = form_safe_json($strBook);

        ?>


    <!DOCTYPE html>
    <html>

        <head>
            <title> title</title>

            <meta charset="utf-8">


            <script type="text/javascript" src="/3p/jquery/jquery-1.7.1.min.js"></script>


            <script type="text/javascript">
                $(document).ready(function(){
                    var strBookObj = '<?php echo $strBook; ?>' ;
                    try{
                        bookObj = JSON.parse(strBookObj) ;
                        console.log(bookObj.title);
                        console.log(bookObj.description);
                        $("#title").html(bookObj.title);
                        $("#description").html(bookObj.description);
                    } catch(ex) {
                        console.log("Error parsing book object json");
                    }

                });
            </script>

        </head>

         <body>

             <h2> Json parsing test page </h2>
             <div id="title"> </div>
             <div id="description"> </div>
        </body>
    </html>

Java script tek tırnak içinde dize koymak. Çift tırnak içine json dize koyarak ayrıştırıcı niteliği marker ({: "değer" "id"} gibi bir şey) başarısız olmasına neden olur. Eğer "literal" olarak dize koymak ve JSON ayrıştırıcı çalışma yapalım eğer başka hiçbir öncelemeli gerekli olmalıdır.

Belki ben körüm, ama örnekte onlar kaçtı ARE. Ne hakkında

<script type="text/javascript">

JSON.parse("<?php echo $s ?>");  // Will throw SyntaxError 

</script>

(Farklı tırnak unutmayın)

$search = array("\n", "\r", "\u", "\t", "\f", "\b", "/", '"');
$replace = array("\\n", "\\r", "\\u", "\\t", "\\f", "\\b", "\/", "\"");
$encoded_string = str_replace($search, $replace, $json);

Bu doğru bir yoldur

Karşılık Greg 'nin için sadece ilave bir: çıkış json_encode() önce çift tırnak (") içinde yer alır, bu yüzden onları çevreleyen gerek yoktur yine tırnak ile:

<script type="text/javascript">
    JSON.parse(<?php echo $s ?>);
</script>

Ajax herhangi bir biçimde kullanırken, CGI sunucusundan alınan yanıtların biçimi için ayrıntılı belgeler Web üzerinde eksik gibi görünüyor. Stackoverflow.com bazı burada Notlar ve kayıtlar döndürülen metin veya json veri newlines jQuery tarafından otomatik olarak yapılır olsun, (muhtemelen yakalanmamış istisna atarak oluşturulan) JSON dönüşüm sonsuz döngüler (askıda) engellemek için kaçan ya da manuel olarak kullanıyor gerektiğine işaret javascript sistem veya kitaplık JSON ayrıştırma çağırır.

Programcıları bu sorunu sonrası her durumda, yetersiz çözümler sunulmaktadır (en sık gönderme tarafında n \ \ tarafından \ n yerine) ve madde bırakılır. Yanlışlıkla gibi Windows pathnames gibi kontrol öncelemlerini, embed dize değerlerini geçerken kendi yetersizlik ortaya çıkar. Bir örnek: "C: \ Chris \ Roberts.php" kontrol karakterleri ^ c ve dizenin JSON dönüşüm {"dosya": "C: Chris \ Roberts.php \"} neden olabilir ^ r içerir, için sonsuza kadar döngü. Gibi değerleri üreten bir yolu sunucu istemci, makul bir fikir PHP uyarı ve hata mesajları geçmek girişimi için kasıtlı olduğunu.

Tanım olarak, Ajax perde arkasında HTTP bağlantılarını kullanır. Bu tür bağlantıları kodlama kontrol karakterleri de dahil olmak üzere, yanlış sözdizimi önlemek için, veri gönderilen gerektiren her ikisi de, GET ve POST kullanarak veri aktarmak.

Verilerin kodunu yan (alma) verileri kodlamak için yan (gönderme) ve JavaScript üzerinde unescape PHP rawurlencode kullanmak için: Bu bir çözüm (daha fazla test ihtiyacı) gibi görünüyor ne oluşturmak için bir ipucu yeterli verir. Bazı durumlarda, diğer durumlarda sadece JSON içine değerlerine geçerli olacak, tüm metin dizeleri için bu geçerli olacaktır.

Bu fikir doğru olduğu ortaya çıkarsa, basit örnekler her düzeyde programcılar kez ve herkes için bu sorunu çözmeye yardımcı olmak için inşa edilebilir.

Kontrol karakterleri textarea.value yeni hat dışında HTML içinde özel bir anlamı var. Eğer beklendiği gibi json_encode PHP> 5.2 bunu yapacağız.

Sadece metin göstermek istiyorsanız JSON sonra gitmek gerekmez. JSON diziler ve nesneler JavaScript (ve PHP için indisli ve ilişkisel dizi) içindir.

Eğer texarea etiketi için bir satır besleme gerekiyorsa:

$s=preg_replace('/\r */','',$s);
echo preg_replace('/ *\n */','&#13;',$s);

Ben tam var_export nasıl çalıştığını anlamıyorum, bu yüzden belaya girerse ben güncelleme olacak, ama bu benim için çalışıyor gibi görünüyor:

<script>
    window.things = JSON.parse(<?php var_export(json_encode($s)); ?>);
</script>