我需要一个非常非常快的方法来检查字符串是否为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;
}
有没有表演爱好者想改进这种方法?
当前回答
我不知道我的解决方案的性能或优雅性,但这就是我正在使用的:
if (preg_match('/^[\[\{]\"/', $string)) {
$aJson = json_decode($string, true);
if (!is_null($aJson)) {
... do stuff here ...
}
}
因为我所有的JSON编码字符串都以{”开头,所以用RegEx进行测试就足够了。我对RegEx一点也不流利,所以可能有更好的方法来做到这一点。另外:strpos()可能更快。
我只是想贡献我的价值。
备注:刚刚将RegEx字符串更新为/^[\[\{]\"/,也可以找到JSON数组字符串。所以它现在在字符串的开头寻找["或{"。
其他回答
之前我只是检查一个空值,这实际上是错误的。
$data = "ahad";
$r_data = json_decode($data);
if($r_data){//json_decode will return null, which is the behavior we expect
//success
}
上面的代码可以很好地处理字符串。然而,只要我提供号码,它就中断了。为例。
$data = "1213145";
$r_data = json_decode($data);
if($r_data){//json_decode will return 1213145, which is the behavior we don't expect
//success
}
要修复它,我所做的很简单。
$data = "ahad";
$r_data = json_decode($data);
if(($r_data != $data) && $r_data)
print "Json success";
else
print "Json error";
这样就可以了:
function isJson($string) {
$decoded = json_decode($string); // decode our JSON string
if ( !is_object($decoded) && !is_array($decoded) ) {
/*
If our string doesn't produce an object or array
it's invalid, so we should return false
*/
return false;
}
/*
If the following line resolves to true, then there was
no error and our JSON is valid, so we return true.
Otherwise it isn't, so we return false.
*/
return (json_last_error() == JSON_ERROR_NONE);
}
if ( isJson($someJsonString) ) {
echo "valid JSON";
} else {
echo "not valid JSON";
}
如其他答案所示,json_last_error()返回来自上一次json_decode()的任何错误。然而,在一些边缘用例中,仅使用这个功能还不够全面。例如,如果你json_decode()一个整数(例如:123),或者一个没有空格或其他字符的数字字符串(例如:“123”),json_last_error()函数将不会捕获错误。
为了解决这个问题,我添加了一个额外的步骤,以确保json_decode()的结果是一个对象或数组。如果不是,则返回false。
要查看具体操作,请查看以下两个示例:
只使用json_last_error()检查 首先检查对象/数组
下面是我创建的一个简单的性能函数(在使用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;
}
你真正需要做的就是…
if (is_object(json_decode($MyJSONArray)))
{
... do something ...
}
这个请求甚至不需要一个单独的函数。只需将is_object包装在json_decode周围,然后继续。似乎这个解决方案让人们花了太多心思。
2023年的今天,时代的回答:
虽然PHP 8.3仍在开发中,将提供新的内存效率高的json_validate()函数,但由于神奇的Symfony Polyfill组件,您可以在较旧的PHP版本(7.1和更新的版本)中使用它。
只需将以下包添加到您的项目:
composer require symfony/polyfill-php83
并在应用程序中使用它:
if (json_validate($data)) {
// do sometihng
}
由于这种方法,您可以在旧的应用程序中使用新的PHP特性,并且在将来无需任何代码更改就可以迁移到PHP 8.3,因为当内置函数可用时,您的代码将自动使用它。