Reputation: 1509
I have the following class I wrote:
class Sanitizer {
public function sanitizeSingle ($string) {
if (get_magic_quotes_gpc()) {
$string = stripslashes($string);
}
return trim(htmlspecialchars($string, ENT_QUOTES));
}
public function sanitize ($string) {
if (is_array($string)) {
foreach ($string as $k => $v) {
$string[$k] = $this->sanitizeSingle($v);
}
}
else {
$string = $this->sanitizeSingle($string);
}
return $string;
}
public function desanitize ($string) {
return trim(htmlspecialchars_decode($string, ENT_QUOTES));
}
}
The problem is that while it works on strings and one-dimensional arrays, I get the following error with multidimensional arrays:
Warning: htmlspecialchars() expects parameter 1 to be string, array given in C:\wamp\www\classes\Sanitizer.php on line 10
How do I fix this? Any help would be greatly appreciated.
Upvotes: 1
Views: 1979
Reputation: 47894
With some minor adjustments, you can leverage a native recursive function to sanitize scalar values at any level in your array.
array_walk_recursive($data, [$this, 'sanitizeSingle']);
Code: (Demo)
class Sanitizer {
public function sanitizeSingle(&$string) {
if (function_exists("get_magic_quotes_gpc") && get_magic_quotes_gpc()) {
$string = stripslashes($string);
}
$string = trim(htmlspecialchars($string, ENT_QUOTES));
}
public function sanitize($data) {
if (is_array($data)) {
array_walk_recursive($data, [$this, 'sanitizeSingle']); // replace your loop with this line
} else {
$this->sanitizeSingle($data);
}
return $data;
}
}
$array = ['one' => ['a ', ' b ', ' c'], 'two' => " <a href='test'>Test</a>"];
$string = ' another "test"';
$sanitizer = new Sanitizer();
var_export($sanitizer->sanitize($array));
echo "\n---\n";
var_export($sanitizer->sanitize($string));
Output:
array (
'one' =>
array (
0 => 'a',
1 => 'b',
2 => 'c',
),
'two' => '<a href='test'>Test</a>',
)
---
'another "test"'
sanitizeSingle()
modifies the input string by reference so any adjustments are declared upon the variable and there is no return
value.
sanitize()
does not modify by reference; the modified data is return
ed.
Upvotes: 1
Reputation: 3743
Your code was not evaluating array in $v
Modify your foreach block like this, this modification will sanitize any level of nested array,
foreach ($string as $k => $v) {
if(is_array($v))
{
$string[$k] = $this->sanitize($v);
}
else
{
$string[$k] = $this->sanitizeSingle($v);
}
}
Upvotes: 3