2009-05-18 10 views
11

W jednym bicie kodu, nad którym pracuję, muszę pobrać wartość z bazy danych i sprawdzić, czy jest to 0. Początkowo napisałem to jako:Jak najlepiej porównać do 0 w PHP?

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

Ale kiedy spojrzał na nią znowu dzisiaj, zdałem sobie sprawę błąd tam:

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

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

Ponieważ wartość ta pochodzi z bazy danych, które zwykle oznacza to będzie ciąg, więc przypuszczam, że mogę to zrobić:

if ($myVal === "0") 

ale wydaje się sprzeczne z intuicją, ponieważ tak naprawdę chcą mieć do czynienia z liczbą całkowitą, a th wydaje się pokazywać, że pracujemy z ciągami. (Mam nadzieję, że ma to sens dla ciebie). Również nie powinno być nieoczekiwane, że dowolny dany akcesor DB będzie rzutować wartości na ich odpowiedni typ, biorąc pod uwagę typ pola.

Jakiej metody używasz do sprawdzania wartości 0, jeśli może to być ciąg lub int?

+0

+1 Wydaje się tak proste, ale zaskakująco interesujące pytanie z żonglerki typu PHP. – cletus

Odpowiedz

19

wersja skrócona:

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

lub

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

Długa wersja:

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

o, to jest sprytne - nie pomyślałbym, aby przekonwertować to w inny sposób! – nickf

+1

Domyślam się, że długa wersja jest w rzeczywistości szybszą wersją. === to szybkie porównanie, ponieważ nie dokonuje konwersji typu. – jmucchiello

+0

@Jm: prawdopodobnie masz rację. To jest bardziej denerwujące w pisaniu. :) – cletus

2

Najlepszym Mam obecnie jest to:

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

Ten warunek zawsze zwróci false, ponieważ, jak powiedziałeś w swoim pytaniu, wartości z db są zwracane jako łańcuchy. $ myVal to ciąg znaków, a porównanie zostanie tutaj zatrzymane. Powinieneś rzucić swoją wartość na liczbę całkowitą przed wykonaniem porównania. –

+1

Właściwie bgy, is_numeric() zwróci wartość true dla ciągu liczbowego. Zobacz http://au2.php.net/is_numeric – thomasrutter

0

Spróbuj użyć intval() oddać ciąg do int

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

(intval ("to nie powinno być równe zero") == 0) jest prawdziwe – nickf

+0

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

+0

Przesyłanie ciągu znaków do int daje 0, chyba że ciąg zaczyna się cyframi. Ciąg "foo" rzuca się do 0, łańcuch "35foo" rzuca do 35. – dirtside

1

Jeśli wartości wrócisz z bazy danych są łańcuchami, ale oryginalny typ danych jest liczbą całkowitą, to prawdopodobnie chcesz, aby DAO (Data Access Object, czy cokolwiek to jest, że pociąga za danych), aby rzutować rzeczy na typy danych, których oczekujesz. W ten sposób kod PHP, który patrzy na wartości, analizuje typ danych, jakiego oczekuje.

Problem polega oczywiście na tym, że nie istnieje żadna relacja między typami danych, które definiuje DB, a typami danych zdefiniowanymi przez PHP. Jednak w większości przypadków nie stanowi to problemu, ponieważ dla większości typów, których używamy normalnie, istnieją typy równoważne: int, float, bool, string.

Efektem jest to, że między miejscem, w którym odpytujesz bazę danych, a miejscem, w którym sprawdzasz te wartości, te wartości powinny być rzutowane na oczekiwane typy danych. Właśnie testowałem z mysql_fetch_object() na tabeli MySQL zawierającej int (10) i varchar (50); oba pola zawsze były wczytywane jako "ciąg" przez PHP. Więc jeśli chcesz, aby jedno z pól było traktowane jako int, przesyłaj je do int, zanim zrobisz cokolwiek z nim. Na przykład:

$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 
} 

Zapytanie i rzeczy RealRow powinny znajdować się wewnątrz klasy/metody, tak aby były enkapsulowane; w ten sposób KAŻDA część kodu, który otrzyma dane z table, zawsze otrzyma obiekt $ RealRow, który będzie miał wszystko ustawione na właściwe typy danych.Oczywiście, jeśli zmienisz typy danych, wymaga to ręcznej edycji DAO, aby poradzić sobie z rzutowaniem; możliwe byłoby również zapytanie do DB, aby uzyskać typ każdego pola (z "POKAŻ KOLUMNY Z tablicy"), a następnie automatycznie odrzuć pola do właściwego typu danych.

+0

Polecenie "POKAŻ PEŁNE KOLUMNY Z myTable" jest znacznie prostszym sposobem określenia typów danych każdego pola. Czasami jednak ten poziom abstrakcji może być przesadzony w danej sytuacji. – nickf

+0

Wolałbym, jeśli "POKAŻ [PEŁNE] KOLUMNY" faktycznie zepsuł typy danych według podstawowego typu, przestrzeni wyświetlania, bez znaku, itd. W oddzielne pola, dzięki czemu był bardziej dostępny programowo. Teraz musisz ręcznie przeanalizować pole "Typ" na wyjściu ... chociaż jestem pewien, że ktoś ma do tego bibliotekę. – dirtside

1

myślę, że należy po prostu użyć

if ($myVal == 0) 

Nie sądzę, trzeba się martwić o to, czy $ myVal jest „foo”. Powiedziałeś sobie, że ta wartość to tylko liczba.

Innymi słowy, jeśli kiedykolwiek doświadczysz, że $ myVal jest "foo", błąd nie jest tym "foo" == 0, błąd polega na tym, że $ myVal to "foo", kiedy to ma być liczba.

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

Podczas gdy ten kod może odpowiedzieć na pytanie, podanie dodatkowego kontekstu dotyczącego tego, dlaczego i/lub jak ten kod odpowiada na pytanie, poprawia jego długoterminową wartość. –