views:

124

answers:

4

I have $_GET['tags'] = "apples, oranges, bananas, grapes, cherries"

I need to place the data into an array ($tags).

What is a quick way to trim each item and perform security functions (stripping html, special chars)?

+1  A: 

Try the following:

function process_tags($tags) {
    $tags = strip_tags($tags);
    $tags = explode(',', $tags);
    foreach($tags as $key => $value) {
        $tags[$key] = htmlentities($tags[$key]);
        $tags[$key] = trim($tags[$key]);
    }

    return $tags;
}

You can simply call the function in the following way:

$myTags = "apples, berries, oranges";
$tags = process_tags($myTags);
Andrew Moore
@Chacha102: No, as you want to trim around delimiters (`,`). Trimming beforehand will not do that.
Andrew Moore
Ahh... comment deletion magic...
Andrew Moore
Wouldn't there be a way to strip out all the newlines/other characters without going through a foreach statement?
Chacha102
I deleted my comment because I felt it was already stated in my answer, and didn't want to create noise :)
Chacha102
@Chacha102: A regex, which will cost you as much (if not more) than a simple foreach (as you don't want to remove valid spaces such as a tag called "two words").
Andrew Moore
Fair enough, I withdraw my answer :)
Chacha102
+3  A: 

With array_walk() you could write your tag cleaning function separately, and then easily apply it to your incoming data.

function sterilize(&$val,$key)
{
    //do whatever security you need here
    $val = trim($val);
    $val = strip_tags($val);
    //etc
    return htmlspecialchars($val);
}
$bad_values = explode(',',$_GET['tags']);
array_walk($bad_values,'sterilize');
zombat
You haven't used `strip_tags()` anywhere.
too much php
The way the question was asked, "What is a quick way to trim each item and perform security functions (stripping html, special chars)?" appeared to me to leave some ambiguity as to which security functions would actually be applied, so I separated the concerns. You could write the sterilize() function however you wished. I can add in tag stripping for conciseness I suppose.
zombat
I've always used `array_map()` but I guess `walk` is more efficient if you don't need it returned?
Mark
+1  A: 

Using array_map to apply trim() and htmlentities to all items in the array, you can do it in one line:

$tags = array_map('htmlentities', array_map('trim', explode(',', strip_tags($_GET["tags"]))));
too much php
+1  A: 

Be careful how you do this. HTML escaping is an output task, and not something you want to do with data you don't intend to immediately print to the page.

I think it pages to be fairly explicit with this sort of thing, and really separate the filtering of content from the escaping of content.

// First, get the tags as an array, filtered to be valid data
$tags = array_map( 'filterTag', explode( ',', $_GET['tags'] ) );

// Do whatever other processing with $tags

// NOW, create a version of the tags that you'll use for display only
// or do this step ONLY just prior to display
$tagsSafeForHtml = array_map( 'escapeForHtml', $tags );

function filterTag( $tag )
{
  // Use whatever combination of filtering functions you want
  return trim( strip_tags( $value ) );
}

function escapeForHtml( $value )
{
  // Use whatever escaping strategy that makes most sense for your content
  return htmlspecialchars( $value, ENT_COMPAT, 'UTF-8' );
}
Peter Bailey