Search code examples
phparraysformsdynamichtmlspecialchars

htmlspecialchars on an array of arrays is not working


I have this form with a bunch of sections, and some of them have name of an array because they are supposed to add up dynamically. I'm trying to perform htmlspecialchars on them first and then once the submit button is clicked, echo them out on a next confirmation page, but it won't work for some reason. I did print_r on $clean, but it didn't show the input $value of them, so I don't know where I did something wrong.

It would be great if somebody could help me on this.

Thank you.

Here is a part of the htmlspecialchars code.

$clean = array();

if( !empty($_POST) ) {

foreach( $_POST as $key => $value ) {

    if( is_array($key)){

      foreach($key as $key2 => $value2)

         $clean[$key2] = htmlspecialchars( $value2, ENT_QUOTES);

    } else {

        $clean[$key] = htmlspecialchars( $value, ENT_QUOTES);
      }

    } 
}

This is a html part of it

 <div class="seconf-h-form">
      <label>Multiple</label>
      <input type="radio" id="r2" name="team_select" 
      onchange="toggleFunc('ex_t_button');" value="Multiple"/>
 </div>

 <div class="element_wrap" id="box_2">
   <input type="submit" name="add" id="add" value="add more">
   <label>The name of your team</label>
   <input type="text" name="ex_team_n[]" id="ex_team_n"/>
   <select name="ex_amount[]">
      <option value="">Select</option>
      <option value="3">3</option>
      <option value="4">4</option>
      <option value="5">5</option>
      <option value="6">6</option>
   </select>
  <div id="add_section"></div>

and this is the part where I echo them out

<div class="element_wrap">
    <label>The name of your team</label>
    <p><?php echo $clean['ex_team_n']; ?></p>
</div>


<div class="element_wrap">
    <label>The number of your team</label>
    <p><?php echo $clean['ex_amount']; ?></p>
</div>

  <input type="hidden" name="amount" value="<?php if( 
  $clean['team_select'] === "Multiple"){echo $clean['ex_team_n'];} ?>">
  <input type="hidden" name="amount" value="<?php if( 
  $clean['team_select'] === "Multiple"){echo $clean['ex_amount'];} ?>">

Solution

  • You can use array_walk_recursive() to escape all data inside an array:

    // Sample data, you can use $_POST instead or any other array
    $array = array(
        [
            'a_key' => '<b>html</b>',
            'b_key' => '<a href="http://example.com/">another code</a>',
            'c_key' => array('<script>alert(\'Hello\');</script>', 'No code, no change'),
        ],
        [
            'd_key' => '<small>ssup</small>',
            'e_key' => 'stack',
            'f_key' => 'overflow',
        ],
    );
    
    // Function to escape the value, you must pass the item by reference using the & operator
    function html_escape(&$item){
        $item = htmlspecialchars($item, ENT_QUOTES);
    }
    
    // Dump data before escaping
    var_dump($array);
    
    // Walk recursively through the array and call our function
    array_walk_recursive($array, 'html_escape');
    
    // Dump data after escaping
    var_dump($array);
    

    The data dumped before escaping

    array (size=2)
      0 => 
        array (size=3)
          'a_key' => string '<b>html</b>' (length=11)
          'b_key' => string '<a href="http://example.com/">another code</a>' (length=46)
          'c_key' => 
            array (size=2)
              0 => string '<script>alert('Hello');</script>' (length=32)
              1 => string 'No code, no change' (length=18)
      1 => 
        array (size=3)
          'd_key' => string '<small>ssup</small>' (length=19)
          'e_key' => string 'stack' (length=5)
          'f_key' => string 'overflow' (length=8)
    

    The data dumped after escaping

    array (size=2)
      0 => 
        array (size=3)
          'a_key' => string '&lt;b&gt;html&lt;/b&gt;' (length=23)
          'b_key' => string '&lt;a href=&quot;http://example.com/&quot;&gt;another code&lt;/a&gt;' (length=68)
          'c_key' => 
            array (size=2)
              0 => string '&lt;script&gt;alert(&#039;Hello&#039;);&lt;/script&gt;' (length=54)
              1 => string 'No code, no change' (length=18)
      1 => 
        array (size=3)
          'd_key' => string '&lt;small&gt;ssup&lt;/small&gt;' (length=31)
          'e_key' => string 'stack' (length=5)
          'f_key' => string 'overflow' (length=8)
    

    Documentation for array_walk_recursive()