Размещение цикла foreach внутри условия if - PullRequest
6 голосов
/ 28 августа 2010

Мне нужно создать оператор 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 ||
  }
)

Итак, должно ли это когда-нибудь работать?Или я просто сумасшедший?Если на самом деле нет способа поместить цикл в такое состояние, кто-нибудь может предложить лучший способ сделать это?Очень ценится!

Ответы [ 4 ]

15 голосов
/ 28 августа 2010

Предварительно вычислить значение, вы не можете использовать цикл в качестве выражения:

$val = false;

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

if($val) {
    // ...
}
1 голос
/ 28 августа 2010

Вы должны инвертировать два оператора и поместить if в цикл for.Зацикливайтесь на белом списке, и как только вы найдете совпадение, установите флаг и выйдите из цикла, используя break.Затем проверьте этот флаг после цикла и посмотрите, установлен ли он когда-либо.

$allowed = false;

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

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

Для чего бы то ни было, существуют другие более выразительные языки, где вы можете написать код так, как пытались.В Python, например, вы могли бы написать это:

if any(ref.starts_with('http://'+url+'/') for url in whitelist):
    # Found a whitelisted URL.
0 голосов
/ 28 августа 2010

Вычислить условие внутри цикла, а не заранее.

$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
    }
}
0 голосов
/ 28 августа 2010

Этого нельзя сделать, потому что блок 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...