2009-10-08 7 views
20

In alcune lingue, si può fareEsiste un cortocircuito OR in PHP che restituisce il valore più a sinistra?

$a = $b OR $c OR die("no value");

Cioè, l'OR sarà corto circuito, solo valutando i valori da sinistra a destra finché non trova un vero valore. Inoltre, restituisce il valore effettivo che è stato valutato, al contrario di solo true.

Nell'esempio precedente, in PHP, $a sarà il valore 1 se uno o $a$b sono valori non-false, o sarà die.

Così ha scritto una funzione first, da utilizzare come

$a = first($a, $b, die("no value"));

che restituisce il valore di di una $a o $b. Ma, non cortocircuitare, sarà sempre die.

C'è un cortocircuito OR in PHP che restituisce il valore effettivo?

Edit: Alcune buone risposte per l'esempio che ho dato, ma credo che il mio esempio non è esattamente quello che volevo dire. Permettimi di chiarire.

$a = func1() OR func2() OR func3();

Dove ciascuna di queste funzioni fa un davvero intenso calcolo, quindi voglio solo per valutare ogni espressione una volta al massimo. E per il primo a restituire un valore vero, voglio che il valore attuale sia memorizzato in $a.

Penso che si possa escludere la scrittura di una funzione, perché non cortocircuiterà. E la risposta dell'operatore condizionale valuterà ciascuna espressione due volte.

+2

Questo, ovviamente, morirà sempre. Quando chiami una funzione, PHP deve prima valutare tutti i parametri. Durante la valutazione, vede 'die ("nessun valore")' e fa proprio questo. – Tom

+1

Valutare ogni espressione due volte andava bene quando parlavamo di variabili. Devi spiegare la tua domanda la prima volta e non criticare una risposta dopo aver presentato informazioni aggiuntive che non erano disponibili la prima volta. Se intendevi le funzioni, usa le funzioni la prima volta. La migliore risposta è ora il "no" del caos. –

+1

il commento n. 2 è errato. php ha una valutazione di cortocircuito ma AFAIK non restituisce la valle più a sinistra. Restituisce sempre un booleano. – apinstein

risposta

10

È possibile utilizzare solo:

$a = func1() or $a = func2() or $a = func3(); 

o mi sto perdendo qualcosa?

+0

Non esattamente quello che stavo cercando, ma è pulito e funziona. Grazie. – Steve

+16

Per valori sufficientemente "sporchi" di "pulito". – chaos

+3

Sopprimerò la risposta, ma sarebbe bello se potessi parlare a rovescio della lingua –

28

No, non c'è, e questo è, secondo me, una delle cattive decisioni prese da Rasmus Lerdorf nel progettare PHP che ostacola la maggior parte degli sviluppatori competenti al fine di covare quelli incompetenti.

Modifica: in PHP 5.3 e versioni successive, è possibile scrivere $a = $b ?: $c e anche $a = $b ?: $c ?: $d. Ancora non buono come gli operatori logici non danneggiati dal cervello, ma è qualcosa.

+3

?: La sintassi è, IMHO, completamente illeggibile. I cortocircuiti sarebbero stati tanto migliori che non è nemmeno paragonabile:/ –

+6

Non troverete argomenti da parte mia, signore. – chaos

2

Si potrebbe utilizzare un qualche tipo di coalesce function:

function coalesce() { 
    foreach (func_get_args() as $arg) { 
     if ($arg) { 
      return $arg; 
     } 
    } 
    return null; 
} 

$a = coalesce($a, $b) or die("no value"); 
+0

Questo non è completamente equivalente a un insieme di operatori logici correttamente funzionante (non consente che le espressioni complesse o le chiamate di funzione siano cortocircuitate e, naturalmente, ha molto più overhead), ma è qualcosa. – chaos

+1

Questo è bello, ma valuterà ciascuno degli argomenti da fondere, a differenza di un vero cortocircuito OR. Ad esempio, coalesce (true, launch_missiles()) o die ("the end is near") provocherà comunque il lancio di missili. – Shawn

1

Che dire funzioni variabili?

function coalesce($funcs) 
{ 
    foreach ($funcs as $func) 
    { 
     //Catch language constructs 
     switch($func) 
     { 
      case 'die': 
       die(); 
     } 
     $result = $func(); 
     if ($result) 
     { 
      return $result; 
     } 
    } 
} 
0

Questo dovrebbe funzionare:

$a = (($f1=func1()) ? $f1 : ($f2=func2()) ? $f2 : func3())); 
1

Mi dispiace, ma la maggior parte di questi risposta sono appena fuori.

$ a = $ b O $ c OR die ("nessun valore");

diventa

$a = $b ?: $c ?: die("no value"); 

la ragione o non funziona è che invece invece di restituire il valore primo o quest'ultimo restituisce vero o falso.

Problemi correlati