Curiosità sulla istruzioni switch di PHP

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Avatar utente
aschenaz
Staff
Staff
Messaggi: 4623
Iscritto il: mer 28 lug 2004, 0:00
Nome Cognome: Nino
Slackware: current
Kernel: 5.4.x
Desktop: KDE
Località: Reggio Calabria
Contatta:

Re: Curiosità sulla istruzioni switch di PHP

Messaggio da aschenaz »

@ spina: d'accordo, ma per l'esempio posto da samiel andava bene. :)

@ samiel: comunque sia, col costrutto switch-case, ottieni maggiori chiarezza
e linearità nel codice. Dopo tutto, può anche diventare una questione di stile...

Mi sono ricordato di un mio vecchio progetto php-gtk, in cui c'era una situazione
molto simile: si trattava di calcolare i valori percentili della crescita dei bambini.
Allora avevo optato per switch-case, col metodo suggerito da giberg e nuitari;
ad esempio, nel calcolo della statura:

Codice: Seleziona tutto

switch($hpc) {
			case ($hpc>69 && $hpc<80):
				$hgh="ALTA";
			break;
			case ($hpc>79):
				$hgh="MOLTO ALTA";
			break;
			case ($hpc<30):
				$hgh="BASSA";
			break;
			default:
				$hgh="MEDIA";
		} // switch

Avatar utente
nuitari
Linux 3.x
Linux 3.x
Messaggi: 777
Iscritto il: dom 14 ott 2007, 12:51
Slackware: 12.0
Località: San Colombano al Lambro
Contatta:

Re: Curiosità sulla istruzioni switch di PHP

Messaggio da nuitari »

spina ha scritto: Anche a me piace questa soluzione (la prendo per funzionante visto che l'hai scritta), rende il codice più leggibile. Però anche qui, un numero o appartiene all'intervallo (3,8) o all'intervallo (-inf, 3] o all'intervallo [8,+inf), quindi il secondo case dovrebbe essere (>=8) e non (>3) e il terzo (<=3) e non (<8), non trovi?
Certo che funziona, provo sempre il codice prima di postarlo ^^ Per quanto riguarda gli operatori di confronto, usando >= e <= non si sarebbe mai verificato il "default", perchè i case avrebbero *coperto* tutte le eventualità.
Ho spezzato il check iniziale in due parti volutamente, per chiarire un concetto importante: lo switch non *salta* all'istruzione adatta, ma verifica i case in sequenza, motivo per cui il check più restrittivo va effettuato per primo.
spina ha scritto: Più precisamente è il break che interrompe lo switch!
Spina
Mai asserito il contrario... io parlavo di un altra cosa: al verificarsi del primo case, switch termina di eseguire i check . Significa che dal momento della verifica con successo del primo case, gli ulteriori case vengono del tutto ignorati, break o non break. Che poi il break faccia uscire forzatamente dal costrutto è un altro discorso.

Ragazzi, avete fatto un errore nel codice che avete postato, attenzione.
Switch esegue un confronto fra il valore passato all'istruzione switch ed il valore dei vari case. Se all'interno di un case viene inserito un confronto booleano, il valore restituito sarà boolaeano (true/false). Per cui il valore da confrontare è a sua volta da considerare booleano.
Per chiarire, facciamo un esempio. Il codice:

Codice: Seleziona tutto

<?php
$temperatura = 0;

switch ($temperatura)
{
	case ($temperatura < 10):
		echo "minore di 10";
		break;
		
	default:
		echo "altro";
}
?> 
per quanto potrebbe apparire corretto, darà un risultato inaspettato, ci visualizzerà "altro".
Il motivo è che, come ho spiegato, il risultato di un confronto booleano è booleano (true/false) e lo 0 nelle conversioni di tipo vale false. Per cui, il check "($temperatura < 10)" restituirà true, che verrà confrontato con il valore nello switch $temperatura che essendo 0 viene convertito in false, ed il risultato sarà mancato riscontro, pertanto il costrutto passerà al default.
Il codice di cui sopra va obbligatoriamente scritto nel seguente modo:

Codice: Seleziona tutto

<?php
$temperatura = 0;

switch (true)
{
	case ($temperatura < 10):
		echo "minore di 10";
		break;
		
	default:
		echo "altro";
}
?> 
ed in tal caso il risultato sarà "minore di 10", come da previsione. Altre forme sono errate, a meno che non ci sia sott'inteso un comportamento voluto.
Se non sono stato chiaro e devo dare ulteriori delucidazioni, ditemelo e cercherò di spiegarmi meglio.

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6643
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: Curiosità sulla istruzioni switch di PHP

Messaggio da targzeta »

nuitari ha scritto:...
Ho spezzato il check iniziale in due parti volutamente, per chiarire un concetto importante: lo switch non *salta* all'istruzione adatta, ma verifica i case in sequenza, motivo per cui il check più restrittivo va effettuato per primo
...
:lol: si si, era chiaro ma...
nuitari ha scritto:...
al verificarsi del primo case, switch termina di eseguire i check . Significa che dal momento della verifica con successo del primo case, gli ulteriori case vengono del tutto ignorati, break o non break. Che poi il break faccia uscire forzatamente dal costrutto è un altro discorso.
...
Qui sono io che volevo spiegare un altro concetto. Se ho questo switch

Codice: Seleziona tutto

switch( $a )
{
  case 1: $b=13;
  case 2: $b=21;
              break;
  case 3: $b=35;
              break;
}
echo $b;
Se a == 1, il risultato sarà 21, e non 13 come ci si aspettava (anche se il check ha fatto bene il suo lavoro).

Spina
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama

Avatar utente
nuitari
Linux 3.x
Linux 3.x
Messaggi: 777
Iscritto il: dom 14 ott 2007, 12:51
Slackware: 12.0
Località: San Colombano al Lambro
Contatta:

Re: Curiosità sulla istruzioni switch di PHP

Messaggio da nuitari »

ahhh adesso ho capito che intendevi :D pensavi io dicessi che viene ignorato il case con il codice relativo. io intendevo che solo le ulteriori *istruzioni* "case .." sono ignorate, non il codice sottostante. Incomprensione risolta ^^

Ovviamente il break va messo per interrompere l'esecuzione. Per inciso, l'unica vera differenza fra switch() e if()/elseif() è proprio la possibilità di far condividere a check differenti lo stesso blocco di codice. Es.:

Codice: Seleziona tutto

switch ($numero_da_1_a_10)
{
    case "2":
    case "4":
    case "8":
    case "10":
        echo "pari";
        break;

    default:
        echo "dispari";
}

Rispondi