2009-05-18 10 views
11

In un bit di codice su cui sto lavorando, ho bisogno di estrarre un valore dal database e controllare se è 0. In origine, avevo scritto questo come:Il modo migliore per confrontare con 0 in PHP?

if ($myVal == 0) { ... 

Ma quando ho guardato di nuovo oggi, mi sono reso conto di un bug non:

var_dump("foo" == 0); // bool(true) 

// and while we're here... 
var_dump(intval("foo")); // int(0) 

Dal momento che questo valore proviene dal database, che solito significa che sarà una stringa, quindi suppongo che potrei fare questo:

if ($myVal === "0") 

ma sembra contro-intuitivo, dato che in realtà voglio avere a che fare con un numero intero, e tH sembrerebbe mostrare che stiamo lavorando con le stringhe. (spero che abbia senso per voi.) Inoltre, non dovrebbe essere inaspettato che qualsiasi data accessor di DB possa trasmettere valori al tipo appropriato, dato il tipo di campo.

Quale metodo si usa per verificare un valore di 0 quando potrebbe essere una stringa o un int?

+0

+1 Sembra una domanda di base, ma sorprendentemente interessante, data la giocoleria di tipo PHP. – cletus

risposta

19

Versione corta:

if ("$myVal" === '0') 

oppure

if (strval($myVal) === '0') 

Versione lunga:

if ($myVal === 0 || $myVal === '0') 
+1

oh questo è intelligente - non avrei mai pensato di convertirlo nell'altro modo! – nickf

+1

La mia ipotesi è che la versione lunga sia in realtà la versione più veloce. === è un confronto veloce perché non esegue conversioni di tipo. – jmucchiello

+0

@ Jm: probabilmente hai ragione. È solo più fastidioso digitare. :) – cletus

2

Il migliore che ho avuto al momento è questa:

is_numeric($myVal) && $myVal == 0 
+0

Questa condizione restituirà sempre false, poiché come hai detto nella tua domanda, i valori di db vengono restituiti come stringhe. $ myVal è una stringa e il confronto si fermerà qui. Prima di eseguire il confronto, è necessario trasmettere il valore a un numero intero. –

+1

In realtà bgy, is_numeric() restituirà true per una stringa di un valore numerico. Vedere http://au2.php.net/is_numeric – thomasrutter

0

Provare a utilizzare intval() per lanciare la stringa in un int

if(intval($myVal) == 0) 
+3

(intval ("questo non dovrebbe essere uguale a zero") == 0) è vero – nickf

+0

-1: intval ('null') restituisce 0 – ya23

+0

Lanciare una stringa a un int restituisce 0 a meno che la stringa non inizi con le cifre. La stringa "foo" viene convertita in 0, la stringa "35foo" viene convertita in 35. – dirtside

1

Se i valori si ottiene indietro dalla banca dati sono stringhe, ma il tipo di dati originale è intero, allora probabilmente volete che il vostro oggetto DAO (Data Access, o qualunque cosa sia che sta tirando il dati) per trasmettere le cose ai tipi di dati che ti aspetti. In questo modo, il codice PHP che sta guardando i valori sta esaminando il tipo di dati che si aspetta.

Il problema è, naturalmente, che non esiste una corrispondenza 1-1 tra i tipi di dati definiti dal DB e i tipi di dati definiti da PHP. Tuttavia, per la maggior parte questo non è un problema, dal momento che esistono tipi equivalenti per la maggior parte dei tipi che usiamo normalmente: int, float, bool, string.

Il risultato è che tra il luogo in cui si esegue una query nel database e il luogo in cui si verificano tali valori, è necessario eseguire il cast dei valori sui tipi di dati previsti. Ho appena provato con mysql_fetch_object() su una tabella MySQL contenente un int (10) e un varchar (50); entrambi i campi sono sempre stati inseriti come tipo "stringa" da PHP. Quindi, se vuoi che uno dei campi sia trattato come int, fallo un int prima di fare qualcosa con esso. Per esempio:

$rs = mysql_query("SELECT * FROM table"); 
while ($row = mysql_fetch_object($rs)) { 
    $RealRow->id = (int)$row->id; 
    $RealRow->name = $row->name; 
    // etc. 
} 

// ... later ... 

if ($RealRow->status == 0) { 
    // do something 
} 

La query e roba RealRow dovrebbe essere all'interno di una classe/metodo, in modo che sia incapsulato; In questo modo, QUALSIASI parte del codice che ottiene i dati da table otterrà sempre l'oggetto $ RealRow, che avrà tutto impostato sui tipi di dati corretti.Ovviamente, se si modificano i tipi di dati, è necessario modificare manualmente il DAO per gestire il casting; sarebbe anche possibile interrogare il DB per ottenere il tipo di ogni campo (con una "MOSTRA COLONNE DA tabella"), e automaticamente cast i campi al tipo di dati corretto.

+0

Il comando "MOSTRA COLONNE COMPLETE FROM myTable" è un modo molto più semplice per determinare i tipi di dati di ciascun campo. A volte, tuttavia, questo livello di astrazione può essere esagerato per una determinata situazione. – nickf

+0

Preferirei se "MOSTRA [PIENO] COLUMNS" abbia effettivamente suddiviso i tipi di dati per tipo di base, spazio di visualizzazione, senza segno, ecc. In campi separati, in modo che fosse accessibile a livello di programmazione. In questo momento devi analizzare manualmente il campo "Tipo" dell'output ... anche se sono sicuro che qualcuno ha una libreria per questo. – dirtside

1

penso che si dovrebbe semplicemente usare

if ($myVal == 0) 

non credo sia necessario preoccuparsi se $ myVal è "pippo". Hai detto a te stesso che questo valore sarà sempre e solo un numero.

In altre parole, se si verifica che $ myVal sia "foo", il bug non è "foo" == 0, il bug è che $ myVal è "foo", quando dovrebbe essere un numero.

0
if(('integer' === gettype($is_anonymous) && $is_anonymous === 0) 
    || 
    ('string' === gettype($is_anonymous) && $is_anonymous === '0')  
) { 
    echo 'matches'; 
} 
+0

Sebbene questo codice possa rispondere alla domanda, fornire un contesto aggiuntivo sul perché e/o su come questo codice risponde alla domanda migliora il suo valore a lungo termine. –

Problemi correlati