2010-08-28 42 views
5

Necesito crear una instrucción foreach que se ejecutará y creará condiciones para una declaración condicional. Escribí este trozo de código, sin esperar que funcione, y por supuesto no lo hice ...Colocar un bucle foreach dentro de una condició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 || 
    } 
) 

Por lo tanto, si esto nunca será capaz de trabajar? ¿O estoy solo loco? Si realmente no hay forma de poner un lazo en la condición de esta manera, ¿alguien podría sugerir una mejor manera de hacer esto? ¡Muy apreciado!

+3

¿No tiene sentido O soy solo yo? – shamittomar

+0

Jaja, probablemente no tiene sentido. Estoy ejecutando una matriz con pruebas foreach si cualquier valor en la matriz coincide con una cadena definida, si hace una cosa, si no hace otra. –

Respuesta

14

Calcular el valor de antemano, no se puede utilizar un bucle como una expresión:

$val = false; 

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

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

En ese caso, es posible que desee simplemente 'if (strpos (...) === 0) {$ val = true; romper;} 'hacer menos trabajo en casos fáciles. – viraptor

+0

Esto funciona muy bien con un poco de ajuste para adaptarse a mi situación. Muchas gracias por la atención Félix! –

+0

@Ben: De nada. Como dijo @viraptor, puedes mejorar el código de la forma que él describió. Porque si 'strpos ($ ref, 'http: //'.$whitelist.'/') === 0' es una vez' true', toda la expresión seguirá siendo verdadera, por lo que no tiene sentido probar otras posibilidades. Así es como funciona el 'OR' lógico. –

1

Usted tiene que invertir los dos estados y poner el if dentro del bucle for. Pasa el cursor sobre la lista blanca, y una vez que encuentres una coincidencia, establece una bandera y sal del círculo usando break. Luego, verifique esa marca después del ciclo y vea si alguna vez se configuró.

$allowed = false; 

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

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

Por lo que vale, hay otros idiomas más expresivos donde podría escribir el código de la forma en que lo intentó. En Python, por ejemplo, podría escribir esto:

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

Eso no se puede hacer debido a un bloque foreach devuelve nada.

quieres algo como esto:

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

con

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

Calcular la condición dentro del bucle, no antes.

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