解决json插入mysql后再读出使用json_decode()返回null问题

在开发在线考试系统时,遇到一个问题:将json数据存入MySQL后,读取并用json_decode()处理返回null。经过排查,发现MySQL在存储时将双引号转换为'"',导致json_decode()失败。解决方案是在解码前使用str_replace()函数替换'"'为双引号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题背景:

本人在开发一个在线考试系统平台的过程中,需要根据前端部分选择传来的参数随机生成试卷。因为整份卷子的内容是动态的(不定长的),所以我想到使用json保存我的试卷内容方便在读出的时候使用。

随机生成试卷内容代码如下:

			$selected_tq = $test_question->where(array("ib_id"=>$_POST['ib_id']))->select();

			//随机在指定题型库中抽取指定数目的题目
			$key = array_rand($selected_tq, $_POST['each_tp_count']);

			//使用Jason存储试卷内容
			if ($_POST['each_tp_count'] == 1) {
				$t[0]['tq_content'] = $selected_tq[$key]['tq_content'];
				$t[0]['tq_id'] = $selected_tq[$key]['tq_id'];
				$t[0]['answer'] = $selected_tq[$key]['answer'];
				$_POST['tp_content'] = json_encode($t);

				// $_POST['tp_content'] = $selected_tq[$key]['tq_content'];

				// $_POST['tp_content'] = "{\"t1\":\"".$selected_tq[$key]['tq_content']."\"}";
			}
			else if ($_POST['each_tp_count'] > 1) {

/*				for ($i=0; $i < $_POST['each_tp_count']; $i++) { 
					// $test[$i] = $selected_tq[$key[$i]]['tq_content'];
					if ($i == $_POST['each_tp_count'] - 1) {
						$_POST['tp_content'] .= $selected_tq[$key[$i]]['tq_content'];
					} else
						$_POST['tp_content'] .= $selected_tq[$key[$i]]['tq_content']."|";
				}	*/

				// serialize 
/*				for ($i=0; $i < $_POST['each_tp_count']; $i++) { 
					$index = 't' . $i;
					p($index);
					$t[$index] = $selected_tq[$key[$i]]['tq_content'];
				}
				$_POST['tp_content'] = serialize($t);
				p(unserialize ($_POST['tp_content']));		*/		

				//json
				for ($i=0; $i < $_POST['each_tp_count']; $i++) { 

					$t[$i]['tq_content'] = $selected_tq[$key[$i]]['tq_content'];
					$t[$i]['tq_id'] = $selected_tq[$key[$i]]['tq_id'];
					$t[$i]['answer'] = $selected_tq[$key[$i]]['answer'];
				}
				$_POST['tp_content'] = json_encode($t);

			}


			$_POST['status'] = 0;
			$course_id = $_POST['course_id'];

			if($tp->insert($_POST))
				$this->success("添加考试成功", 1, "user/tchExamList/course_id/$course_id"); 
			else {
				$this->error("添加考试失败", 1, "user/tchExamList/course_id/$course_id"); 
			}
		} 


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


过程:

我发现,当我把写入的json数据从mysql读出并json_decode()时,该函数始终返回空


直接打印读出的字符串如下图所示:


似乎并没有任何json语法错误。。。


该部分代码如下:

			$tp = D("test_paper");

			$selected_tp = $tp->where(array("tp_id"=>$_GET['tp_id']))->find();	

			$str = 	$selected_tp['tp_content'];

			$data = json_decode($str, true);
			p($data);

于是去百度,百度上大牛各种说法例如:BOM头部,隐藏字符方法等对于我这情况完全无法解决。于是使用如下代码:

 switch (json_last_error()) {
        case JSON_ERROR_NONE:
            echo ' - No errors';
        break;
        case JSON_ERROR_DEPTH:
            echo ' - Maximum stack depth exceeded';
        break;
        case JSON_ERROR_STATE_MISMATCH:
            echo ' - Underflow or the modes mismatch';
        break;
        case JSON_ERROR_CTRL_CHAR:
            echo ' - Unexpected control character found';
        break;
        case JSON_ERROR_SYNTAX:
            echo ' - Syntax error, malformed JSON';
        break;
        case JSON_ERROR_UTF8:
            echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
        break;
        default:
            echo ' - Unknown error';
        break;
}
发现一直报JSON_ERROR_SYNTAX错误即json语法错误,在此纠结5,6个小时,无法解决。在此期间,在mysql中查看到json数据存储形式如下图所示:


百思不得其解之时,使用如下代码:

			p(strlen($str));
			$str='["In system modeling, describe the meaning of System Flow Diagram (SFD) and its relationship with System Context Diagram (SCD) and Data Flow Diagram (DFD).","2+2=","3+3="]';
			p(strlen($str));

比较从mysql中读出的字符串和在程序中直接赋相同的值的字符串的长度,发现结果

长度不一样!!!!!!!!!!!!!!

终于发现哪里出问题了,大哭


在继续的调试中,发现原来是“&quot;”这玩意儿在使坏,那么解决方法来了~


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


解决方法:

在json_decode()前,加一句话:

            $str = str_replace('&quot;', '"', $str);

将“&quot;”字符串替换即可。


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


总结:

个人认为,mysql在处理插入语句中的值带有双引号时,会自动将其转换为“&quot;”保存,在读出使用时,浏览器会自动将其转义为双引号,所以,我们以为它在实际语句中是一个字符,但实际它占了6个字符!!!!json_decode()当然会报语法错误了。




转载请注明出处

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值