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);
}
精彩评论