Tại sao PHP lại coi 0 0 là FALSE trong bối cảnh boolean?


12

"0", dưới dạng một chuỗi chứa một ký tự, không phải là thứ gì đó trống rỗng bằng trực giác. Tại sao PHP coi nó là FALSE khi được chuyển đổi thành boolean, không giống như các ngôn ngữ lập trình khác?


2
trùng lặp: stackoverflow.com/questions/523643/ . Nó giống nhau trong cả PHP và javascript, hãy kiểm tra câu trả lời bên dưới câu trả lời được chấp nhận.
Walfrat

5
Đó là bởi vì PHP đi rất dài để không nhất quán, với cả chính nó và mọi ngôn ngữ lập trình khác, càng tốt.
David Arno

2
@DavidArno Ngược lại, nó là tốt nhất để được nhất quán ; một khi bạn bắt đầu tự động xâu chuỗi (rất tiện dụng trong một ngôn ngữ thường lấy các vars từ URL hoặc các cơ quan yêu cầu), bạn phải tuân theo logic đó. Nếu '0'được đối xử như 0trong $x + 1, tại sao nó cũng không nên được coi là 0, và do đó false, trong if ( $x )?
IMSoP

1
@DavidArno chính xác;)
linuxunil

1
@DavidArno Một khi bạn bắt đầu thực hiện các diễn viên mất mát, tôi nghĩ rằng một số mâu thuẫn là không thể tránh khỏi; giải pháp nhất quán liên quan đến việc từ chối một số diễn viên, và thiết kế phần còn lại rất cẩn thận. Rất ít ngôn ngữ phổ biến được thiết kế từ đầu; hầu hết phát triển từ các thí nghiệm vô tình phổ biến, hoặc từ các ngôn ngữ cũ với các mục tiêu và hành lý khác nhau. Ngay cả C #, có rất nhiều thiết kế lý thuyết âm thanh, cũng có một số di sản từ C, vốn không bao giờ có ý định phổ biến như nó đã trở thành. Snark như "đi rất lâu để không nhất quán" giống như hét vào ref trong một trận đấu thể thao.
IMSoP

Câu trả lời:


12

PHP được thiết kế (hoặc, đúng hơn là phát triển) để sử dụng cho các yêu cầu web, trong đó bạn thường xuyên xử lý đầu vào chuỗi (tham số URL hoặc yêu cầu POST từ một biểu mẫu trong trình duyệt). Như vậy, nó sẽ tự động truyền chuỗi sang các loại khác.

Một ví dụ đơn giản về điều này là '1' + '2'đưa ra 3, không phải là lỗi, hoặc '12', hoặc một số giải thích khác. Theo cùng một logic, chuỗi '0'có thể được sử dụng như một số 0.

Trong khi đó, giống như nhiều ngôn ngữ, PHP coi các giá trị nhất định là "giả" khi chuyển sang boolean - những ngôn ngữ "trực giác" trống rỗng, như bạn nói. Điều đó bao gồm số 0, cũng như chuỗi trống ''và mảng trống []. Trong một ifcâu lệnh, biểu thức được truyền rõ ràng thành boolean, do đó, if ( 0 )giống như if ( false ).

Đặt hai thứ này lại với nhau, bạn sẽ nhận được một câu hỏi hóc búa: một mặt, như bạn nói '0'là một chuỗi không trống; mặt khác, chúng tôi đã nói rằng nó có thể được sử dụng như một số 0, "trống". PHP chọn cách coi "zero-ness" quan trọng hơn "tính nghiêm ngặt", do đó '0'được coi là "giả mạo".

Tóm lại : '0' == 0 == false; hoặc là(bool)'0' === (bool)(int)'0'


Có ai đó hạ thấp câu trả lời của tôi chỉ vì tôi dám bảo vệ PHP và trả lời câu hỏi bằng một thứ khác ngoài một trò đùa rẻ tiền và không biết gì? Hoặc có điều gì đó không chính xác hoặc không có ích trong câu trả lời của tôi mà họ muốn chỉ ra?
IMSoP

