English 中文(简体)
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);
for($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?

最佳回答

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
        )

)
问题回答

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.

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 ]);
}
?>




相关问题
SQL SubQuery getting particular column

I noticed that there were some threads with similar questions, and I did look through them but did not really get a convincing answer. Here s my question: The subquery below returns a Table with 3 ...

难以执行 REGEXP_SUBSTR

I m 查询Oracle 10g。 我有两张表格(样本数据见下文)。 i m 试图提取一些领域

SQL Query Shortcuts

What are some cool SQL shorthands that you know of? For example, something I learned today is you can specify to group by an index: SELECT col1, col2 FROM table GROUP BY 2 This will group by col2

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 ...

OracleParameter and DBNull.Value

we have a table in an Oracle Database which contains a column with the type Char(3 Byte). Now we use a parameterized sql to select some rows with a DBNull.Value and it doesn t work: OracleCommand ...

Running numbers in SQL

I have a SQL-statement like this: SELECT name FROM users WHERE deleted = 0; How can i create a result set with a running number in the first row? So the result would look like this: 1 Name_1 2 ...

How to get SQL queries for each user where env is production

I’m developing an application dedicated to generate statistical reports, I would like that user after saving their stat report they save sql queries too. To do that I wrote the following module: ...

热门标签