我需要一种非常快的方法来检查一个字符串是否是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 is_array(json_decode($str,true));
}
json_decode($str,true)
使其将对象转换为数组,因此它将通过is_array检查。但是,您对于字符串、整数等是正确的。 - Paul Phillips应该是类似这样的:
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);
}
}
ErrorException
。 - sykez$non_json_values
是完全有效的 JSON。 - undefined您好,这是我图书馆中的一个小片段。在这个条件语句中,我只是检查数据是否为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
}
}
我不了解我方案的性能或优雅程度,但这就是我正在使用的:
if (preg_match('/^[\[\{]\"/', $string)) {
$aJson = json_decode($string, true);
if (!is_null($aJson)) {
... do stuff here ...
}
}
只是想要贡献一点我的见解。
P.S. 刚刚更新了正则表达式字符串为/^[\[\{]\"/
以查找JSON数组字符串。 因此,现在它会查找字符串开头的["或{"。
更新:json_validate() 将在 PHP 8.3 中上线
提醒:
我正在致力于一项 RFC,旨在添加一个新的函数到 PHP 中,该函数能够仅验证 JSON 字符串而不生成对象/数组。
为什么需要一个仅验证的函数?因为 json_decode() 在解析 JSON 字符串时会创建一个数组/对象,从而影响使用的内存量;这意味着验证 JSON 字符串时可能会达到最大内存限制。
举个例子,看看这段代码 performance_test_json_validate()_vs_json_decode():
在这个测试中,我们可以看到新函数json_validate()用0 MB来验证 JSON 字符串,而json_decode()需要109 MB(因为它在解析时创建了一个内存数组/对象)。
目前这还是一个正在进行中的工作,但我想发表一下我的看法(不是关于是否值得拥有它,而是从技术角度来看)。
Github: https://github.com/php/php-src/pull/9399
RFC(正在进行中):https://wiki.php.net/rfc/json_validate
期待您对此的意见和支持。
提前致谢。
function isJson($string) {
$obj = json_decode($string);
return json_last_error() === JSON_ERROR_NONE && gettype($obj ) == "object";
}
这个可以工作,但对于数字不会返回true
新更新
上述解决方案如果JSON很长并且您不需要使用$obj,则性能不佳
如果您只想检查,最好使用以下函数
function isJson($string) {
if(is_numeric($string)) return false;
json_decode($string);
return json_last_error() === JSON_ERROR_NONE;
}
在这个答案的基础上,进一步探讨以下问题:
<?php
$json = '[{"user_id":13,"username":"stack"},{"user_id":14,"username":"over"}]';
//$json = '12';
function isJson($string) {
json_decode($string);
if(json_last_error() == JSON_ERROR_NONE) {
if(substr($string,0,1) == '[' && substr($string,-1) == ']') { return TRUE; }
else if(substr($string,0,1) == '{' && substr($string,-1) == '}') { return TRUE; }
else { return FALSE; }
}
}
echo isJson($json);
?>
$r = (array)json_decode($arr);
if(!is_array($r) || count($r) < 1) return false;
function isJson(string $string) {
return ($result = json_decode($string, true)) ? $result : $string;
}
stations.json
无效、缺失或超过一个月,请执行某些操作。if (!is_array(json_decode(@file_get_contents("stations.json"))) || time() > filemtime("stations.json") + (60*60*24*31)){
// The json file is invalid, missing, or is more than 1 month old
// Get a fresh version
} else {
// Up to date
}
json_decode
,并检查其输入和返回值。 - user166390