Newsgroup: it.comp.www.php
Titolo: If che non funziona

Ciao a tutti,
non sono un programmatore php, stò solo cercando di approntare una piccola 
applicazione per la gestione dei device in azienda; una cosa molto semplice e 
banale.
Il problema che ho riguarda un if che non fà il controllo correttamente e non 
riesco assolutamente a capire il perchè!
Ho provato a verificare tutte le condizioni però non riesco a capire ma 
qualunque numero io inserisca lui rileva comunque i due valori uguali, perchè? 
Cosa ho sbagliato?
Potete aiutarmi?
 
La parte del codice incriminata è questa:
 
if($_POST['numsim'] && $_POST['numtel'])
  {
   $result = mysql_query('SELECT numsim FROM sim');
   while($query = mysql_fetch_array($result)) {
    //VISUALIZZO LE VARIABILI PER CAPIRE COSA VEDE PHP
    echo $query['numsim'], '<br>';
    echo $_POST['numsim'], '<br>';
 
     if($query['numsim'] == $_POST['numsim'])
      {
       echo '<p align="center"><b>ERRORE: la SIM esiste gia\'</b></p>';
       echo '<form>';
       echo '<input align="center" type="button" value="Indietro" 
onClick="javascript:history.back()" name="button">';
       echo '</form>';
       exit;
      }
   }
 
 
A prescindere dalle tantissime cavolate che trovate potreste aiutarmi a capire 
perchè non funziona, dov'è l'errore?
 
Grazie
Rizio


Io cambierei
while($query = mysql_fetch_array($result)) {
con
while($query = mysql_fetch_assoc($result)) {
 
 
 

    echo $_POST['numsim'], '<br>';
 
Cosa ti visualizzano queste echo ?
 
-- 
g4b0, linux user n. 369000
http://brosulo.net
 

 while($query = mysql_fetch_assoc($result)) {
 
:(
Ho provato con assoc al posto di array ma il risultato è sempre lo stesso :(
 
8119107800019879366
8119107800019879382
 
 
ERRORE: la SIM esiste gia'
 
 
A me fà pensare che stia comparando solo il tipo di variabile e non il contenuto 
della stessa, può essere?
 
Rizio

 Cosa ti visualizzano queste echo ?
 
Mi visualizzano 2 numeri differenti:
 
8119107800019879366
8119107800019879382
 
La cosa che davvero non capisco è quella!!!!
 
Come dicevo a Quasimodo mi dà l'idea che stia confrontando altro e non il 
contenuto delle variabili, ma non riesco a capire cosa nè perchè.
 
Rizio

 ERRORE: la SIM esiste gia'
 
PHP gira su una macchina a 32 o a 64bit?
 
Prova cosi`:
 
if ( 's'.$query['numsim'] == 's'.$_POST['numsim'] )
 
 
Bye.


A me su una macchina 64bit funziona correttamente.
Ma da mysql e da _POST non dovrebbero arrivare stringhe?
 
 


Hai provato con strncmp?
 
A me cmq funziona:
 
g4b0@gabodeb:~$ uname -a
Linux gabodeb 3.2.0-2-amd64 #1 SMP Mon Jun 11 17:24:18 UTC 2012 x86_64
GNU/Linux
 
g4b0@gabodeb:~$ php -v
PHP 5.4.4-2 (cli) (built: Jun 19 2012 07:38:55)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
    with Xdebug v2.2.0, Copyright (c) 2002-2012, by Derick Rethans
 
g4b0@gabodeb:~$ php -r 'var_dump('8119107800019879366' ==
'8119107800019879382');'
bool(false)


 A me cmq funziona:
 
Ci credo ed in effetti mi sembra davvero assurdo come problema però sai, non 
essendo un programmatore non sò, magari qualcosa mi era scappato.
 
Rizio

 Ma da mysql e da _POST non dovrebbero arrivare stringhe?
 
Si`, ma il mio dubbio e` che PHP converta la prima in numero per vedere 
se e` true o qualcosa del genere), e poi converta la seconda come la 
prima per confrontarle. A quel punto sono entrambi interi, che su un 
32bit vanno in overflow entrambi, e quindi sono uguali.
 
Solo che non ho macchine a 32bit per testare. :D
 
Aggiungendo una stringa davanti blocchi la conversione in intero e li 
confronti correttamente. Forse.
 
Mi piacerebbe sapere da Rizio se funziona.
 
Bye.

 if ( 's'.$query['numsim'] == 's'.$_POST['numsim'] )
 
Si, così funziona!!
Ma come mai??? In caso consiste quella s tra apici?
 
Grazie intanto per la soluzione.
Rizio

 Mi piacerebbe sapere da Rizio se funziona.
 
Si, come ti ho confermato in un altra mail.
Grazie ancora.
 
Rizio

 altri linguaggi?
 
Si`, puoi provare cosi`:
 
if ( (string)$query['numsim'] == (string)$_POST['numsim'] )
 
Anche se io preferisco essere ancora piu` esplicito:
 
if ( (string)($query['numsim']) == (string)($_POST['numsim']) )
 
Bye.

 if ( 's'.$query['numsim'] == 's'.$_POST['numsim'] )
 
Vecchia volpe della shell…

 if ( (string)($query['numsim']) == (string)($_POST['numsim']) )
 
Ok, userò uno di questi 2 metodi per pulizia.
 
Grazie ancora.
Rizio

 Hai provato con strncmp?
 
Sai che non riesco mica ad implementarlo?
Non ho capito perchè non riesco ad usarlo nell'if. Continua a darmi degli errori 
di sintassi relativi a parentesi graffe o virgole. Probabilmente dovrei 
"rivedere" il codice scritto prima e dopo per adattarlo meglio di quanto non 
abbia fatto ora.
 
Secondo me avrebbe comunque funzionato perchè avrei semplicemente dovuto 
verificare se restituiva 0 che significava che le stringhe erano uguali, e, 
visto che il problema è quello degli interi troppo grandi come scovato da 
Alessandro, avrei aggirato l'ostacolo.
 
Grazie comunque, per ora risolvo con lo (string) suggerito da Alessandro.
Rizio

Il 05/07/2012 14:34, Rizio ha scritto:

Non è molto che programmo in PHP, ma facendola più semplice per cercare 
di capire,
 
if($_POST['numsim'] && $_POST['numtel'])
 
// facendola più semplice e scrivendo
 
$A = $_POST['numsim'];
$B = $_POST['numtel'];
 
// che senso ha
 
if ($A and $b)
{
 
// esegui se la condizione and è vera
 
}
 
Non mi pare abbia molto senso.
Leonardo
 
 
 
 

 Non mi pare abbia molto senso.
 
Ne ha nella misura in cui
 
if ($_POST['numsim'])
 
viene implicitamente tradotto da PHP come
 
if ( !is_null($_POST['numsim']) )
 
e $_POST['numsim'] viene implicitamente tradotto in null quando in realta` 
e` undefined.
 
E` una serie di conversioni di tipo che a volte fanno comodo, ma a volte 
sono pericolose trappole.
 
Bye.

 Vecchia volpe della shell…
 
Già, vecchio trucco sempre efficace ;-)
 
Però... la spiegazione di Alessandro mi convince ma forse non basterebbe 
un operatore che testi insieme l'identità?
 
if($query['numsim'] === $_POST['numsim'])
 
-- 
Design for the future, because it will be here sooner than you think.
(C) Eric S. Raymond, from "The Art of Unix Programming"

 if (isset($_POST['numsim']) && isset($_POST['numtel']))
 
Ok, intanto la riscrivo così, grazie mille.
Rizio

 if($query['numsim'] === $_POST['numsim'])
 
Ho provato e così funziona, mi spieghi cosa sott'intende il terzo =
Relaziona anche il tipo della variabile? Perchè in realtà il problema non è 
sulla relazione ma quanto sull'automatismo di php di assumere il tipo di 
variabile dal contenuto e, in questo caso le considera numeriche e va in 
overflow. Perchè con il terzo uguale non succede?
 
Grazie
Rizio

 questo modo.
 
Se posso permettermi: per fortuna!
 
Molti pensano che programmare consista solo in prendere pezzi di codice 
qua e la` e metterli insieme per far andare "il coso".
 
Programmare e` un lavoro che richiede anni di studio. Come qualsiasi 
altro lavoro. Vale la regola delle 10.000 ore: puoi dire di saper fare 
qualcosa solo dopo che l'hai fatto per almeno 10.000 ore (con orari 
classici lavorativi sono 5 anni di pratica).
 
Se hai bisogno di un lavoro fatto bene ti rivolgi a un professionista.
 
Bye.

 32bit vanno in overflow entrambi, e quindi sono uguali.
 
A me questo comportamento pare un bug. Non ha senso, se hai una 
variabile nata stringa, farla diventare un intero per velocizzare il 
confronto. Se il programmatore mette "if ($st1 == $st2) " il compito del 
linguaggio è verificare se è vera o falsa, non farsi delle seghe mentali 
su tipi presunti per fare più in fretta.
Quindi se $st1 è stringa, deve iniziare a fare il confronto prima sulla 
lunghezza poi sui singoli byte o caratteri.
 
A questo punto mi viene in mente una domanda per Rizio: il campo 
'numsim' della tabella 'sim', è ben un VARCHAR, vero?
 
 
 

 tabella 'sim', è ben un VARCHAR, vero?
 
Si, è un VARCHAR
 
Rizio

 A me questo comportamento pare un bug.
 
Risolto l'arcano. Non e` un bug ed e` documentato:
 
http://php.net/manual/en/language.operators.comparison.php
 
 
Bye.

 Se hai bisogno di un lavoro fatto bene ti rivolgi a un professionista.
 
Si, hai ragione, ti dò pienamente ragione su tutta la linea.
Poi purtroppo esistono delle eccezioni ma credo che queste debbano essere 
limitate sia come tempo che come azione altrimenti torna vera la tua regola di 
chiusura: se ti serve qualcosa di "serio" e professionale ti rivolgi ad un 
professionista!
Io per ora sono nella fascia dell'eccezione ma non escludo che se l'applicazione 
venga rivista dai responsabili come qualcosa di "ufficiale" e non ad uso ufficio 
debba essere commissionata ad un programmatore vero perchè il mio intervento è 
solo per togliere il classico e maledetto foglio di excel!
 
Rizio

 e va in overflow. Perchè con il terzo uguale non succede?
 
Te lo ha spiegato Alessandro segnalando il link alla documentazione 
sugli operatori di confronto.
Se usi l'operatore === php non esegue conversioni di tipo, diversamente 
(0 == '0') ad esempio ritorna vero.



Adesso me lo ricordo! Era capitato anche a noi, però ne eravamo usciti 
consultando questa pagina:
http://www.php.net/manual/en/types.comparisons.php
 
(nel nostro caso era un ciclo while o simile che sballava perché 
valutava sempre FALSE il primo operando).
Comunque resta sempre un bug: se la conversione in intero porta ad un 
overflow (non credo che siano così pazzi da convertire in float), 
dovrebbe passare al confronto lessicale. Altrimenti ti trovi nel caso 
che un pezzo di codice funziona "magicamente" su alcune piattaforme, 
mentre "toppa" su altre (ovviamente quelle in produzione).
 

 '0') ad esempio ritorna vero.
 
Avevo seguito il link e letto (con taaaanto apprezzamento :) ) un pò ma non 
avevo capito.
La descrizione dell'operatore non mi era sembrata come quella che mi hai dato tu 
ora.
Nella parte descrittiva degli operatori di confronto il link dice:
$a === $b 	Identical 	TRUE if $a is equal to $b, and they are of the same type.
 
però mi devo essere perso la parte in cui dice che non esegue alcuna conversione 
(perciò immagino che lui gestisca tutto come stringa giusto?)
 
Grazie mille per la delucidazione
Rizio

 giusto?)
 
