Php 来自MySQL的JSON安全值
我正在使用MySQL的GROUP_CONCAT生成一个JSON字符串。然后我用json_decode在PHP中对其进行解码 我已经在如下值中转义双引号:Php 来自MySQL的JSON安全值,php,mysql,json,Php,Mysql,Json,我正在使用MySQL的GROUP_CONCAT生成一个JSON字符串。然后我用json_decode在PHP中对其进行解码 我已经在如下值中转义双引号: REPLACE(COALESCE(`column_name`, ''), '"', '\\\\"') $data = json_decode(mysql_json_escape($mysql_json)); 我的问题是,记录中还有其他无效字符,在尝试解码时会导致JSON_错误_语法4。我不想追踪导致此问题的特定字符,而是想应用一种更通用的解
REPLACE(COALESCE(`column_name`, ''), '"', '\\\\"')
$data = json_decode(mysql_json_escape($mysql_json));
我的问题是,记录中还有其他无效字符,在尝试解码时会导致JSON_错误_语法4。我不想追踪导致此问题的特定字符,而是想应用一种更通用的解决方案,使这些值更安全
通过使用MySQL的十六进制函数对值进行编码,然后在解码端为每个值使用此PHP函数来解决此问题:
function hexToStr($hex)
{
$string = '';
for ($charIter = 0; $charIter < strlen($hex) - 1; $charIter += 2)
{
$string .= chr(hexdec($hex[$charIter] . $hex[$charIter + 1]));
}
return $string;
}
我正在寻找一个解决方案,需要较少的工作在解码端。理想情况下,在MySQL中完成所有工作
经过三次反对票和接近票,我不知道如何更好地组织我的问题。我只是想转义MySQL中的值,以便它们是JSON安全的。更新:我已切换到MariaDB,并使用COLUMN_JSON函数,该函数负责双引号转义,但不负责控制字符
旧的解决方案
在查询中保留双引号转义:
REPLACE(COALESCE(`column_name`, ''), '"', '\\\\"')
添加此函数用于转义反斜杠和控制字符,但保留已转义的双引号不变:
/**
* Makes sure the JSON values built by GROUP_CONCAT() in MySQL are safe for json_decode()
* Assumes that double quotes are already escaped
*
* @param string $mysql_json
* @return string
*/
function mysql_json_escape($mysql_json)
{
$rtn = '';
for ($i = 0; $i < strlen($mysql_json); ++$i) {
$char = $mysql_json[$i];
if (($char === '\\') && ($mysql_json[$i + 1] !== '"')) {
// escape a back slash, but leave escaped double quotes intact
$rtn .= '\\\\';
} elseif (($ord = ord($char)) && ($ord < 32)) {
// hex encode control characters (below ASCII 32)
$rtn .= '\\u' . str_pad(dechex($ord), 4, '0', STR_PAD_LEFT);
} else {
$rtn .= $char;
}
}
return $rtn;
}
为什么要使用组_CONCAT生成json字符串?GROUP_CONCAT将使查询变慢。为什么不执行一个简单的查询呢?你从来没有想过你所做的基本上是愚蠢的?你在MySQL中创建一个JSON字符串,然后在PHP中对其进行解码——从MySQL中获取内容然后在PHP中对其进行处理有什么不对——转换它并对其进行编码/解码?数据库不是将数据转换为各种格式的编程语言,它们的工作很简单,而且做得很好。你想用锤子来喝汤。虽然可行,但这样做有意义吗?或者,您可以始终使用JSON UDF解决问题,但愚蠢的部分仍然存在。