简体   繁体   中英

foreach loop not working

I'm trying to use a foreach loop to search for word in $_POST, but it doesn't work? Help is preciated.

$unsafeWords = array('content-typ','bcc','cc');
foreach ($_POST as $key => $input) {
    foreach ($unsafeWords as $value) {
        $_POST = str_ireplace($value, "", $input) ;
    }
}

Don't overwrite the $_POST array with a string

$unsafeWords = array('content-typ','bcc','cc');
foreach ($_POST as $key => $input) {
    foreach ($unsafeWords as $value) {
        $_POST[$key] = str_ireplace($value, "", $input) ;
    }
}

though I dislike overwriting the original $_POST array and would prefer to build a new array of cleaned values

Note that you don't need to loop the $unsafeWords array, but can pass an it as an array directly to str_ireplace()

EDIT

Example of using the $unsafeWords array as an argument for str_ireplace() rather than looping through it with foreach() and calling str_ireplace() for each entry.

$unsafeWords = array('content-type','bcc','cc');
foreach ($_POST as $key => $input) {
    $_POST[$key] = str_ireplace($unsafeWords, "", $input) ;
}

and you're not replacing with a space, you're replacing with an empty string (effectively removing the unsafe strings from your $_POST vars)

EDIT 2

I guess it's OK to put this inside the foreach loop as well?

Not quite... if you're just adding it as an extra line within the loop, you'll overwrite your previous substitutions. Do it as:

$unsafeWords = array('content-type','bcc','cc');
foreach ($_POST as $key => $input) {
    $_POST[$key] = str_ireplace($unsafeWords, "", filter_var($input, FILTER_SANITIZE_STRIPPED)) ;
}

You are trying to overwrite $_POST (which is an array) with string values. The correct way is this:

foreach ($_POST as &$input) {
    $input = str_ireplace($unsafeWords, array(), $input) ;
}

The above code also takes advantage of a couple other features ( foreach with a reference as loop variable, str_ireplace accepting arrays) to be much shorter.

Not completely clear what you're asking but this:

 $_POST = str_ireplace($value, "", $input) ;

definitely won't do what you expect. You probably want:

 $_POST[$key] = str_ireplace($value, "", $input) ;

Try this instead (missing $key at the assignment)

$unsafeWords = array('content-typ','bcc','cc');
foreach ($_POST as $key => $input) {
    foreach ($unsafeWords as $value) {
        $_POST[$key] = str_ireplace($value, "", $input) ;
    }
}

Aside form that foreach problem, it seems very insufficient validation in terms of mail injection protection.

For the email field I'd use some regexp-based or filter_var() solution. For the name and subject fields I'd suggest to encode it according to RFC rules.

So, I believe that safe code could be (in case of utf-8 encoded email):

if ($email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){
  $subject = "=?UTF-8?B?".base64_encode($_POST['subject'])."?=";
  $from    = "From: =?UTF-8?B?".base64_encode($_POST['name'])."?= <$email>\r\n";
  $message = str_replace("\n.", "\n .", $_POST['text']);
  mail('me@example.com',$subject,$message,$from);
}

If you want to remove indexes from the $_POST array that are specified in the $unsafeWords, then you went on with the wrong approach. Use unset() function to remove the index you don't want or simply set it to

foreach($_POST as $key => $input)
{
    if(in_array($input, $unsafeWords)
    {
        $_POST[$key] = null; // or $_POST[$key] = '' or unset($_POST[$key]
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM