PHP array callback functions for cleaning output
I have an array of output from a database. I am wondering what the cleanest way to filter the values is
example array
Array
(
[0] => Array
(
[title] => title 1
[cat_title] => Drawings
[sec_title] => Portfolio
)
[1] => Array
(
[title] => title 2
[cat_title] => Paintings
[sec_title] => Portfolio
)
[2] => Array
(
[title] => title 3
[cat_title] => Drawings
[sec_title] => Portfolio
)
)
As an example what would be the cleanest way to make all of the cat_title to uppercase and all of the sec_title's to htmlspecialchars?
I was thinking if i sorted the array improperly that I could use the array map function. like this
improper array
Array
(
[title] => Array
(
[0] => title 1
[1] => title 2
[2] => title 3
)
[cat_title] => Array
(
[0] => Drawings
[1] => Paintings
[2] => Drawings
)
)
Then I could do something handy like:
array_map('strtoupper', $array['cat_title']);
and make all of the cat_titles uppercase in one go. Something like that would sure beat this, which is what I have going on now.
$count = count($array);
fo开发者_运维技巧r($i=0; $i < $count; $i++) {
//filter list output
if (isset($array[$i]['cat_title'])) {
$array[$i]['cat_title'] = strtoupper($array[$i]['cat_title']);
}
}
Do you guys know of anyway I could callback functions on numbered array's a little bit more elegantly then above? Hopefully without sorting the array incorrectly? something like array_map or array_walk?
The Really Elegant way to do this is NOT to use associative arrays at all: make an array of objects. Turn your element into a Class which has a constructor, and title, cat_title, and sec_title as fields. Then make them private and use setters (or use a constructor) where you will check the data and perform any validation or transformation you need.
You can do this with array_walk
, it would be something like:
function cleanData( &$item, $key )
{
$item['cat_title'] = strtoupper( $item['cat_title'] );
$item['sec_title'] = htmlspecialchars( $item['sec_title'] );
}
array_walk( $arr, 'cleanData' );
However, functions like htmlspecialchars
are really only intended for the very last moment when you're actually sending content to the browser. Before then, you want to work with the raw text and just have <?=htmlspecialchars($var)?>
in your template/view file. Otherwise you can end up with encoding problems if you, for example, send that encoded data to a database, then retrieve it and run htmlspecialchars
again.
UPDATE: Here's the code I used to test this; it works fine for me. I'm on PHP 5.2 but there isn't any difference in the function from version 4+.
$arr = array(
array( 'title' => 'title 1', 'cat_title' => 'Drawings', 'sec_title' => 'Portfolio' ),
array( 'title' => 'title 2', 'cat_title' => 'Paintings', 'sec_title' => 'Portfolio' ),
array( 'title' => 'title 3', 'cat_title' => 'Drawings2', 'sec_title' => 'Portfolio' )
);
array_walk( $arr, 'cleanData' );
echo '<pre>', print_r($arr, true), '</pre>';
Outputs:
Array
(
[0] => Array
(
[title] => title 1
[cat_title] => DRAWINGS
[sec_title] => Portfolio
)
[1] => Array
(
[title] => title 2
[cat_title] => PAINTINGS
[sec_title] => Portfolio
)
[2] => Array
(
[title] => title 3
[cat_title] => DRAWINGS2
[sec_title] => Portfolio
)
)
My solution is using array_map and anonymous functions:
<?php
$data = array_map(
function($element) {
$element['cat_title'] = strtoupper($element['cat_title']);
$element['sec_title'] = htmlentities($element['sec_title']);
return $element;
},
$data);
?>
If you're using PHP < 5.3 you'd have to put the function somewhere else as these anonymous functions are a 5.3 feature.
I suppose you could simply use array_keys
, that at least would give you access to everything you want on a more basic level:
foreach( $holder as $subarr )
{
$keys = array_keys( $subarr );
foreach( $keys as $key )
{
switch( $key ):
{
case 'cat_title':
$subarr[ $key ] = strtoupper( $subarr[ $key ] );
break;
default:
$subarr[ $key ] = htmlspecialchars( $subarr[ $key ] );
}
}
}
Admittedly, this solution is a good deal more verbose than you need, but it will work.
I would recommend a foreach-loop instead as it is slightly faster as you save the overhead for unnecessary function calls.
<?php
foreach ($array as &$item) {
$item['cat_title'] = strtoupper($item['cat_title']);
$item['sec_title'] = htmlentities($item['sec_title']);
}
?>
精彩评论