2010-02-27 13 views
36

Próbuję obsługiwać złe dane JSONA podczas analizowania przez json_decode(). Używam następujący skrypt:Wykrywanie złych danych json w PHP json_decode()?

if(!json_decode($_POST)) { 
    echo "bad json data!"; 
    exit; 
} 

Jeśli $ _POST wynosi:

'{ bar: "baz" }' 

Następnie json_decode obsługuje grzywny błędu i wypluwa; "złych danych JSON!" Jednakże, jeśli mogę ustawić $ _POST do czegoś podobnego „Nieprawidłowe dane”, to daje mi:

Warning: json_decode() expects parameter 1 to be string, array given in C:\server\www\myserver.dev\public_html\rivrUI\public_home\index.php on line 6 
bad json data! 

Czy muszę napisać niestandardowy skrypt do wykrywania poprawnych danych JSON, czy istnieje jakiś inny sprytny sposób, aby wykryć to?

+0

'$ _POST' zawsze jest tablicą c przy użyciu parametrów * x-www-form-urlencoded * przekazywanych przez POST. Jak przesłać swoje dane do skryptu PHP? – Gumbo

+0

Dołączone funkcje json w PHP nie są zbyt pomocne. Mają wiele problemów. Spójrz na [json.org] (http://json.org/), aby znaleźć dobrą bibliotekę. – whiskeysierra

Odpowiedz

82

Oto kilka rzeczy, o json_decode:

  • zwraca dane lub null gdy wystąpi błąd
  • może również zwrócić null gdy nie ma błędu: gdy łańcuch JSON zawiera null
  • podnosi ostrzeżenie w przypadku ostrzeżenia - ostrzeżenie, że chcesz zniknąć.


Aby rozwiązać problem z ostrzeżeniem, rozwiązaniem byłoby użyć @ operator(nie często zalecają go używać, jak to sprawia, że ​​o wiele więcej debuging trudniej ... Ale tu nie ma dużego wyboru):

$_POST = array(
    'bad data' 
); 
$data = @json_decode($_POST); 

Byłbyś wtedy trzeba sprawdzić, czy jest null$data - i, aby uniknąć przypadek, w którym json_decode powraca null dla null w ciąg JSON, można c Heck json_last_error, który (cytowanie):

Zwraca ostatni błąd (jeśli występują) nastąpiło przez ostatni JSON parsowania.


Co oznacza, że ​​trzeba użyć kodu jak poniżej:

if ($data === null 
    && json_last_error() !== JSON_ERROR_NONE) { 
    echo "incorrect data"; 
} 
10

Można również użyć json_last_error: http://php.net/manual/en/function.json-last-error.php

który jako dokumentacja mówi:

Powoduje zwrócenie ostatniego błędu (jeśli wystąpił) podczas ostatniego JSON kodowanie/dekodowanie.

tutaj jest przykładem

+6

To jest całkowicie niepotrzebne w PHP 5.5 z http://php.net/manual/en/function.json-last-error-msg.php – vvondra

1

właśnie złamałem głowę nad błąd składni json w tym, co wydaje się być idealny json: { "test1": "samochód", "test2": "auto "} z zakodowanego ciągu URL.

Ale w moim przypadku niektóre z powyższych zostały zakodowane w html, ponieważ dodanie html_entity_decode($string) rozwiązało problem.

$ft = json_decode(html_entity_decode(urldecode(filter_input(INPUT_GET, 'ft', FILTER_SANITIZE_STRING)))); 

Mam nadzieję, że to uratuje kogoś jeszcze przez jakiś czas.

1

/** * * zwyczaj json_decode * błędy uchwyt json_decode * * typ @param $ json_text * typ @return */ publiczna funkcja statycznego custom_json_decode ($ json_text) {

$decoded_array = json_decode($json_text, TRUE); 
    switch (json_last_error()) { 
     case JSON_ERROR_NONE: 
      return array(
       "status" => 0, 
       "value" => $decoded_array 
      ); 


     case JSON_ERROR_DEPTH: 
      return array(
       "status" => 1, 
       "value" => 'Maximum stack depth exceeded' 
      ); 

     case JSON_ERROR_STATE_MISMATCH: 
      return array(
       "status" => 1, 
       "value" => 'Underflow or the modes mismatch' 
      ); 

     case JSON_ERROR_CTRL_CHAR: 
      return array(
       "status" => 1, 
       "value" => 'Unexpected control character found' 
      ); 

     case JSON_ERROR_SYNTAX: 
      return array(
       "status" => 1, 
       "value" => 'Syntax error, malformed JSON' 
      ); 

     case JSON_ERROR_UTF8: 
      return array(
       "status" => 1, 
       "value" => 'Malformed UTF-8 characters, possibly incorrectly encoded' 
      ); 

     default: 
      return array(
       "status" => 1, 
       "value" => 'Unknown error' 
      ); 
    } 
} 
1

ten sposób chlać obsługuje json

/** 
* Parse the JSON response body and return an array 
* 
* @return array|string|int|bool|float 
* @throws RuntimeException if the response body is not in JSON format 
*/ 
public function json() 
{ 
    $data = json_decode((string) $this->body, true); 
    if (JSON_ERROR_NONE !== json_last_error()) { 
     throw new RuntimeException('Unable to parse response body into JSON: ' . json_last_error()); 
    } 

    return $data === null ? array() : $data; 
}