2009-05-18 40 views
11

Trong một bit mã tôi đang làm việc trên, tôi cần phải kéo một giá trị từ cơ sở dữ liệu và kiểm tra xem nó là 0. Ban đầu, tôi đã viết điều này như:Cách tốt nhất để so sánh với 0 trong PHP?

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

Nhưng khi tôi nhìn vào nó một lần nữa ngày hôm nay, tôi nhận ra một lỗi có:

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

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

Kể từ khi giá trị này được phát ra từ cơ sở dữ liệu, mà thường có nghĩa là nó sẽ là một chuỗi, vì vậy tôi cho rằng tôi có thể làm điều này:

if ($myVal === "0") 

nhưng có vẻ phản trực giác vì tôi thực sự muốn xử lý một số nguyên và thứ sẽ xuất hiện để cho thấy rằng chúng tôi đang làm việc với các chuỗi. (Tôi hy vọng điều đó có ý nghĩa đối với bạn.) Ngoài ra, không được bất ngờ khi bất kỳ trình truy cập DB nào cho phép đưa các giá trị vào loại thích hợp của chúng, với kiểu trường.

Bạn sử dụng phương pháp nào để kiểm tra giá trị 0 khi nó có thể là chuỗi hoặc int?

+0

+1 Có vẻ rất cơ bản nhưng lại là một câu hỏi thú vị đáng ngạc nhiên đối với việc tung hứng kiểu PHP. – cletus

Trả lời

19

phiên bản ngắn:

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

hoặc

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

phiên bản Long:

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

oh đó là thông minh - tôi sẽ không có ý nghĩ chuyển đổi theo cách khác! – nickf

+1

Tôi đoán là phiên bản dài thực sự là phiên bản nhanh hơn. === là so sánh nhanh vì không có chuyển đổi loại nào. – jmucchiello

+0

@Jm: có lẽ bạn đã đúng. Nó chỉ là khó chịu hơn để gõ. :) – cletus

2

Điều tốt nhất tôi đã hiện đã là thế này:

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

Điều kiện này sẽ luôn trả về false, vì như bạn đã nói trong câu hỏi của bạn, các giá trị từ db được trả về dưới dạng chuỗi. $ myVal là một chuỗi và so sánh sẽ dừng ở đây. Bạn nên bỏ giá trị của mình vào một số nguyên trước khi thực hiện so sánh. –

+1

Trên thực tế bgy, is_numeric() sẽ trả về true cho một chuỗi giá trị số. Xem http://au2.php.net/is_numeric – thomasrutter

0

Hãy thử sử dụng intval() để đúc chuỗi đến một int

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

(intval ("số này không bằng 0") == 0) là đúng – nickf

+0

-1: intval ('null') trả về 0 – ya23

+0

Truyền chuỗi thành int kết quả bằng 0 trừ khi chuỗi bắt đầu bằng chữ số. Chuỗi "foo" chuyển thành 0, chuỗi "35foo" chuyển thành 35. – dirtside

1

Nếu các giá trị bạn nhận được trở lại từ cơ sở dữ liệu là chuỗi, nhưng datatype ban đầu là số nguyên, sau đó bạn có thể muốn đối tượng DAO (Data Access của bạn, hoặc bất cứ điều gì được đó là kéo dữ liệu) để truyền nội dung đến các loại dữ liệu bạn mong đợi. Theo cách đó, mã PHP đang xem xét các giá trị đang xem xét kiểu dữ liệu mà nó mong đợi.

Vấn đề là, tất nhiên, không có sự tương ứng 1-1 giữa các kiểu dữ liệu mà DB xác định và các kiểu dữ liệu PHP định nghĩa. Tuy nhiên, đối với hầu hết các phần này không phải là một vấn đề, vì có loại tương đương cho hầu hết các loại chúng ta sử dụng bình thường: int, float, bool, string.

Bản cập nhật là giữa vị trí nơi bạn truy vấn cơ sở dữ liệu và địa điểm bạn kiểm tra các giá trị đó, các giá trị đó sẽ được truyền sang các loại dữ liệu bạn mong đợi. Tôi chỉ thử nghiệm với mysql_fetch_object() trên một bảng MySQL có chứa một int (10) và một varchar (50); cả hai trường luôn được kéo theo kiểu "chuỗi" bằng PHP. Vì vậy, nếu bạn muốn một trong các lĩnh vực được coi là một int, cast nó vào một int trước khi bạn làm bất cứ điều gì với nó. Ví dụ:

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

Truy vấn và công cụ RealRow phải nằm trong một lớp/phương pháp để nó được đóng gói; theo cách đó, bất kỳ phần nào của mã của bạn nhận dữ liệu từ table sẽ luôn nhận đối tượng $ RealRow thay thế, sẽ có mọi thứ được đặt thành các loại dữ liệu thích hợp.Tất nhiên, nếu bạn thay đổi kiểu dữ liệu của bạn, điều này đòi hỏi phải tự chỉnh sửa DAO để đối phó với việc đúc; nó cũng sẽ có thể truy vấn DB để có được kiểu của mỗi trường (với một "SHOW COLUMNS FROM table"), và tự động truyền các trường vào kiểu dữ liệu thích hợp.

+0

Lệnh "HIỂN THỊ TÓM TẮT ĐẦY ĐỦ TỪ myTable" là cách dễ dàng hơn nhiều để xác định loại dữ liệu của từng trường. Tuy nhiên, đôi khi, mức trừu tượng này có thể vượt quá mức đỉnh cho một tình huống cụ thể. – nickf

+0

Tôi muốn nếu "HIỂN THỊ [ĐẦY ĐỦ] COLUMNS" thực sự đã chia nhỏ các loại dữ liệu theo loại cơ bản, không gian hiển thị, không được ký, v.v. thành các trường riêng biệt, để có thể truy cập theo chương trình hơn. Ngay bây giờ bạn phải tự phân tích cú pháp trường "Loại" của đầu ra ... mặc dù tôi chắc rằng ai đó có thư viện cho điều đó. – dirtside

1

Tôi nghĩ rằng bạn chỉ nên sử dụng

if ($myVal == 0) 

Tôi không nghĩ rằng nó cần thiết phải lo lắng về việc liệu $ myVal là "foo". Bạn đã tự nói rằng giá trị này chỉ là một con số.

Nói cách khác, nếu bạn từng trải nghiệm $ myVal là "foo", lỗi không phải là "foo" == 0, lỗi là $ myVal là "foo", khi được cho là số.

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

Mặc dù mã này có thể trả lời câu hỏi, cung cấp ngữ cảnh bổ sung về lý do và/hoặc cách mã này trả lời câu hỏi cải thiện giá trị lâu dài của nó. –

Các vấn đề liên quan