regex,PHP-从复杂的json字符串中删除单引号、双引号和反斜杠



下面的片段只是一个较大json的一部分。这个json通过ajax调用在PHP中从客户端传递到服务器端。json结构在许多地方都具有值属性。这个json是由jQuery插件生成的。

代码片段:

{"1":{"value":"abcdefg","style":{"autoFormatter":{}}}}

在将值保存到数据库中之前,我需要从value属性的value部分(即abcdefg(中删除任何单引号('(、双引号("(或反斜杠((。因此,我尝试在完整的json中运行一个正则表达式,以便删除前面提到的任何字符。

例如,应将"value":"xyz'abc"更改为"value":"xyzabc"

什么应该是正确的方式?

我认为最简单的方法是

  • 将JSON导入PHP数组
  • 递归遍历数组
  • 将其存储回JSON字符串中

类似于:

$arr = json_decode($str, true);
// Modify $arr.
array_walk_recursive($arr, function(&$value, $key) {
if ('value' === $key) {
$value = str_replace([ '"', "'", '\' ], '', $value);
}
});
$str = json_encode($arr);

使用正则表达式解析JSON字符串的代价可能是"谢谢,但不是"。

较旧的PHP

function cleanvalues(&$value, $key) {
// Programmers from Blefuscu usually write this as
// if ($key == $value)
// -- feel free.
if ('value' === $key) {
// Haven't tested this, and don't think it's faster, but
// regexes can be used here:
// $value = preg_replace('#["'\\]+#', '', $value);
$value = str_replace(array('"', "'", '\'), '', $value);
}
}
array_walk_recursive($arr, 'cleanvalues');

一个稍微不同的问题的答案

这就是所谓的"XY问题"。当实际问题是问题X:时,您正试图解决问题Y("从JSON中删除SQL问题字符"(

我需要稍后从DB中获取它,并将其保存在一个javascript变量中。然后我调用我正在使用的jQuery插件的fromJson方法。

因此,需要的是:">一种以SQL无关、JSON无关、Javascript无关的表示形式存储文本值的方法"。

您可以使用Base64来执行此操作。使用Base64作为应用程序层(SQL、Javascript和PHP(之间的"通用语言"。然后在值进入边界时对其进行解码,并在值再次外出时对其编码:

$value = "string with weird JSON that won't go into SQL";
$val2  = base64_encode($value);
...now $val2 is stored into SQL and can be retrieved with no problems
(search can be difficult but can be done, somewhat).

然后,您可以检索$val2并将其存储到Javascript中,而不会出现任何问题,只需记住它的base64即可。是的,它会占用更多的空间,但现在这真的是个问题吗?

// Value recovered from SQL through PHP
var base64val = '{$val2}';
// base64val is a safe string, but useless.
var trueval = btoa(base64val);
// trueval is a JSON string, but not yet decoded.
var fromjson = JSON.parse(trueval);
// finally fromjson holds the real value

现在,你有了一个任何事情都可以进入的工作流程-你可以放斜线、美元符号、引号、双引号,更重要的是,还有很多UTF8字符,这些字符可能会破坏我之前的答案(你可能想在阅读"畸形的UTF8攻击以及在哪里找到它们"时寻求一些刺激(。

我创建了一个小测试来解决这个问题。首先,我认为您在将json字符串写入数据库时遇到问题,因为您没有使用任何类型的"escape_string"或绑定参数。

---更新---

稍后只需将json字符串用作html中的对象,而不使用$.parseJSON(jsonString(.

<?php
/*
CREATE TABLE `table_53805089_test` (
`id` int(11) NOT NULL,
`json` text COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
*/
// Example json string from ajax call
$jsonFromAjaxRequest = '{"1":{"value":"ab"cd'efg","style":{"autoFormatter":{}}}}';
// Connect to database
$mysqli = new mysqli('localhost', 'root', '', 'stackoverflow');
// Write into database
$query = 'REPLACE INTO `table_53805089_test` 
(`id`, `json`) 
VALUES (1, '' . $mysqli->escape_string($jsonFromAjaxRequest) . '')';
$mysqli->query($query);
// Read from database
$query = 'SELECT json FROM `table_53805089_test` WHERE id = 1';
$result = $mysqli->query($query);
$row = $result->fetch_assoc();
// Use in html -> javscript variable
?>
<!DOCTYPE html>
<html>
<head><title>test</title></head>
<body>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
// Error:
// jsonString = '<?php echo $row['json']; ?>';
// $(document).ready(function () {
//  data = $.parseJSON(jsonString);
//  console.log(data);
//});
// Works:
var jsonData = <?php echo $row['json']; ?>;
console.log(jsonData['1']['value']);
// Suggestion in case $row['json'] is empty
var jsonData = <?php echo $row['json'] ?: '{}' ?>;
console.log(jsonData['1']['value']);
</script>
</body>
</html>

最新更新