我需要一个非常非常快的方法来检查字符串是否为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($str){
return json_decode($str) != null;
}
当检测到非法编码时,http://tr.php.net/manual/en/function.json-decode.php返回值为空。
其他回答
我试过其中的一些方法,但没有一种对我有效。我尝试了这么简单的事情:
$isJson = json_decode($myJSON);
if ($isJson instanceof \stdClass || is_array($isJson)) {
echo("it's JSON confirmed");
} else {
echo("nope");
}
我认为这是一个很好的解决方案,因为JSON解码没有第二个参数给出一个对象。
编辑:如果知道输入内容,就可以根据需要调整代码。在我的情况下,我知道我有一个Json以“{”开始,所以我不需要检查它是否是一个数组。
使用json_decode“探测”它实际上可能不是最快的方法。如果它是一个嵌套很深的结构,那么实例化大量数组对象来丢弃它们是浪费内存和时间。
所以使用preg_match和RFC4627正则表达式来确保有效性可能会更快:
// in JS:
var my_JSON_object = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
text.replace(/"(\\.|[^"\\])*"/g, '')));
在PHP中也一样:
return !preg_match('/[^,:{}\\[\\]0-9.\\-+Eaeflnr-u \\n\\r\\t]/',
preg_replace('/"(\\.|[^"\\\\])*"/', '', $json_string));
不过,我不是一个性能爱好者,不会在这里费心进行基准测试。
//Tested thoroughly, Should do the job:
public static function is_json(string $json):bool
{
json_decode($json);
if (json_last_error() === JSON_ERROR_NONE) {
return true;
}
return false;
}
下面是我创建的一个简单的性能函数(在使用json_decode处理更大的字符串之前使用基本的字符串验证):
function isJson($string) {
$response = false;
if (
is_string($string) &&
($string = trim($string)) &&
($stringLength = strlen($string)) &&
(
(
stripos($string, '{') === 0 &&
(stripos($string, '}', -1) + 1) === $stringLength
) ||
(
stripos($string, '[{') === 0 &&
(stripos($string, '}]', -1) + 2) === $stringLength
)
) &&
($decodedString = json_decode($string, true)) &&
is_array($decodedString)
) {
$response = true;
}
return $response;
}
应该是这样的:
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);
}
}