Newsgroup: it.comp.www.php
Titolo: gli OR ( || ) negli if vengono valutati tutti?

devo valutare il contenuto di una stringa e a seconda dei casi (ognuno dei quali esclude gli altri) assegnare tale stringa ad una variabile o lasciare la variabile vuota.
 
nella gran parte dei casi il contenuto è abbastanza semplice e lo potrò verificare con uno strpos.  in altri casi sarà necessario fare uso di espressioni regolari e preg_match.
 
pensavo quindi a qualcosa del genere:
 
if (
   strpos ( $stringa_da_verificare, 'semplice_1' ) !== false )
   ||
   strpos ( $stringa_da_verificare, 'semplice_2' ) !== false )
   ||
   preg_match ( [regex_complicata_1], $stringa_da_verificare ) === 1 
   ||
   preg_match ( [regex_complicata_2], $stringa_da_verificare ) === 1 
) {
   // salva la stringa da qualche parte
}
 
avendo letto però che preg_match è (ovviamente) più onerosa computazionalmente di strpos mi è venuto il dubbio (direi la certezza) che anche se $stringa_da_verificare contiene 'semplice_1' comunque i preg_match seguenti verrebbero valutati con sforzo e tempi computazionali inutili.
 
una cosa come la seguente potrebbe essere meglio?
 
if ( strpos ( $stringa_da_verificare, 'semplice_1' ) !== false ) ) {
   // salva la stringa da qualche parte
} elseif ( strpos ( $stringa_da_verificare, 'semplice_2' ) !== false ) {
   // salva la stringa da qualche parte
} elseif ( preg_match ( [regex_complicata_1], $stringa_da_verificare ) === 1 ) {
   // salva la stringa da qualche parte
} elseif ( preg_match ( [regex_complicata_2], $stringa_da_verificare ) === 1 
) {
   // salva la stringa da qualche parte
}
 

 <snip>
 
Rispondendo al subject, no, una serie di condizioni logiche viene
corto-circuitata il prima possibile.
 
Ciao!

 lasciare la variabile vuota.
 
ti rispondo con un esempio
 
if(1 || $a['pippo']){
echo 'non ho ricevuto warning da  $a[\'pippo\'] perchè non lo ha mai 
valutato';
}

grazie ad entrambi!

Ci sono operatori logici completi o a cortocircuito
 
AND e OR
 
valutano da entrambi gli operandi, invece && e || prima quello sinistro e se ha senso anche il destro.
 
esempio:
if(array_key_exists('parametro',$_GET) && $_GET['parametro'] == 5)
non esegue il lato destro evitandoti il warning per aver acceduto ad una chiave inesistente
if($a<$b AND ++c = 5)
valuta entrambi gli operandi anche se $a non è minore di $b
 
Gli operatori hanno una precedenza diversa
http://php.net/manual/it/language.operators.precedence.php
 

valuta entrambi gli operandi anche se $a non è minore di $b
 
Codice così andrebbe bombardato dall'orbita anche se funzionasse ;-)
 
Ma non funziona; se $a non è minore di $b (e.g. se $a fosse maggiore di $b),
$c non viene toccato.
 
<?php
$a = 10;
$b = 5;
$c = 10;
 
if ($a < $b AND ++$c ==  5 ) { }
 
print "$c vale 10, non 11 e tantomeno 5\n";
 
?>
 
In caso contrario, $c sarebbe incrementato e varrebbe 11.
 
Leonardo
-- 
 
Some say the world will end in fire; / some say in ice.
From what I’ve tasted of desire, / I hold with those who favor fire.
But if it had to perish twice, / I think I know enough of hate
To say that for destruction ice / Is also great, / And would suffice.

 
 
No.
la differenza tra AND,OR,&& e || è solo la precedenza.
Lo trovi scritto nella pagina che hai link-ato tu stesso.
 
IMHO non dovevano proprio lasciarli, i primi due, che non c'hanno senso, ma
vabbè, ci teniamo anche 'sta roba.
 
Ciao!

A prescindere che è un esempio e che non credo di aver mai asserito che sarebbe diventato 5.
La cosa importante è che tu hai ragione, a differenza di java da dove provengo (provenivo) per il buon php tutti gli operatori sono short-circuit.
Quindi chiedo venia.


http://php.net/manual/it/language.operators.precedence.php
 
illustra che gli operatori hanno una precedenza diversa ma non parla di short-circuit.
 
