我需要一个非常非常快的方法来检查字符串是否为JSON。我觉得这不是最好的方式:
function isJson($string) {
return ((is_string($string) &&
(is_object(json_decode($string)) ||
is_array(json_decode($string))))) ? true : false;
}
有没有表演爱好者想改进这种方法?
我需要一个非常非常快的方法来检查字符串是否为JSON。我觉得这不是最好的方式:
function isJson($string) {
return ((is_string($string) &&
(is_object(json_decode($string)) ||
is_array(json_decode($string))))) ? true : false;
}
有没有表演爱好者想改进这种方法?
当前回答
function is_json($input) {
$input = trim($input);
if (substr($input,0,1)!='{' OR substr($input,-1,1)!='}')
return false;
return is_array(@json_decode($input, true));
}
其他回答
对亨里克的回答做一个简单的修改,以触及最需要的可能性。
(包括“{}和[]”)
function isValidJson($string) {
json_decode($string);
if(json_last_error() == JSON_ERROR_NONE) {
if( $string[0] == "{" || $string[0] == "[" ) {
$first = $string [0];
if( substr($string, -1) == "}" || substr($string, -1) == "]" ) {
$last = substr($string, -1);
if($first == "{" && $last == "}"){
return true;
}
if($first == "[" && $last == "]"){
return true;
}
return false;
}
return false;
}
return false;
}
return false;
}
嗨,这是我的库中的一个小片段,在第一个条件下,我只是检查数据是否为json,然后返回它,如果正确解码,请注意substr的使用性能(我还没有看到任何json文件不以{或[开始
$input=trim($input);
if ((substr($input, 0, 1) == '{' && substr($input, -1) == '}') or (substr($input, 0, 1) == '[' && substr($input, -1) == ']')) {
$output = json_decode($input, 1);
if (in_array(gettype($output),['object','array'])) {
#then it's definitely JSON
}
}
问题的答案
函数json_last_error返回JSON编码和解码过程中发生的最后一个错误。因此,检查有效JSON的最快方法是
// decode the JSON data
// set second parameter boolean TRUE for associative array output.
$result = json_decode($json);
if (json_last_error() === JSON_ERROR_NONE) {
// JSON is valid
}
// OR this is equivalent
if (json_last_error() === 0) {
// JSON is valid
}
注意json_last_error仅在PHP >= 5.3.0中支持。
完整的程序来检查准确的错误
在开发期间了解准确的错误总是好的。下面是基于PHP文档检查确切错误的完整程序。
function json_validate($string)
{
// decode the JSON data
$result = json_decode($string);
// switch and check possible JSON errors
switch (json_last_error()) {
case JSON_ERROR_NONE:
$error = ''; // JSON is valid // No error has occurred
break;
case JSON_ERROR_DEPTH:
$error = 'The maximum stack depth has been exceeded.';
break;
case JSON_ERROR_STATE_MISMATCH:
$error = 'Invalid or malformed JSON.';
break;
case JSON_ERROR_CTRL_CHAR:
$error = 'Control character error, possibly incorrectly encoded.';
break;
case JSON_ERROR_SYNTAX:
$error = 'Syntax error, malformed JSON.';
break;
// PHP >= 5.3.3
case JSON_ERROR_UTF8:
$error = 'Malformed UTF-8 characters, possibly incorrectly encoded.';
break;
// PHP >= 5.5.0
case JSON_ERROR_RECURSION:
$error = 'One or more recursive references in the value to be encoded.';
break;
// PHP >= 5.5.0
case JSON_ERROR_INF_OR_NAN:
$error = 'One or more NAN or INF values in the value to be encoded.';
break;
case JSON_ERROR_UNSUPPORTED_TYPE:
$error = 'A value of a type that cannot be encoded was given.';
break;
default:
$error = 'Unknown JSON error occured.';
break;
}
if ($error !== '') {
// throw the Exception or exit // or whatever :)
exit($error);
}
// everything is OK
return $result;
}
使用有效的JSON INPUT进行测试
$json = '[{"user_id":13,"username":"stack"},{"user_id":14,"username":"over"}]';
$output = json_validate($json);
print_r($output);
有效的输出
Array
(
[0] => stdClass Object
(
[user_id] => 13
[username] => stack
)
[1] => stdClass Object
(
[user_id] => 14
[username] => over
)
)
使用无效JSON进行测试
$json = '{background-color:yellow;color:#000;padding:10px;width:650px;}';
$output = json_validate($json);
print_r($output);
无效的输出
Syntax error, malformed JSON.
额外注意(PHP >= 5.2 && PHP < 5.3.0)
由于PHP 5.2中不支持json_last_error,因此可以检查编码或解码是否返回布尔值FALSE。这里有一个例子
// decode the JSON data
$result = json_decode($json);
if ($result === FALSE) {
// JSON is invalid
}
应该是这样的:
function isJson($string)
{
// 1. Speed up the checking & prevent exception throw when non string is passed
if (is_numeric($string) ||
!is_string($string) ||
!$string) {
return false;
}
$cleaned_str = trim($string);
if (!$cleaned_str || !in_array($cleaned_str[0], ['{', '['])) {
return false;
}
// 2. Actual checking
$str = json_decode($string);
return (json_last_error() == JSON_ERROR_NONE) && $str && $str != $string;
}
单元测试
public function testIsJson()
{
$non_json_values = [
"12",
0,
1,
12,
-1,
'',
null,
0.1,
'.',
"''",
true,
false,
[],
'""',
'[]',
' {',
' [',
];
$json_values = [
'{}',
'{"foo": "bar"}',
'[{}]',
' {}',
' {} '
];
foreach ($non_json_values as $non_json_value) {
$is_json = isJson($non_json_value);
$this->assertFalse($is_json);
}
foreach ($json_values as $json_value) {
$is_json = isJson($json_value);
$this->assertTrue($is_json);
}
}
function is_json($input) {
$input = trim($input);
if (substr($input,0,1)!='{' OR substr($input,-1,1)!='}')
return false;
return is_array(@json_decode($input, true));
}