Как использовать рекурсивный итератор массива для обработки многомерного массива?

Я пытаюсь получить что-то вроде этого:

function posts_formatter (&$posts){ foreach ($posts as $k => $v){ if (is_array($v)){ posts_formatter($v); }else{ switch (strtolower($k)){ # make email addresses lowercase case (strpos($k, 'email') !== FALSE): $posts[$k] = strtolower($v); break; # make postcodes uppercase case (strpos($k, 'postcode') !== FALSE): $posts[$k] = strtoupper($v); break; # capitalize certain things case (strpos($k, 'line1') !== FALSE): case (strpos($k, 'line2') !== FALSE): case (strpos($k, 'line3') !== FALSE): case (strpos($k, 'forename') !== FALSE): case (strpos($k, 'surname') !== FALSE): $posts[$k] = capitalize($v); break; } } } } 

Он будет правильно проходить массив и форматировать значения, но я не могу заставить их их вернуть. Я играл с удалением & из объявления функции и добавлением возврата в конце, но ничего не сделает.

Кроме того, я думаю, что, возможно, использование RecursiveArrayIterator может быть способом. Однако, несмотря на наличие книги прямо передо мной с главой о Итераторах SPL, его примеры бесполезны для достижения того, чего я пытаюсь сделать. Как я могу реализовать его?

Редактировать:

 array ( 'user' => array ( 'title' => 'Mr.', 'forename' => 'lowercase', 'surname' => 'name', 'businessName' => 'some dude', 'telephone' => '07545464646', 'postcode' => 'wa1 6nj', 'line1' => 'blergh road', 'line2' => 'randomLY cApitaLIzed wOrds', 'line3' => '', ), 'email' => 'CAPITALIZED@BLERGH.com', 'address' => array ( 'postcode' => 'ab1 1ba', 'line1' => 'test road', 'line2' => 'testville', 'line3' => 'testshire', ), 'date' => '2010-09-30' ) 

Хорошо, вот вам кое-что нужно выяснить:

 $data = array( 'title' => 'how to work with iterators', 'posts' => array( array( 'title' => 'introduction to iterators', 'email' => 'JohnDoe@example.com' ), array( 'title' => 'extending iterators', 'email' => 'JaneDoe@example.com' ) )); 

Основная идея – повлиять на то, как Iterator возвращает current элемент. Итераторы штабелируются, поэтому вы должны использовать RecursiveArrayIterator и обернуть его в RecursiveIteratorIterator . Для достижения пользовательских функций вы можете подклассифицировать RecursiveIteratorIterator (как показано ниже) или использовать дополнительные итераторы для украшения RecursiveIteratorIterator :

 class PostFormatter extends RecursiveIteratorIterator { public function current() { $current = parent::current(); switch($this->key()) { case 'email': $current = strtolower($current); break; case 'title': $current = ucwords($current); break; default: break; } return $current; } } 

Затем вы просто переходите через итератор

 $it = new PostFormatter(new RecursiveArrayIterator($data)); foreach($it as $key => $post) { echo "$key: $post", PHP_EOL; } 

и получить

 title: How To Work With Iterators title: Introduction To Iterators email: johndoe@example.com title: Extending Iterators email: janedoe@example.com 

Вы можете попытаться вернуть массив из функций iterator_to_array или iterator_apply . Однако, чтобы получить значения, повторно примененные к исходной структуре массива, вам не нужен итератор:

 array_walk_recursive($data, function(&$val, $key) { switch($key) { case 'title': $val = ucwords($val); break; case 'email': $val = strtolower($val); break; default: break; } }); print_r($data); 

Примечание: обменивайтесь Lambda с именем функции при использовании PHP <5.3