我想为来自各种来源的数据建立一个通用的消毒剂。通过消毒我的意思是(在这个阶段)将htmlspecialchars应用于字符串。现在,来自这些源的数据可以是从对象到数组到字符串,所有嵌套(和复杂)的数据,格式总是有点不同。
所以我想到了一个递归的htmlspecialchars函数,它将自身应用于数组和对象,并且只将htmlspecialchars应用于字符串,但是如何递归地遍历对象?
感谢。
编辑:我想我应该提到这一点 - 我实际上正在构建一个严重依赖JS和JSON进行客户端 - 服务器通信的RIA。服务器唯一做的就是从数据库中获取东西并通过JSON将其返回给客户端,格式如下:
{"stat":"ok","data":{...}}
正如我所说,数据可以是任何东西,不仅来自字符串形式的数据库,而且来自XML 处理JSON的工作流程如下:
将它们放入“数据”数组
使用
以递归方式从iso-8859-1转换为utf-8private function utf8_encode_deep(&$input) {
if (is_string($input)) {
$input = $this -> str_encode_utf8($input);
} else if (is_array($input)) {
foreach ($input as &$value) {
$this -> utf8_encode_deep($value);
}
unset($value);
} else if (is_object($input)) {
$vars = array_keys(get_object_vars($input));
foreach ($vars as $var) {
$this -> utf8_encode_deep($input -> $var);
}
}
}
使用PHP的json_encode
将数据转换为JSON
将数据发送(回显)到客户端
使用JS渲染数据(例如放入表格)
介于两者之间,数据应该以某种方式消毒(在这个阶段只有htmlspecialchars)。现在的问题应该是: 在哪里使用什么方法进行消毒?
答案 0 :(得分:1)
您只想在输出到HTML时转义。并且您无法将完整的数组或对象输出到HTML中,因此转义所有内容似乎都无效。
由于您的JSON输出,您有一个间接级别。所以你不能在PHP中决定数据的用途是什么--JSON仍然是纯文本,而不是HTML。
因此,要确定是否必须为HTML转义JSON中的任何数据,我们必须知道您的Javascript如何使用JSON数据。
示例:如果您的JSON被视为纯文本,并且包含<b>BOLD</b>
之类的内容,则在任何HTML中使用的预期结果正是此文本,包括看起来像HTML标记的字符,但没有粗体排版。只有当您的Javascript客户端以纯文本格式处理此测试时,才会发生这种情况。它不会使用innerHTML()
将其放在页面上,因为这会激活HTML标记,但只能激活innerText()
或textContent()
或其他任何便利方法。 jQuery(.text()
)。
另一方面,如果您希望JSON包含提供给innerHTML()
的现成HTML,那么您必须在将此字符串放入JSON之前将其转义。但是,只有在您不想为其添加任何格式时,才必须转义整个字符串。否则,您处于使用模板将预定义格式与用户内容混合的情况:用户内容在放入HTML上下文时必须进行转义,但结果不得 - 否则Javascript无法将其放入innerHTML()
并启用格式化。
基本上,对于数组或对象内部的所有内容的全局转义很可能是错误的,除非您知道它将在您的Javascript中在HTML上下文中使用的所有内容。
答案 1 :(得分:1)
您可以尝试以下
class MyClass {
public $var1 = '<b>value 1</b>';
public $var2 = '<b>value 2</b>';
public $var3 = array('<b>value 3</b>');
}
$list = array();
$list[0]['nice'] = range("A", "C");
$list[0]['bad'] = array("<div>A</div>","<div>B</div>","<div>C</div>",new MyClass());
$list["<b>gloo</b>"] = array(new MyClass(),"<b>WOW</b>");
var_dump(__htmlspecialchars($list));
使用的功能
function __htmlspecialchars($data) {
if (is_array($data)) {
foreach ( $data as $key => $value ) {
$data[htmlspecialchars($key)] = __htmlspecialchars($value);
}
} else if (is_object($data)) {
$values = get_class_vars(get_class($data));
foreach ( $values as $key => $value ) {
$data->{htmlspecialchars($key)} = __htmlspecialchars($value);
}
} else {
$data = htmlspecialchars($data);
}
return $data;
}
输出类似
的内容array
0 =>
array
'nice' =>
array
0 => string 'A' (length=1)
1 => string 'B' (length=1)
2 => string 'C' (length=1)
'bad' =>
array
0 => string '<div>A</div>' (length=24)
1 => string '<div>B</div>' (length=24)
2 => string '<div>C</div>' (length=24)
3 =>
object(MyClass)[1]
...
array
0 =>
object(MyClass)[2]
public 'var1' => string '<b>value 1</b>' (length=26)
public 'var2' => string '<b>value 2</b>' (length=26)
public 'var3' =>
array
...
答案 2 :(得分:0)
function htmlrecursive($data){
if (is_array($data) && count($data) > 1){
foreach ($data as &$d){
$d = htmlrecursive($d);
}
} else if (!is_array($data)){
return htmlspecialchars($data);
}
else {
return htmlspecialchars($data[0])
}
}
htmlrecursive($array);
答案 3 :(得分:0)
对于需要实现The ArrayAccess interface的对象,您可以执行数组遍历递归
同时检查此问题Getting an object to work with array_walk_recursive in PHP