2010-08-28 99 views
5

我需要創建一個foreach語句,它將貫穿併爲條件語句創建條件。我寫了這一點的代碼,沒想到它的工作,當然它沒有...在條件語句中放置一個foreach循環

$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 || 
    } 
) 

所以,這應該永遠能夠工作?還是我瘋了?如果真的沒有辦法在這樣的條件下放置一個循環,有人可以建議一個更好的方法來做到這一點?非常感激!

+3

它沒有意義或者它只是我嗎? – shamittomar 2010-08-28 15:53:57

+0

哈哈,可能確實沒有意義。我正在通過foreach測試數組,如果數組中的任何值與定義的字符串匹配,如果它確實做了一件事,如果它沒有做另一件事。 – 2010-08-28 15:57:04

回答

14

計算值事先,你不能用一個環路的表達式:

$val = false; 

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

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

在這種情況下,您可能只需要'if(strpos(...)=== 0){$ val = true;打破;}'在簡單的情況下做更少的工作。 – viraptor 2010-08-28 16:09:56

+0

這適合我的情況調整一下美麗的作品。非常感謝Felix的關注! – 2010-08-28 16:35:36

+0

@Ben:不客氣。正如@viraptor所說,你可以按照他描述的方式改進代碼。因爲如果'strpos($ ref,'http://'.$whitelist.'/')=== 0'曾經是'true',整個表達式將保持爲真,所以沒有必要測試更多的可能性。這就是'OR'的合理性。 – 2010-08-28 16:39:02

1

你要反轉兩種說法,把iffor循環中。在白名單上循環播放,一旦找到匹配項,請使用break設置標誌並退出循環。然後在循環之後檢查該標誌,看看它是否被設置。

$allowed = false; 

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

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

對於什麼是值得的,還有其他更具表現力的語言,您可以按照您嘗試的方式編寫代碼。在蟒蛇,比如,你可以寫:

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

那不能做,因爲foreach塊沒有返回值。

你想是這樣的:

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

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

計算條件的循環中,而不是事前。

$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 
    } 
}