我需要一个非常非常快的方法来检查字符串是否为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;
}
有没有表演爱好者想改进这种方法?
当前回答
嗨,这是我的库中的一个小片段,在第一个条件下,我只是检查数据是否为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
}
}
其他回答
应该是这样的:
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($str)
{
return is_array(json_decode($str,true));
}
这样就可以了:
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无效,缺失,或超过一个月,做一些事情。
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
}
为PHP 5.2兼容性新创建的函数,如果你需要成功解码的数据:
function try_json_decode( $json, & $success = null ){
// non-strings may cause warnings
if( !is_string( $json )){
$success = false;
return $json;
}
$data = json_decode( $json );
// output arg
$success =
// non-null data: success!
$data !== null ||
// null data from 'null' json: success!
$json === 'null' ||
// null data from ' null ' json padded with whitespaces: success!
preg_match('/^\s*null\s*$/', $json );
// return decoded or original data
return $success ? $data : $json;
}
用法:
$json_or_not = ...;
$data = try_json_decode( $json_or_not, $success );
if( $success )
process_data( $data );
else what_the_hell_is_it( $data );
一些测试:
var_dump( try_json_decode( array(), $success ), $success );
// ret = array(0){}, $success == bool(false)
var_dump( try_json_decode( 123, $success ), $success );
// ret = int(123), $success == bool(false)
var_dump( try_json_decode(' ', $success ), $success );
// ret = string(6) " ", $success == bool(false)
var_dump( try_json_decode( null, $success ), $success );
// ret = NULL, $success == bool(false)
var_dump( try_json_decode('null', $success ), $success );
// ret = NULL, $success == bool(true)
var_dump( try_json_decode(' null ', $success ), $success );
// ret = NULL, $success == bool(true)
var_dump( try_json_decode(' true ', $success ), $success );
// ret = bool(true), $success == bool(true)
var_dump( try_json_decode(' "hello" ', $success ), $success );
// ret = string(5) "hello", $success == bool(true)
var_dump( try_json_decode(' {"a":123} ', $success ), $success );
// ret = object(stdClass)#2 (1) { ["a"]=> int(123) }, $success == bool(true)