开发者

Placing a foreach loop inside an if condition

I am needing to create a foreach statement that will run through and create conditions for a conditional statement. I开发者_StackOverflow中文版 wrote this bit of code, not expecting it to work, and of course it didn't...

$filename = "whitelist.txt";
$handle = fopen($filename, 'r');
$whitelist = fread($handle, filesize($filename));
fclose($handle);
$whitelist = explode("\n", $whitelist);
if (
  foreach ($whitelist as $value) {
    strpos($ref, 'http://'.$value.'/')===0 ||
  }
)

So, should this ever be able to work? Or am I just crazy? If there is really no way to put a loop in the condition like this, could someone suggest a better way to do this? Much appreciated!


Compute the value beforehand, you cannot use a loop as an expression:

$val = false;

foreach ($whitelist) {
   $val = $val || strpos($ref, 'http://'.$whitelist.'/')===0;
}

if($val) {
    // ...
}


You have to invert the two statements and put the if inside the for loop. Loop over the whitelist, and once you find a match set a flag and exit the loop using break. Then check that flag after the loop and see if it ever got set.

$allowed = false;

foreach ($whitelist as $url) {
    if (strpos($ref, "http://$url/") === 0) {
        $allowed = true;
        break;
    }
}

if ($allowed) {
    // Do what you want to do.
}

For what it's worth, there are other more expressive languages where you could write the code the way you tried to. In python, for instance, you could write this:

if any(ref.starts_with('http://'+url+'/') for url in whitelist):
    # Found a whitelisted URL.


Compute the condition inside the loop, not beforehand.

$filename = "whitelist.txt";
$handle = fopen($filename, 'r');
$whitelist = file($handle)
fclose($handle);
foreach ($whitelist as $line) {
    if(strpos($ref, 'http://'.$line.'/')) {
       //do stuff
    }
    else {
      // do not do stuff
    }
}


That can't be done because a foreach block returns nothing.

You want something like this:

if (for_any($whitelist,
    function ($arg) use ($ref) { return strpos($ref, 'http://'.$arg.'/')===0; } ) {
    /* ... */
}

with

function for_any(array $arr, $func) {
    return array_reduce($arr,
        function ($a, $v) use ($func) {
            return $a || call_user_func($func, $v);
        }, true);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