17

I have a custom post form that sends data to a page which uses wp_insert_post to create a post. I can easily sanitize most data, but I have some troubles with my tags, I retrieve in an array:

$tags =  $_POST['tags'];

Before using these tags as tags_input, how can I successfully sanitize all names?

Thanks!

4 Answers 4

46

Here's a way to do it with PHP's array map function:

// Good idea to make sure things are set before using them
$tags = isset( $_POST['tags'] ) ? (array) $_POST['tags'] : array();

// Any of the WordPress data sanitization functions can be used here
$tags = array_map( 'esc_attr', $tags );
5
  • +1 Looks like the right way to do it — stackoverflow.com/a/4861080/535406
    – jibiel
    Commented May 15, 2013 at 9:30
  • Yep, This looks like the way to go. Commented Dec 3, 2015 at 23:56
  • I think its a good practice Commented Oct 1, 2016 at 11:58
  • +1 yeh! that's actually I needed.
    – Frank
    Commented Oct 6, 2020 at 12:11
  • 6
    Functions like esc_attr() do NOT sanitize anything, and should never be used for that purpose. The sole exception to this is URLs, which can use esc_url() or esc_url_raw() when being saved.
    – mujuonly
    Commented Nov 4, 2020 at 7:14
9

I needed a recursive sanitation, so here's my solution:

/**
 * Recursive sanitation for an array
 * 
 * @param $array
 *
 * @return mixed
 */
function recursive_sanitize_text_field($array) {
    foreach ( $array as $key => &$value ) {
        if ( is_array( $value ) ) {
            $value = recursive_sanitize_text_field($value);
        }
        else {
            $value = sanitize_text_field( $value );
        }
    }

    return $array;
}
3
  • What't that & before $value for?
    – Daniel
    Commented Jun 23, 2018 at 8:13
  • 1
    When you iterate an array in a foreach statement, it works on a copy of that array. so if you really want to modify $value, you have to add & before it. see stackoverflow.com/questions/3307409/…
    – Broshi
    Commented Jun 23, 2018 at 20:09
  • Thanks - nice solution simple yet elegant.
    – Clinton
    Commented May 8, 2020 at 19:59
3

If anyone is interested, I solved it like this:

        $tags = $_POST['tags'];
        if (count($tags) > 5){
            echo 'Niet meer dan 5 tags';
            $stop = true;
        }

        if (is_array($tags)) {
            foreach ($tags as &$tag) {
                $tag = esc_attr($tag);
            }
            unset($tag );
        } else {
            $tags = esc_attr($tags);
        }
1
  • 2
    you should use sanitize_term instead of esc_attr, for your particular case Commented Aug 21, 2011 at 13:45
0

You can use this function for almost all cases.

/**
 * Recursive sanitation for text or array
 * 
 * @param $array_or_string (array|string)
 * @since  0.1
 * @return mixed
 */
function sanitize_text_or_array_field($array_or_string) {
    if( is_string($array_or_string) ){
        $array_or_string = sanitize_text_field($array_or_string);
    }elseif( is_array($array_or_string) ){
        foreach ( $array_or_string as $key => &$value ) {
            if ( is_array( $value ) ) {
                $value = sanitize_text_or_array_field($value);
            }
            else {
                $value = sanitize_text_field( $value );
            }
        }
    }

    return $array_or_string;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.