raffaele181188 ha scritto:@nuitari Ricapitoliamo. Sembra che questa funzione restituisca il nome dell'utente autenticato (o 0 in caso di errore) controllando id e password (già la logica di tutto questo mi sfugge, ma andiamo avanti). Essendo nuovo di PHP, ne approfitto per chiederti chiarimenti sull'
identical === Mi spiego
php.net ha scritto:
1- For SELECT, SHOW, DESCRIBE, EXPLAIN and other statements returning resultset, mysql_query() returns a resource on success, or FALSE on error.
2-$a === $b (Identical) TRUE if $a is equal to $b, and they are of the same type. (introduced in PHP 4)
3- Converting to Boolean: [...] Every other value is considered TRUE (including any resource)
Quindi se e solo se mysql_query() avverte un errore SQL il risultato è un
false booleano, in tutti gli altri casi restituisce una resource che viene valutata comunque come
true (anche se vuota). Domanda: quindi perchè === se if($risultato = mysql_query($q)) porterebbe allo stesso risultato ed è più compatto?
Eheh ho sorvolato anch'io sulla logica. Il motivo per l'utilizzo dell'identical è che il *not* è semanticamente sbagliato ed è un *bad habit* che porta a fare errori quando invece andrebbe usato. Inoltre è incongruente con la documentazione dell'API. E' vero che una risorsa valida viene convertita in TRUE nella tipizzazione debole del PHP, ma se la funzione restituisce come errore un FALSE booleano, è corretto verificare il FALSE booleano con l'operatore apposito, che è l'identical. Il modo di gestire una risorsa o la conversione dei tipi cambia in base ai settaggi dell'interprete e delle revisioni del PHP. Se il confronto è fatto rispettando *le regole*, il codice andrà sempre e comunque.
A meno che non cambino l'API, ovviamente, ma in tal caso trovare e sistemare le occorrenze nell'utilizzo diventa molto più semplice.
raffaele181188 ha scritto:
Poi questo blocco
Codice: Seleziona tutto
if (false === ($n_rows = mysql_num_rows($result)))
die("mysql_error: " . mysql_error());
non lo capisco. Provo a farmi seguire: per arrivare qui non bisogna uscire col die() di prima, quindi il risultato di mysql_query() deve essere una resource. Se il risultato è una resource mysql_num_rows() non restituirà mai false, ma tutt'al più 0 (zero), che comunque non sarà mai uguale a false usando === (identical). Quindi mi sembra che questo blocco non abbia chance di essere eseguito mai.
E invece ne ha eccome

Le funzioni di api mysql_* lavorano su risorse, sulla connessione al DB, etc. Possono succedere una quantità di errori che dipendono dall'api stessa, dalla connessione con il db, dalla gestione di PHP della risorsa, dagli interventi del programmatore, etc. Se la documentazione dell API specifica che questa funzione può restituire FALSE on failure (e questo è il caso di mysql_num_rows()), è compito del programmatore verificare il valore di ritorno nel modo appropriato. La differenza fra lo *spaghetti code* ed un buon codice almeno per il 50% risiede nel controllo dei codici di errore restituiti dalle funzioni.
raffaele181188 ha scritto:
E a proposito dell'ultimo if, che viene eseguito se mysql_fetch_row() restituisce false,
Codice: Seleziona tutto
if (false === ($query_data = mysql_fetch_row($result)))
die("mysql_error: " . mysql_error());
ti faccio notare che questo accade se e solo se non ci sono più risultati nella resource. E poichè il nostro select non può restituire più di UN SOLO riscontro ciò significa che mysql_num_rows($resource) ritornerebbe 0 (nel caso l'utente non sia nel db), e quindi la funzionre ritornerebbe 0 a causa del blocco immediatamente precedente. Anche questo blocco non può essere eseguito. Ovviamente ti chiedo così tante cose perchè mastico poco di PHP e mi sembra, a questo punto, di non capirci un c
Vai tranquillo, chiedere è lecito, rispondere è cortesia

Questa è stata solo estrema pignoleria. Per logica non dovrebbe arrivare li se i risultati sono quelli premessi, hai ragione. Il fatto è che lui ha una situazione di errore, e per risolvere una situazione di errore devi applicare controlli completi, a volte persino estremi. Per cui, piuttosto che perdere tempo a rimbalzare fra 1.000 post ho preferito suggerirgli di scrivere la funzione in questo modo, a prova dell'errore più scemo, di corruzione della memoria, etc.
Volendo concludere, non bisogna mai dare per scontati i risultati e bisogna SEMPRE controllare i valori di ritorno delle funzioni nel modo corretto, non facendo MAI affidamento sulle conversioni e su altri meccanismi *impliciti*, se si vuole scrivere codice *sempre* funzionante.
Scrivendo codice di una certa complessità mi è capitato d'incappare in corruzioni della memoria in PHP, trovandomi con risultati inaspettati in cose come gli array superglobal. Scrivevo codice del tipo:
Codice: Seleziona tutto
echo $_REQUEST["username"];
$username = $_REQUEST["username"];
echo $username;
il primo echo mi restituiva il valore corretto, il secondo un riferimento ad una risorsa... è illogico vero? eppure può accadere. Se verifichi ogni operazione che esegui nel modo corretto, scovare e risolvere bug, limitare i comportamenti imprevisti dell'applicazione dovuti agli errori tuoi e quelli non gestiti dell'utente diventa molto, molto più semplice