1
Tôi nghĩ rằng PHP đã lấy điều này từ Perl, có cùng một "0" hành vi là sai hành vi. Trong Perl, theo nghĩa đen không có bất kỳ sự khác biệt nào mà người dùng có thể nhìn thấy giữa chuỗi "0"và số 0- gây khó chịu khi xử lý JSON, nhưng rất trực quan khi xử lý dữ liệu văn bản. Sau đó, không thể có số 0là falsey mà không có chuỗi "0"là falsey. PHP và JavaScript mượn quyết định thiết kế này, nhưng thêm một số nhầm lẫn bằng cách phân biệt dây / bools / kiểu dữ liệu trong khi vẫn cho phép chuyển đổi tiềm ẩn (PHP: 0 == "0 foo", 0 == false, nhưng "0 foo" == true: ==không bắc cầu)
amon

@amon Có, Perl sử dụng cách tiếp cận thú vị của (gần) tất cả các toán tử và các hàm dựng sẵn buộc các toán hạng thành một loại cụ thể, với các toán tử bổ sung như eqcho đẳng thức chuỗi. Tuy nhiên, điều này không cứu nó khỏi sự không chuyển đổi của các diễn viên mất mát: "0 foo"là sự thật trong bối cảnh boolean, nhưng bằng với 0dưới ==. Vì vậy, if ( ! $foo ) ..$false = (1 == 2); if ( $foo == $false ) ... không đưa ra kết quả tương tự. Tôi đoán ngôn ngữ đang thiếu toán tử "boolean
Equality

Mặc dù "0" là 0 khi được đánh giá là số, nhưng khi chúng tôi sử dụng một chuỗi trong ngữ cảnh boolean (ví dụ trong câu lệnh if), chúng tôi không quan tâm đến giá trị số của nó. Nếu chúng ta muốn diễn giải nó dưới dạng số, chúng ta sẽ so sánh nó với một số, ví dụ $_POST['id'] == 0, điều này làm cho ý định rõ ràng rằng chúng ta muốn coi đầu vào của người dùng là một số.
Michael Tsang

1
@MestreLion Ví dụ đó là của Perl chứ không phải PHP. Sự khác biệt quan trọng là không có loại boolean riêng biệt trong Perl, do đó $falsekết thúc được đặt thành 0; Vì vậy, khi bạn viết $foo == $false, Perl không biết bạn muốn so sánh boolean và thay vào đó là int. Trong PHP, điều đó không xảy ra, vì $falselà boolean false, do đó ==chuyển sang boolean, cho kết quả tương tự như!
IMSoP

3

Theo tài liệu PHP về booleans , nó nói rằng:

Khi chuyển đổi sang boolean, các giá trị sau được coi là FALSE
...
chuỗi rỗng và chuỗi "0"
...

Nếu không thì:

Mọi giá trị khác được coi là ĐÚNG (bao gồm mọi tài nguyên).

Nếu bạn chạy:

var_dump((bool) "0");

Nó sẽ in:

bool (sai)

Vì vậy, nó hoạt động như mong đợi.


Để trả lời rõ ràng câu hỏi của bạn:

Tuy nhiên, trong hầu hết các trường hợp, việc truyền là không cần thiết, vì một giá trị sẽ được tự động chuyển đổi nếu một toán tử, hàm hoặc cấu trúc điều khiển yêu cầu một đối số boolean.

Điều này có nghĩa là "autocast" của PHP sẽ chuyển "0" thành số nguyên 0, FALSEcũng như trong cấu trúc điều khiển như nói một if()câu lệnh.


Tôi muốn biết lý do căn bản của quyết định thiết kế coi "0" là FALSE khi được chuyển đổi thành boolean, thay vì nhu cầu đúc rõ ràng.
Michael Tsang
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.