dreamact3026 2015-07-08 21:23
浏览 59
已采纳

来自MySQL的JSON安全值

I'm using MySQL's GROUP_CONCAT() to generate a JSON string. I then decode it in PHP with json_decode().

I'm already escaping double quotes in the values like this:

REPLACE(COALESCE(`column_name`, ''), '"', '\\\\"')

My problem is that there's some other character in a record that's invalid and causing a JSON_ERROR_SYNTAX (4) when trying to decode. Rather than track down the specific character that's causing this problem, I'd like to apply a more generic solution that makes the values "safe".

This blog solves the problem by using MySQL's HEX() function to encode the value, and then this PHP function on the decode end for each value:

function hexToStr($hex)
{
    $string = '';
    for ($charIter = 0; $charIter < strlen($hex) - 1; $charIter += 2)
    {
        $string .= chr(hexdec($hex[$charIter] . $hex[$charIter + 1]));
    }
    return $string;
}

I'm looking for a solution that requires less work on the decode end. Ideally doing all the work in MySQL.


After three downvotes and close vote, I'm not sure how to better structure my question. I simply want to escape values in MySQL so that they'll be "JSON safe".

  • 写回答

1条回答 默认 最新

  • douqiaotong8682 2015-07-09 16:36
    关注

    Update: I've switch to MariaDB, and am using the COLUMN_JSON function, which takes care of double quote escaping, but not control characters. Here's my new solution.


    Old Solutiong

    Keep the double quote escaping in the query:

    REPLACE(COALESCE(`column_name`, ''), '"', '\\\\"')
    

    Add this function for escaping the backslash and control characters, but leaving the already escaped double quotes intact:

    /**
     * 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;
    }
    

    Call it like this:

    $data = json_decode(mysql_json_escape($mysql_json));
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥20 测距传感器数据手册i2c