在PHP json_decode()中检测错误的json数据?
我试图在通过json_decode()解析时处理错误的json数据。我正在使用以下脚本:在PHP json_decode()中检测错误的json数据?,php,json,Php,Json,我试图在通过json_decode()解析时处理错误的json数据。我正在使用以下脚本: if(!json_decode($_POST)) { echo "bad json data!"; exit; } 如果$u POST等于: '{ bar: "baz" }' 然后json_decode处理错误并抛出“坏json数据!”; 但是,如果我将$\u POST设置为类似“无效数据”的值,它会给出: Warning: json_decode() expects parameter 1 t
if(!json_decode($_POST)) {
echo "bad json data!";
exit;
}
如果$u POST等于:
'{ bar: "baz" }'
然后json_decode处理错误并抛出“坏json数据!”;
但是,如果我将$\u POST设置为类似“无效数据”的值,它会给出:
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!
我是否需要编写一个自定义脚本来检测有效的json数据,或者是否有其他漂亮的方法来检测此数据?以下是一些关于:
- 当出现错误时,它返回数据,或
null
- 当JSON字符串包含
null
- 它会在有警告的地方发出警告--您希望使其消失的警告
要解决警告问题,一个解决方案是使用(我不经常建议使用它,因为它会使调试更加困难…但在这里,没有太多选择): 然后,您必须测试
$data
是否为null
——为了避免json_decode
在json字符串中为null
返回null
,您可以检查(引用):
返回最后一个错误(如果有)
上次JSON解析时发生
这意味着您必须使用以下代码:
if ($data === null
&& json_last_error() !== JSON_ERROR_NONE) {
echo "incorrect data";
}
您还可以使用json\u last\u error: 正如文件所述: 返回上次JSON过程中发生的最后一个错误(如果有) 编码/解码 这里有一个例子
json_decode($string);
switch (json_last_error()) {
case JSON_ERROR_NONE:
echo ' - No errors';
break;
case JSON_ERROR_DEPTH:
echo ' - Maximum stack depth exceeded';
break;
case JSON_ERROR_STATE_MISMATCH:
echo ' - Underflow or the modes mismatch';
break;
case JSON_ERROR_CTRL_CHAR:
echo ' - Unexpected control character found';
break;
case JSON_ERROR_SYNTAX:
echo ' - Syntax error, malformed JSON';
break;
case JSON_ERROR_UTF8:
echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
break;
default:
echo ' - Unknown error';
break;
}
我刚刚因为一个看似完美的json中的json语法错误而大发雷霆:
{“test1”:“car”,“test2”:“auto”}
但在我的例子中,上面的一些内容是html编码的,因为添加html\u entity\u decode($string)
起到了作用
$ft = json_decode(html_entity_decode(urldecode(filter_input(INPUT_GET, 'ft', FILTER_SANITIZE_STRING))));
希望这能为其他人节省一些时间。Guzzle就是这样处理json的
/**
*
* custom json_decode
* handle json_decode errors
*
* @param type $json_text
* @return type
*/
public static function 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'
);
}
}
/**
* 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;
}
自PHP 7.3以来,json_decode函数将接受一个新的json_THROW_ON_ERROR选项,该选项将允许json_decode抛出异常,而不是在出错时返回null
示例:
try {
json_decode("{", false, 512, JSON_THROW_ON_ERROR);
}
catch (\JsonException $exception) {
echo $exception->getMessage(); // displays "Syntax error"
}
我刚刚花了一个小时浏览了这一页上所有可能的解决方案。我自由地将所有这些可能的解决方案集合到一个函数中,以使其更快、更易于尝试和调试 我希望它能对其他人有用
<?php
/**
* Decontaminate text
*
* Primary sources:
* - https://stackoverflow.com/questions/17219916/json-decode-returns-json-error-syntax-but-online-formatter-says-the-json-is-ok
* - https://stackoverflow.com/questions/2348152/detect-bad-json-data-in-php-json-decode
*/
function decontaminate_text(
$text,
$remove_tags = true,
$remove_line_breaks = true,
$remove_BOM = true,
$ensure_utf8_encoding = true,
$ensure_quotes_are_properly_displayed = true,
$decode_html_entities = true
){
if ( '' != $text && is_string( $text ) ) {
$text = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $text );
$text = str_replace(']]>', ']]>', $text);
if( $remove_tags ){
// Which tags to allow (none!)
// $text = strip_tags($text, '<p>,<strong>,<span>,<a>');
$text = strip_tags($text, '');
}
if( $remove_line_breaks ){
$text = preg_replace('/[\r\n\t ]+/', ' ', $text);
$text = trim( $text );
}
if( $remove_BOM ){
// Source: https://stackoverflow.com/a/31594983/1766219
if( 0 === strpos( bin2hex( $text ), 'efbbbf' ) ){
$text = substr( $text, 3 );
}
}
if( $ensure_utf8_encoding ){
// Check if UTF8-encoding
if( utf8_encode( utf8_decode( $text ) ) != $text ){
$text = mb_convert_encoding( $text, 'utf-8', 'utf-8' );
}
}
if( $ensure_quotes_are_properly_displayed ){
$text = str_replace('"', '"', $text);
}
if( $decode_html_entities ){
$text = html_entity_decode( $text );
}
/**
* Other things to try
* - the chr-function: https://stackoverflow.com/a/20845642/1766219
* - stripslashes (THIS ONE BROKE MY JSON DECODING, AFTER IT STARTED WORKING, THOUGH): https://stackoverflow.com/a/28540745/1766219
* - This (improved?) JSON-decoder didn't help me, but it sure looks fancy: https://stackoverflow.com/a/43694325/1766219
*/
}
return $text;
}
// Example use
$text = decontaminate_text( $text );
// $text = decontaminate_text( $text, false ); // Debug attempt 1
// $text = decontaminate_text( $text, false, false ); // Debug attempt 2
// $text = decontaminate_text( $text, false, false, false ); // Debug attempt 3
$decoded_text = json_decode( $text, true );
echo json_last_error_msg() . ' - ' . json_last_error();
?>
$\u POST
始终是一个数组,包含通过POST传递的x-www-form-urlencoded参数。如何将数据发送到PHP脚本?PHP中包含的json函数没有多大帮助。他们有很多问题。请看一看以找到一个好的库。这在PHP5.5中是完全不必要的,您可以使用json_last_error_msg:如果(json_error_NONE!==json_last_error())抛出新异常(json_last_error_msg())代码>我花了3天时间来查找我的问题,直到我在这里读到您的html\u实体\u解码提示。非常感谢你:如果我没有找到这个答案,我永远也解决不了我的问题。我会给我的第一个孩子取名为“Klompenrunner”!正如Harry Bosch在中指出的,您只需检查JSON\u ERROR\u NONE!==json_last_error()
这应该是可以接受的答案。我收到了一个异常:“警告:在
@domdambrogia中使用未定义的常量JSON\u-THROW\u-ON\u-ERROR-假定“JSON\u-THROW\u-ON\u-ERROR”(这将在PHP的未来版本中引发错误)JSON\u-THROW\u-ON\u-ERROR常量仅在PHP7.3中可用
<?php
/**
* Decontaminate text
*
* Primary sources:
* - https://stackoverflow.com/questions/17219916/json-decode-returns-json-error-syntax-but-online-formatter-says-the-json-is-ok
* - https://stackoverflow.com/questions/2348152/detect-bad-json-data-in-php-json-decode
*/
function decontaminate_text(
$text,
$remove_tags = true,
$remove_line_breaks = true,
$remove_BOM = true,
$ensure_utf8_encoding = true,
$ensure_quotes_are_properly_displayed = true,
$decode_html_entities = true
){
if ( '' != $text && is_string( $text ) ) {
$text = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $text );
$text = str_replace(']]>', ']]>', $text);
if( $remove_tags ){
// Which tags to allow (none!)
// $text = strip_tags($text, '<p>,<strong>,<span>,<a>');
$text = strip_tags($text, '');
}
if( $remove_line_breaks ){
$text = preg_replace('/[\r\n\t ]+/', ' ', $text);
$text = trim( $text );
}
if( $remove_BOM ){
// Source: https://stackoverflow.com/a/31594983/1766219
if( 0 === strpos( bin2hex( $text ), 'efbbbf' ) ){
$text = substr( $text, 3 );
}
}
if( $ensure_utf8_encoding ){
// Check if UTF8-encoding
if( utf8_encode( utf8_decode( $text ) ) != $text ){
$text = mb_convert_encoding( $text, 'utf-8', 'utf-8' );
}
}
if( $ensure_quotes_are_properly_displayed ){
$text = str_replace('"', '"', $text);
}
if( $decode_html_entities ){
$text = html_entity_decode( $text );
}
/**
* Other things to try
* - the chr-function: https://stackoverflow.com/a/20845642/1766219
* - stripslashes (THIS ONE BROKE MY JSON DECODING, AFTER IT STARTED WORKING, THOUGH): https://stackoverflow.com/a/28540745/1766219
* - This (improved?) JSON-decoder didn't help me, but it sure looks fancy: https://stackoverflow.com/a/43694325/1766219
*/
}
return $text;
}
// Example use
$text = decontaminate_text( $text );
// $text = decontaminate_text( $text, false ); // Debug attempt 1
// $text = decontaminate_text( $text, false, false ); // Debug attempt 2
// $text = decontaminate_text( $text, false, false, false ); // Debug attempt 3
$decoded_text = json_decode( $text, true );
echo json_last_error_msg() . ' - ' . json_last_error();
?>