2011-11-07 16 views
7

Il mio obiettivo è mettere una logica complessa in una dichiarazione if(). Diciamo che ho una matrice di valori e ho intenzione di eseguire un po 'di codice se tutto nel mio array è diverso da zero. Normalmente, potrei dire, $valid = true, foreach il mio array e impostare $valid = false quando viene trovato uno zero. Quindi eseguirò il mio codice if ($valid). In alternativa, potrei inserire il mio loop in una funzione e inserire la funzione nel mio if().Cosa restituiscono le chiusure PHP nelle istruzioni IF?

Ma io sono pigro, quindi preferirei non muck con un gruppo di bandiere "valide", e preferirei non scrivere una funzione completamente nuova che viene utilizzata solo in un posto.

Quindi diciamo che ho questo:

if ($q = function() { return 'foo'; }) { 
    echo $q; 
} 
else { 
    echo 'false'; 
} 

mi aspettavo che il if ottiene 'foo', che restituisce true. La mia chiusura è impegnata a $q e l'istruzione viene eseguita. $q restituisce la stringa foo e "foo" viene stampato.

Invece, viene visualizzato l'errore Object of class Closure could not be converted to string.

Quindi proviamo questo, invece:

if (function() { return false; }) { 
    echo 'foo'; 
} 
else { 
    echo 'true'; 
} 

mi aspettavo che la mia funzione sarebbe tornato falso e 'vero' sarebbe da stampare. Invece, viene stampato 'foo'.

Cosa c'è di sbagliato nel modo in cui sto andando a riguardo? Sembra che stia dicendo "Sì, quella è sicuramente una funzione!" invece di "No, perché la funzione è stata valutata su false". C'è un modo per fare ciò che sto cercando di fare?

+3

Lei sembra confondere le funzioni con i loro valori di ritorno. – delnan

+0

Suppongo che quello che volevo fosse più vicino a 'if (function() {return false;}()) {' che è apparentemente valido in Javascript ma non in PHP. – ajp5103

+0

http://stackoverflow.com/questions/3568410/anonymous-functions-that-execute-immediately call_user_func() è quello che stavo cercando. – ajp5103

risposta

4

function() { return false; } crea un oggetto di tipo Closure, simile a new con altri di classe tipi, confrontare il codice seguente:

$func = function() { return false; }; 

$func ora è un oggetto. Ogni oggetto restituisce true in una clausola if. Così

if ($func) 
{ 
    # true 
} else { 
    # will never go here. 
} 

si potrebbe desiderare di fare questo, invece:

if ($func()) 
{ 
    # true 
} else { 
    # false 
} 

che richiamerà l'oggetto Chiusura $func e dare il suo valore di ritorno.

3

Entrambi valutano true.

È necessario eseguire la funzione per utilizzarla nell'istruzione if.

Prova questo:

$q = function() { return false; }; 
if ($q()) { //should not go here. 
    echo $q(); 
} 
else { 
    echo 'false'; 
} 

Demo: http://codepad.viper-7.com/Osym1s

1

Non stai eseguendo la chiusura quando si chiama echo, così sta cercando di stampare la chiusura, non il risultato della chiusura:

echo $q(); 
0

Si sta creando una funzione anonima, ma mai eseguirlo . Quando si prova $q = function() { return 'foo'; }, si sta dicendo "Assegna un riferimento a questa funzione anonima a $ q e passa questo test se $ q non è nullo" (non è divertente PHP?)

È necessario richiamare la chiusura e assegnare il suo risultato a $q prima di eseguire il test ed echeggiare $q.

2

Le chiusure di PHP sono implementate come un hack - oggetti di tipo Closure. Il codice in realtà crea un'istanza di un oggetto di questa classe e lo assegna a $ q. In PHP, il risultato della cessione è il valore di essere assegnati, così in effetti si codice si riduce a

if (new Closure()) { ... } 
Problemi correlati