0
私はMariaDBのCOLUMN_JSON()
関数を使用しています。 this bugが示すように、関数は二重引用符を適切にエスケープしますが、エンコード/エスケープする他の文字はエスケープしません。JSONコントロール文字のエンコード/エスケープ
ここでは、JSON列の作成方法を示すための愚かな例のクエリです。
SELECT CONCAT('[', GROUP_CONCAT(COLUMN_JSON(COLUMN_CREATE(
'name', `name`,
'value', `value`
)) SEPARATOR ','), ']') AS `json`
FROM `settings`
name
またはvalue
が無効なJSON文字が含まれている場合、json_decode
は失敗します。
私は、クエリーから来る値をエスケープ/エンコードするPHP関数を書いていますが、より良い方法があるはずです。
/**
* Makes sure the JSON values built by COLUMN_JSON() in MariaDB are safe for json_decode()
* Assumes that double quotes are already escaped
*
* @param string $mysql_json
* @return string
*/
public static function jsonEscape($mysql_json)
{
$rtn = '';
for ($i = 0; $i < strlen($mysql_json); ++$i) {
$char = $mysql_json[$i];
if (($char === '\\') && ($mysql_json[$i + 1] !== '"')) {
// escape a backslash, 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;
}
文字列ごとに文字列を調べると、このようにうまく機能しません。文字列の置換や正規表現の方がパフォーマンスがよいでしょうか?
これはバグだとは限りません。 _Claudio Galdiolo_の問題は、彼の視聴者が '\ n'をエスケープしていないことを示しています。問題はMaria DBにありません。改行は '\ n'または' \ u000A'ですが、確かに '\\ n'ではありません。 – Halcyon
PHPの 'json_decode()'は、値に制御文字がある場合、MariaDBの 'COLUMN_JSON()'関数から出てくる値を詰まらせます。私はその動作を検証し、解決策を探す際にバグレポートを見つけました。 – Sonny
バグがあるとしましょう。 'str_replace'や' strpos'の実装が高速かどうか試してみてください。 'str_replace'は' value-> replacement'の配列を受け入れます。 strposの場合、32文字すべてをループする必要があります。 – Halcyon