2009-06-26 84 views
25

PHP的json_encode函數沒有任何理由逃避字符串中的所有JSON控制字符?PHP的json_encode不會逃避所有的JSON控制字符

例如,讓我們跨越兩行和具有控制字符(\ r \ n「/ \)在它的字符串:?

<?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: \\." 
?> 

注意,回車和換行字符的轉義爲什麼

我正在使用jQuery作爲我的JS庫,它的$ .getJSON()函數在你完全信任傳入數據時會做的很好,否則我會像其他人一樣使用JSON.org的庫json2.js 但是,如果您嘗試解析該編碼的字符串會引發錯誤:

<script type="text/javascript"> 

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

</script> 

而且你無法獲取數據!如果你刪除或轉義該字符串中的\ r \ n「和\然後JSON.parse()將不會拋出錯誤

是否有任何現有的,良好的PHP函數用於轉義控制字符簡單的str_replace與搜索和替換數組將無法正常工作

+0

而不是<?php echo $ s?>學會使用 :)只是我的提示。 – Thinker 2009-06-26 11:26:39

+24

感謝您的提示,但該快捷方式的回聲語法只適用於啓用short_open_tag時,我從來沒有使用短開標籤,因爲我更喜歡<?php over Gustav 2009-06-26 11:35:32

+0

我已經編輯了我的答案 - 現在就可以工作,或者將你的錢翻倍! – Greg 2009-06-26 12:17:13

回答

12

D'哦 - 你需要雙編碼:JSON.parse期待一個字符串:

<script type="text/javascript"> 

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

</script> 
1

也許我是盲人,但在你的例子,他們被轉義什麼

<script type="text/javascript"> 

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

</script> 

(注意不同的引號)

0

只是一個除了Greg的迴應:的json_encode()輸出已經包含在雙引號("),所以沒有必要圍繞它們與報價再次:

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

我仍然沒有想出沒有str_replace的任何解決方案..

試試這個代碼。

$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); 

希望幫助...

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

這是

25
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; 
    } 

我使用的轉義反斜線上述功能的正確方法(必須先在陣列),並應該處理換膚和退格(我認爲PHP不支持\f\b)。

2

從PHP轉換到PHP應該不是問題。 PHP的json_encode做適當的編碼,但重新解釋內部Java腳本可能會導致問題。像

1)原始字符串 - [字符串與它NNN換行符](其中nnn是實際換行符)

2)json_encode將這個轉換爲 [字符串 「\\ N」 換行符在(控制字符轉換爲「\\ n」 - 文字「\ n」

3)但是,當您使用php回顯以文字字符串重新打印時,則「\\ n」被解釋爲「\ n」並導致心痛。因爲JSON.parse將理解文字印刷 「\ n」 個如換行符 - 一個控制字符(NNN)

這樣來解決此: -

A) 首先編碼在PHP JSON對象使用json_enocde和得到一個字符串。然後通過一個過濾器來運行它,以便在html和java腳本中使用它。

B) 使用來自PHP的JSON字符串作爲「literal」,並將其放在單引號內而不是雙引號內。


<?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腳本。將JSON字符串放在雙引號內會導致解析器在屬性標記處失敗(類似{「id」:「value」})。如果將字符串設置爲「literal」,並且讓JSON解析器完成這項工作,則不需要其他轉義。

-1

使用任何形式的Ajax時,從CGI服務器收到的響應格式的詳細文檔似乎在Web上是缺乏的。這裏的一些Notes和stackoverflow.com的條目指出,返回的文本或json數據中的換行符必須轉義以防止JSON轉換中的無限循環(掛起)(可能通過拋出未捕獲的異常創建),無論是由jQuery自動完成還是手動使用Javascript系統或庫JSON解析調用。

在程序員發佈這個問題的每一種情況下,都提出了不足的解決方案(通常在發送端用\\ n替換\ n),並且該問題被刪除。傳遞意外嵌入控制轉義序列的字符串值(例如Windows路徑名)時會顯示它們的不足之處。一個例子是「C:\ Chris \ Roberts.php」,它包含控制字符^ c和^ r,它們可能會導致字符串{「file」:「C:\ Chris \ Roberts.php」}的JSON轉換爲永遠循環。產生這種值的一種方式是故意嘗試將PHP警告和錯誤消息從服務器傳遞給客戶端,這是一個合理的想法。

根據定義,Ajax在幕後使用HTTP連接。這種連接使用GET和POST傳遞數據,這兩種都需要編碼發送的數據,以避免不正確的語法,包括控制字符。

這給出了足夠的提示來構建似乎是解決方案的東西(它需要更多測試):在PHP(發送)端使用rawurlencode對數據進行編碼,並在Javascript(接收)端使用unescape解碼數據。在某些情況下,您會將這些應用於整個文本字符串,而在其他情況下,您只會將它們應用於JSON中的值。

如果這個想法證明是正確的,可以構造簡單的例子來幫助程序員在所有層面上徹底解決這個問題。

0

控制字符在HTML中沒有特別的含義,除了textarea.value中的新行。 PHP> 5.2上的JSON_encode會像你期望的那樣做。

如果你只是想顯示文本,你不需要去JSON。 JSON適用於JavaScript中的數組和對象(以及PHP的索引和關聯數組)。

如果你需要的texarea標籤換行:

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

我不完全瞭解var_export是如何工作的,所以如果我遇到麻煩,我會更新,但是這似乎是工作我:

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

這是我個人使用,它從來沒有奏效。原本有類似的問題。

源腳本(ajax)將採取一個數組和json_encode它。例如:

$return['value'] = 'test'; 
$return['value2'] = 'derp'; 

echo json_encode($return); 

我的JavaScript將會使AJAX調用,並得到了呼應「json_encode($返程)」作爲它的輸入,並在腳本中,我會使用以下方法:

myVar = jQuery.parseJSON(msg.replace(/&quot;/ig,'"')); 

與「msg」是返回的值。所以,對你來說,像...

var msg = '<?php echo $s ?>'; 
myVar = jQuery.parseJSON(msg.replace(/&quot;/ig,'"')); 

...可能適合你。

0

$ val = array(「\ n」,「\ r」);

$ string = str_replace($ val,「」,$ string);

它將從JSON字符串中刪除所有換行符在PHP

-1

有2個解決方案,除非AJAX使用:

  1. 寫數據到像輸入和JS閱讀:

    <input type="hidden" value="<?= htmlencode(json_encode($data)) ?>"/> 
    
  2. 使用addslashes

    var json = '<?= addslashes(json_encode($data)) ?>';