在 PHP 开发中,使用 json_decode() 函数解析 JSON 字符串时,经常会遇到返回 NULL 的情况,即使 JSON 字符串看似格式正确。本文将深入探讨此问题,并提供多种解决方案。
以下 JSON 字符串在使用 json_decode() 解析时返回 NULL:
$php_input = '{"key":"ao_1/f9pbbnam5_0_230502100035.mp3","fname":"ao_1/f9pbbnam5_0_230502100035.mp3","fsize":"234144","avinfo":"{"attachedpic":null,"audios":[{"disposition":{"attached_pic":0},"avg_frame_rate":"0/0","bit_rate":"96000","channels":2,"codec_long_name":"mp3 (mpeg audio layer 3)","codec_name":"mp3","codec_time_base":"1/16000","codec_type":"audio","duration":"19.512000","index":0,"nb_frames":"","profile":"","r_frame_rate":"0/0","sample_fmt":"s16p","sample_rate":"16000","start_time":"0.000000","tags":{}}],"maxab":96000,"subtitles":null,"videos":null,"audio":{"disposition":{"attached_pic":0},"avg_frame_rate":"0/0","bit_rate":"96000","channels":2,"codec_long_name":"mp3 (mpeg audio layer 3)","codec_name":"mp3","codec_time_base":"1/16000","codec_type":"audio","duration":"19.512000","index":0,"nb_frames":"","profile":"","r_frame_rate":"0/0","sample_fmt":"s16p","sample_rate":"16000","start_time":"0.000000","tags":{}},"format":{"bit_rate":"96000","duration":"19.512000","format_long_name":"mp2/3 (mpeg audio layer 2/3)","format_name":"mp3","nb_streams":1,"size":"234144","start_time":"0.000000","tags":{}},"subtitle":null,"video":null}","format_name":"mp3","bit_rate":"96000","duration":"19.512000","ext":".mp3"}'; $arr_post = json_decode($php_input, true); var_dump($arr_post); // 输出 NULL
问题根源在于 avinfo 字段的值本身就是一个 JSON 字符串,但它被包含在另一个 JSON 字符串中,且内部的双引号未进行转义。这导致了 JSON 解析器无法正确解析该字符串。
以下提供几种解决方法:
立即学习“PHP免费学习笔记(深入)”;
手动将 avinfo 字段中 JSON 字符串的双引号转义为 ":
$php_input = '{"key":"ao_1/f9pbbnam5_0_230502100035.mp3","fname":"ao_1/f9pbbnam5_0_230502100035.mp3","fsize":"234144","avinfo":"{"attachedpic":null,"audios":[{"disposition":{"attached_pic":0},"avg_frame_rate":"0/0","bit_rate":"96000","channels":2,"codec_long_name":"mp3 (mpeg audio layer 3)","codec_name":"mp3","codec_time_base":"1/16000","codec_type":"audio","duration":"19.512000","index":0,"nb_frames":"","profile":"","r_frame_rate":"0/0","sample_fmt":"s16p","sample_rate":"16000","start_time":"0.000000","tags":{}}],"maxab":96000,"subtitles":null,"videos":null,"audio":{"disposition":{"attached_pic":0},"avg_frame_rate":"0/0","bit_rate":"96000","channels":2,"codec_long_name":"mp3 (mpeg audio layer 3)","codec_name":"mp3","codec_time_base":"1/16000","codec_type":"audio","duration":"19.512000","index":0,"nb_frames":"","profile":"","r_frame_rate":"0/0","sample_fmt":"s16p","sample_rate":"16000","start_time":"0.000000","tags":{}},"format":{"bit_rate":"96000","duration":"19.512000","format_long_name":"mp2/3 (mpeg audio layer 2/3)","format_name":"mp3","nb_streams":1,"size":"234144","start_time":"0.000000","tags":{}},"subtitle":null,"video":null}","format_name":"mp3","bit_rate":"96000","duration":"19.512000","ext":".mp3"}'; $arr_post = json_decode($php_input, true); var_dump($arr_post); // 输出数组
避免字符串拼接,直接使用 PHP 数组构建 JSON 对象,然后使用 json_encode() 函数生成 JSON 字符串:
$data = [ "key" => "ao_1/f9pbbnam5_0_230502100035.mp3", "fname" => "ao_1/f9pbbnam5_0_230502100035.mp3", "fsize" => "234144", "avinfo" => [ "attachedpic" => null, "audios" => [ [ "disposition" => ["attached_pic" => 0], // ... 其他 avinfo 数据 ] ], // ... 其他 avinfo 数据 ], "format_name" => "mp3", // ... 其他数据 ]; $php_input = json_encode($data); $arr_post = json_decode($php_input, true); var_dump($arr_post); // 输出数组
使用正则表达式和回调函数自动转义 avinfo 字段中的双引号:
$php_input = '{"key":"ao_1/f9pbbnam5_0_230502100035.mp3","fname":"ao_1/f9pbbnam5_0_230502100035.mp3","fsize":"234144","avinfo":"{"attachedpic":null,"audios":[{"disposition":{"attached_pic":0},"avg_frame_rate":"0/0","bit_rate":"96000","channels":2,"codec_long_name":"mp3 (mpeg audio layer 3)","codec_name":"mp3","codec_time_base":"1/16000","codec_type":"audio","duration":"19.512000","index":0,"nb_frames":"","profile":"","r_frame_rate":"0/0","sample_fmt":"s16p","sample_rate":"16000","start_time":"0.000000","tags":{}}],"maxab":96000,"subtitles":null,"videos":null,"audio":{"disposition":{"attached_pic":0},"avg_frame_rate":"0/0","bit_rate":"96000","channels":2,"codec_long_name":"mp3 (mpeg audio layer 3)","codec_name":"mp3","codec_time_base":"1/16000","codec_type":"audio","duration":"19.512000","index":0,"nb_frames":"","profile":"","r_frame_rate":"0/0","sample_fmt":"s16p","sample_rate":"16000","start_time":"0.000000","tags":{}},"format":{"bit_rate":"96000","duration":"19.512000","format_long_name":"mp2/3 (mpeg audio layer 2/3)","format_name":"mp3","nb_streams":1,"size":"234144","start_time":"0.000000","tags":{}},"subtitle":null,"video":null}","format_name":"mp3","bit_rate":"96000","duration":"19.512000","ext":".mp3"}'; $php_input_fixed = preg_replace_callback( '/"avinfo":"(.*?)"/', function ($matches) { return '"avinfo":"' . str_replace('"', '\"', $matches[1]) . '"'; }, $php_input ); $arr_post = json_decode($php_input_fixed, true); var_dump($arr_post); // 输出数组
选择哪种方法取决于你的具体情况。 如果 JSON 数据结构比较简单,手动转义或使用数组构建是比较直接有效的方法。如果 JSON 数据结构复杂且动态变化,使用 preg_replace_callback() 可以提供更灵活的处理方式,但需要谨慎编写正则表达式以避免误匹配。 记住始终优先选择更清晰易读的方案。
以上就是为什么在PHP中使用json_decode()函数解析JSON字符串会返回NULL?的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号