c8372bd7-6af3 Posted January 11, 2014 Share Posted January 11, 2014 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; } } } } Link to comment https://forums.phpfreaks.com/topic/285287-action-for-every-key-and-value-pair-in-multidimensional-associative-array-of-variable-dimensions/ Share on other sites More sharing options...
Ch0cu3r Posted January 11, 2014 Share Posted January 11, 2014 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)); Link to comment https://forums.phpfreaks.com/topic/285287-action-for-every-key-and-value-pair-in-multidimensional-associative-array-of-variable-dimensions/#findComment-1464834 Share on other sites More sharing options...
c8372bd7-6af3 Posted January 11, 2014 Author Share Posted January 11, 2014 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. Link to comment https://forums.phpfreaks.com/topic/285287-action-for-every-key-and-value-pair-in-multidimensional-associative-array-of-variable-dimensions/#findComment-1464837 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.