2010-08-28 62 views
5

Tôi cần tạo một tuyên bố foreach sẽ chạy qua và tạo điều kiện cho câu lệnh có điều kiện. Tôi đã viết bit này của mã, không mong đợi nó để làm việc, và tất nhiên nó đã không ...Đặt vòng lặp foreach vào trong điều kiện if

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

Vì vậy, nên điều này bao giờ có thể làm việc? Hay tôi chỉ điên thôi sao? Nếu có thực sự không có cách nào để đặt một vòng lặp trong tình trạng như thế này, ai đó có thể đề xuất một cách tốt hơn để làm điều này? Nhiều đánh giá cao!

+3

Điều đó không có ý nghĩa HOẶC chỉ là tôi? – shamittomar

+0

Haha, có thể không có ý nghĩa gì cả. Tôi đang chạy qua một mảng với thử nghiệm foreach nếu bất kỳ giá trị trong mảng phù hợp với một chuỗi được xác định, nếu nó không làm một điều, nếu nó không làm khác. –

Trả lời

14

Tính giá trị trước đó, bạn không thể sử dụng một vòng lặp như là một biểu:

$val = false; 

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

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

Trong trường hợp đó, bạn có thể muốn chỉ đơn giản là 'if (strpos (...) === 0) {$ val = true; phá vỡ;} 'để làm ít công việc trong các trường hợp dễ dàng. – viraptor

+0

Điều này hoạt động tốt đẹp với một chút tinh chỉnh để phù hợp với tình hình của tôi. Cảm ơn rất nhiều vì đã chú ý Felix! –

+0

@Ben: Bạn được chào đón. Như @ viraptor đã nói, bạn có thể cải thiện mã theo cách mà họ mô tả. Bởi vì nếu 'strpos ($ ref, 'http: //'.$whitelist.'/') === 0' là một lần' true', toàn bộ biểu thức sẽ vẫn đúng, vì vậy không có điểm nào trong việc kiểm tra khả năng chiếm hữu thêm nữa. Đó là cách logic 'OR' hoạt động. –

1

Bạn cần phải đảo ngược hai câu lệnh và đặt if bên trong for vòng lặp. Lặp lại danh sách trắng và sau khi bạn tìm thấy một trận đấu, hãy đặt cờ và thoát khỏi vòng lặp bằng cách sử dụng break. Sau đó kiểm tra cờ đó sau vòng lặp và xem liệu nó đã được đặt chưa.

$allowed = false; 

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

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

Đối với những gì đáng giá, có các ngôn ngữ biểu cảm khác mà bạn có thể viết mã theo cách bạn đã cố gắng. Ví dụ, trong trăn, bạn có thể viết điều này:

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

Điều đó không thể thực hiện được vì khối foreach không trả về gì cả.

Bạn muốn một cái gì đó như thế này:

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

với

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

Tính tình trạng bên trong vòng lặp, không trước.

$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 
    } 
} 
Các vấn đề liên quan