Se facesse la conversione non potrebbe confrontare il tipo, quindi e` 
implicito (forse un po' troppo implicito :) che non fa la conversione.
 
Bye.

 if (isset($_POST['numsim']) && isset($_POST['numtel']))
 
l'if dovrebbe implicitamente, grazie all'isset, valutare la presenza di valori 
all'interno delle variabili.
 
Però perchè se io nella pagina precedente clicco direttamente sul tasto di 
registrazione senza inserire alcun valore lui mi accetta ed esegue la query 
d'inserimento anche se i valori sono vuoti?
 
Rizio

 query d'inserimento anche se i valori sono vuoti?
 
Perche` comunque il form le passa al server, solo che passa stringhe 
vuote.
 
Stringa vuota e` diverso da variabile non settata. :)
 
Quell'if ti serve solo per capire se effettivamente le variabili sono 
arrivate da un form in POST e se sono state passate entrambi dal client.
 
Se vuoi verificare che non siano vuote devi usare (oltre all'isset) anche 
($_POST['numsim'] !== '') oppure (strlen($_POST['numsim) > 0)
 
Bye.

 arrivate da un form in POST e se sono state passate entrambi dal client.
 
Ok, grazie mille per l'ennesima volta.
Rizio

 Comunque resta sempre un bug:
 
+1, ma è storia vecchia ed il team di php la pensa diversamente (notare 
la data):
- 
https://bugs.php.net/bug.php?id=40115
 


 (perciò immagino che lui gestisca tutto come stringa giusto?)
 
Mhhh, non vedo dove tu abbia trovato la dichiarazione di questa costante :-)
 
Vero che php, almeno fino all'avvento della 5+, ha abituato i più 
ottimisti a comparare mele e banane senza farsi troppi scrupoli.
Almeno per me che vi sono approdato da un linguaggio fortemente 
tipizzato è stato un trauma.


 A prescindere dalle tantissime cavolate che trovate potreste aiutarmi a capire
 
parlando di altre cavolate, mi pare impossibile che nessuno ti abbia
ancora fatto notare che controllare se hai un dato in un DB così è
demenziale (parlando con affetto, eh) :^)
in pratica tu ogni volta ti selezioni tutti i dati che hai nel DB e ti
controlli a codice se uno è uguale a quello che cerchi... a parte che
se arriverai ad avere parecchi dati nel DB ti ci starà una vita,
questo è proprio il mestiere per cui sono nati i dbms, lasciamolo fare
a loro!
 
Riscrivi il codice con questo flusso (uso pseudocode per essere più
chiaro e perchè penso per te sia meglio se il codice vero te lo scrivi
da solo):
 
 Se (ho valori di numsim e numtel validi dal form) {
    $numsim = sanifica ($_POST['numsim']);
    Preparo una query ('select 1 from sim where numsim = ?', $numsim);
    Eseguo la query;
    Se (la query torna una riga) {
       Stampa un avviso di sim già registrata
       Redireziona ad un punto opportuno nel flusso di navigazion
    }
    altrimenti {
        procedi con l'elaborazione
    }
}
 
la pseudofunzione "sanifica" non è obbligatoria ma quando si prende un
dato di input è buona norma effettuare un po' di controlli, e quello
sarebbe il posto giusto dove farlo.
Se crei un indice sulla tabella sim relativo al campo numsim (come
appare logico fare) in questo modo la query sarà praticamente
immediata anche se dovessi registrare svariati milioni di SIM, con un
DB minimamente ben installato e configurato. Come l'avevi scritto te,
a occhio già con qualche migliaio di record vai in timeout.
 
bye!

 a loro!
 
Va bene, ti ringrazio moltissimo per i suggerimenti e si, in effetti ci credo 
che sia scritta con i piedi, come detto all'inizio sono alle prime armi e non è 
il mio compito perciò sono davvero tanto tanto indietro.
 
Cmq grazie mille davvero, cercherò di rimetterci le mani e regolare un pò il 
codice anche in funzione delle ottimizzazioni sql.
 
Rizio

 Mhhh, non vedo dove tu abbia trovato la dichiarazione di questa costante :-)
 
Da nessuna parte, era solo una mia congettura per cercare di spiegarmelo, 
nient'altro
 
Rizio

 leggere meglio
 
Purtroppo sulla documentazione di PHP le tabelle invadono visivamente lo 
schermo, ma se leggi il paragrafo di testo vicino alla tabella c'è 
scritto. :)
 
Bye.

 scritto. :)
 
Ok, sono una quaglia :)
 
Grazie per la delicatezza :) :) :)
 
Rizio