A parte questo non credo di aver mai usato i full (in java, lo preciso non si sa mai) e ho avuto difficoltà a creare un esempio che ne dimostrasse l'utilità.
 

Leonardo si hai interpretato bene:
 
if($a<$b AND ++c = 5) 
 
doveva essere comparazione e non assegnazione.
 
if($a<$b AND ++c == 5) 

 l'utilità.
 
Io Java lo conosco pochino, però se intendi & e |, contrapposti a && e ||,
non sono semplicemente operatori bitwise? Sì, bitwise estesi sui booleani
(perché in Java, per costruzione, tutto dev'essere più difficile del
massimo necessario) ma come i & e | del C o del PHP - no?
 
Ciao!


Sì, però è codice pericoloso; se lo scrivi in Java e usi qualcosa tipo
CodeStyle, io credo che quella riga lui te la "multi".
 
E' meglio (e anche a costo di perderci due nanosecondi di performance)
scrivere qualcosa come
 
    if ($a < $b) {
        $c++;
        if (5 == $c) {
            ...
        }
    }
 
in modo che sia chiaro cosa succede e quando.
 
Purtroppo in PHP, specie usando funzioni anonime, si riesce a scrivere
anche roba indecifrabile :-D



Dal buon google:
http://www.freejavaguide.com/boolean_operators.htm
 
 
Ormai java non lo conosco più nemmeno io ma ho visto che anche c e c++ hanno gli operatori  non short circuit, mentre javascript taglia la testa al toro e non ammette AND e OR ma solo la versione short circuit && || !.
 
Grazie per la risposta

Il giorno mercoledì 19 agosto 2015 22:09:39 UTC+2, Leonardo Serni ha scritto:

Sfondi una porta aperta, la difficoltà che ho avuto a ideare l'esempio era di trovare qualcosa che funzionasse in un modo col short e in un altro col full. Ho pensato ad un incrementazione, andava bene anche un metodo che modificasse proprietà interne di un oggetto oltre a dare il risultato, ma avrei dovuto scrivere la classe.
 
ciao

 
 
Vediamo la stessa cosa sotto due punti diversi, spiego meglio il mio:
 
& e | *non* sono operatori logici, sono operatori binari, fanno AND e OR così
come lo fanno le porte logiche, a due, otto, sessantaquattro o Nmila ingressi.
In C (e quindi anche in C++ e PHP) per entrare in un if bisogna che la
rappresentazione dell'argomento non sia zero.
"if (a op b)" significa fare "a op b" e se il risultato è zero salto,
altrimenti entro.
Accanto a & e |, che sono i blocchi base di qualsiasi macchina, hanno messo in
C i due && e ||, che si traducono, a livello macchina, come una serie di & |
mischiati a if: "if (a && b)" diventa "if(a){if(b){..}}" (e || si può fare
con && e De Morgan), per cui è, se vuoi, del syntactic sugar.
 
C++ e PHP seguono lo stesso ragionamento - che a me pare non fare una piega,
visto che ricalca quello che fa la macchina.
 
Java, ha tutti i suoi oggettini e classettine, tra cui boolean, in cui &,|,&&
e || (che sono sempre operatori) vanno in overload (e vabbè). C'è anche la
restrizione (perché i programmatori Java sono notoriamente imbecilli e vanno
quindi salvati da loro stessi (questa era l'idea)) che l'argomento di un if
deve per forza essere boolean (e non c'è il cast automatico a boolean, sempre
per il motivo di cui sopra). Cape sapienti vanno ora in giro a fare la 
distinzione tra operatori short-circuit e non-short-circuit, tacendo il fatto
che 'sta porcata esiste solo in Java: nei linguaggi "decenti", come descritto
sopra, gli operatori (binari e logici) seguono regole "umane"! :)
 
M2C,
Ciao!

 ...i programmatori Java sono notoriamente imbecilli...
Credo che la cosa sia sconfinata in una guerra di religione, per cui grazie per l'interessamento, ma ciao.


 
Non hai capito, quello non è il mio pensiero, avevo infatti aggiunto un
"(quella era l'idea)". Non è religione, è la storia di come è nato il
linguaggio, delle idea che si porta dietro e di quali targets ha.
 
Java del 2015 non è più il Java del 1995, un programmatore Java è in media
molto più skill-ato di un programmatore PHP (questo è un dato di fatto, basta
vedere cosa ci si sviluppa e quanto sono gli stipendi), ma rimane il fatto
che deve lottare con un linguaggio che spesso anche lui ritiene "scemo".
 
Ciao!