Jump to content

Action for every key and value pair in multidimensional associative array of variable dimensions


Go to solution Solved by Ch0cu3r,

Recommended Posts

Hi there,

 

I've posted this at stackoverflow but did not receive any replies so far so I'd like to try here as well.

------

I have an array of variable dimensions and namings. Sometimes associative, sometimes partially. Sometimes just a single array, sometimes multiple dimensions. An example array is this:

array(4) {
["name"]=>
string(9) "Some Name"
["user"]=>
array(2) {
["id"]=>
int(1)
["msgs"]=>
array(3) {
[0]=>
string(16) "My first message"
[1]=>
string(17) "My second message"
["folder"]=>
array(2) {
["first"]=>
string(13) "Some folder.."
[1]=>
string(17) "some other stuf.."
}
}
}
[0]=>
string(17) "More random stuff"
["foo"]=>
array(2) {
[0]=>
string(10) "more stuff"
["bar"]=>
string(7) "The end"
}
}

I would like to have a function that goes through every key and value pair and performs a function, without altering the structure of the array. In this case, I want to apply htmlspecialchars() with ENT_QUOTES on every key and value pair in the array while keeping the array itself intact structure wise.

I have tried with array_walk_recursive and array_map, neither seem to do the trick.

I'm pretty new to PHP but I tried the following function by messing about with how I think it should be done but it's obviously not working :)

  private function CreateErrorArray($array, $knownKeys=NULL) {
    if (is_array($array)) {
      foreach ($array as $key => $value) {
        if (is_array($value)) {
          if (is_null($knownKeys)) {  
            $keys = array($key);
            $this->response['ERRORARRAY'][$key] = $this->CreateErrorArray($this->RequestClass->error[$key], $keys);
          } else {
            $keys = array_push($knownKeys, $key);
            $this->response['ERRORARRAY'][$key] = $this->CreateErrorArray($this->RequestClass->error[$knownKeys][$key], $keys);
          }
        } else {
          $this->response['ERRORARRAY'][$key] = $value;
        }
      }
    }
}
  • Solution

Create a recursable function, passing the value by reference

function array_escape($array)
{
    // loop over array, 
    foreach($array as $key => &$value)
    {
        // value is array?, call the function again
        if(is_array($value))
            $value = array_escape($value);
        else
            $value = htmlspecialchars($value, ENT_QUOTES); // apply htmlspecialchars
    }

    return $array; // return the array
}

$array = array( 'key1' => '"test"', 
                'key2' => 't\'wp', 
                'some "other \'value\'',
                'key3' => array('name'=> "'part2'", 
                      'age' => 'part3')
            );

printf('<pre>%s</pre>', print_r(array_escape($array), true));
Edited by Ch0cu3r

Hi,

 

Thanks! That works great for $values. In some cases I also want to escape the keynames themselfs, which was a little tricky since PHP does not allow passing $key by reference, but I found the following workaround:

 private function ForEachFn(Array &$array, $fn) {
    $newArray = array();
    foreach ($array as $key=> $value){
      $fn($key, $value);
      $newArray[$key] =$value;
    }
    $array = $newArray;
  }
 
  private function EscapeArrayKeysAndValues($array) {
    foreach($array as $key => $value) {
      $this->ForEachFn($array, function(&$key, &$value) {
        if(is_array($value))
          $value = $this->EscapeArrayKeysAndValues($value); 
        else {
          $value  = htmlspecialchars($value, ENT_QUOTES);
          $key    = htmlspecialchars($key, ENT_QUOTES);
        }
      });
      return $array;
    }
  }
 
 
$this->response['ERRORARRAY'] = $this->EscapeArrayKeysAndValues($this->RequestClass->error);

Thanks to John Erck for the workaround as well.

Edited by c8372bd7-6af3
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.