Phân tích một chuỗi thành một giá trị boolean trong PHP


126

Hôm nay tôi đã chơi với PHP và tôi phát hiện ra rằng các giá trị chuỗi "true" và "false" không được phân tích cú pháp chính xác thành boolean trong một điều kiện, ví dụ như xem xét hàm sau:

function isBoolean($value) {
   if ($value) {
      return true;
   } else {
      return false;
   }
}

Nếu tôi thực thi:

isBoolean("true") // Returns true
isBoolean("") // Returns false
isBoolean("false") // Returns true, instead of false
isBoolean("asd") // Returns true, instead of false

Nó dường như chỉ hoạt động với các giá trị "1" và "0":

isBoolean("1") // Returns true
isBoolean("0") // Returns false

Có một hàm riêng trong PHP để phân tích các chuỗi "true" và "false" thành boolean không?


Trong mã của bạn, isBoolean("")nên trả về false.
BoltClock

Bạn nên xem xét việc thay đổi câu trả lời được chấp nhận cho câu trả lời của Eric Caron. Nó cho bạn thấy một hàm riêng thực hiện những gì bạn yêu cầu.
Chỉ huy mã

1
PHP không nghĩ về những gì chuỗi nói, "false" chỉ là năm ký tự không có nghĩa gì. Chúng là một cái gì đó , vì vậy giá trị boolean đánh giá truemặc dù đối với người đọc con người, nó có vẻ trực quan hơn mà nó có nghĩa FALSE.
zeel

Câu trả lời:


413

Có một phương thức PHP gốc để thực hiện việc này sử dụng phương thức filter_var của PHP:

$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN);

Theo hướng dẫn của PHP :

Trả về TRUE cho "1", "true", "on" và "yes". Trả về SAI nếu không.

Nếu FILTER_NULL_ON_FAILURE được đặt, FALSE chỉ được trả về cho "0", "false", "tắt", "không" và "" và NULL được trả về cho tất cả các giá trị không phải là boolean.


Đây phải là câu trả lời được chấp nhận. Các hàm PHP được xây dựng tốt hơn là xây dựng các hàm của riêng bạn. Không cần phải sáng chế lại bánh xe! Quá tệ, đã quá muộn: P
casraf

1
nó cũng viết thường giá trị để so sánh?
Mob xuất sắc

3
@Mobiletainment, vâng - nó xử lý bất kỳ vỏ bọc nào bạn có thể tưởng tượng với giá trị $ (false, FALSE, FalSe, v.v.)
Eric Caron

Borked testcase vào cuối của tôi. Được sử dụng == thay vì === để so sánh. Sẽ xóa bình luận trước đó của tôi để không gây nhầm lẫn cho mọi người.
andig

6
Câu trả lời khiến tôi mất cảnh giác vì bạn phải thêm cờ FILTER_NULL_ON_FAILUREvào filter_var()hàm và KHÔNG thay thế nó FILTER_VALIDATE_BOOLEANnhư tôi nghĩ. Điều này sẽ dẫn đến mã sau đây đã lừa tôi:$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)
Dragon54

14

Lý do là tất cả các chuỗi đánh giá truekhi chuyển đổi chúng thành boolean, ngoại trừ "0"""(chuỗi trống).

Hàm sau sẽ thực hiện chính xác những gì bạn muốn: nó hoạt động chính xác như PHP, nhưng cũng sẽ đánh giá chuỗi "false"false:

function isBoolean($value) {
   if ($value && strtolower($value) !== "false") {
      return true;
   } else {
      return false;
   }
}

Tài liệu giải thích rằng: http://php.net/manual/en/lingu.types.boolean.php :

Khi chuyển đổi sang boolean, các giá trị sau được coi là FALSE:

  • FALSE boolean chính nó
  • số nguyên 0 (không)
  • số float 0,0 (không)
  • chuỗi rỗng và chuỗi "0"
  • một mảng có các phần tử bằng không
  • loại NULL đặc biệt (bao gồm các biến không đặt)
  • Các đối tượng SimpleXML được tạo từ các thẻ trống

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


2
+1 Đẹp. (Có thể tặc lưỡi một strtolower ở đó, nhưng đó là về nó.)
John Parker

Tôi nghĩ rằng middaparka có nghĩa là so sánh strtolower ($ value) với 'false'. Truyền một chữ 'sai' theo nghĩa đen vào strtolower là một chút .... :)
Paul Dixon

@Paul Dixon Yup, đó là những gì tôi đã đề cập. :-)
John Parker

2
@Marco - if ($ value && strtolower ($ value)! == "Faux") {nếu bạn đang làm việc bằng tiếng Pháp; if ($ value && strtolower ($ value)! == "falsch") {bằng tiếng Đức; if ($ value && strtolower ($ value)! == "onwaar") {bằng tiếng Hà Lan ... bạn có thể hiểu tại sao PHP không được xây dựng theo tiêu chuẩn này
Mark Baker

1
"tất cả các chuỗi không trống đánh giá là đúng khi chuyển đổi chúng thành boolean, ngoại trừ" 0 "."
BoltClock

5

Trong PHP chỉ "0"hoặc chuỗi rỗng ép buộc thành false; tất cả các chuỗi không rỗng khác ép buộc thành đúng. Từ hướng dẫn :

Khi chuyển đổi sang boolean, các giá trị sau được xem xét FALSE:

  • chuỗi rỗng và chuỗi "0"

Bạn cần phải viết chức năng riêng của mình để xử lý các chuỗi "true"vs "false". Ở đây, tôi giả sử mọi thứ khác mặc định là sai:

function isBoolean($value) {
   if ($value === "true") {
      return true;
   } else {
      return false;
   }
}

Trên một lưu ý phụ có thể dễ dàng được cô đọng để

function isBoolean($value) {
   return $value === "true";
}

4

Gần đây tôi cần một hàm chuyển đổi boolean "lỏng lẻo" để xử lý các chuỗi như chuỗi bạn đang hỏi (trong số những thứ khác). Tôi tìm thấy một vài cách tiếp cận khác nhau và đưa ra một bộ dữ liệu thử nghiệm lớn để chạy qua chúng . Không có gì khá phù hợp với nhu cầu của tôi nên tôi đã tự viết:

function loosely_cast_to_boolean($value) {
    if(is_array($value) || $value instanceof Countable) {
        return (boolean) count($value);
    } else if(is_string($value) || is_object($value) && method_exists($value, '__toString')) {
        $value = (string) $value;
        // see http://www.php.net/manual/en/filter.filters.validate.php#108218
        // see https://bugs.php.net/bug.php?id=49510
        $filtered = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
        if(!is_null($filtered)) {
            return $filtered;
        } else {
            // "none" gets special treatment to be consistent with ini file behavior.
            // see documentation in php.ini for more information, in part it says: 
            // "An empty string can be denoted by simply not writing anything after 
            // the equal sign, or by using the None keyword".
            if(strtolower($value) === 'none') {
                $value = '';
            }
            return (boolean) $value;
        }
    } else {
        return (boolean) $value;
    }
}

Lưu ý rằng đối với các đối tượng có thể đếm được và có thể truyền chuỗi, điều này sẽ ưu tiên đếm trên giá trị chuỗi để xác định tính trung thực. Đó là, nếu $object instanceof Countableđiều này sẽ trở lại (boolean) count($object)bất kể giá trị của (string) $object.

Bạn có thể thấy hành vi cho dữ liệu thử nghiệm tôi đã sử dụng cũng như kết quả cho một số chức năng khác tại đây . Thật khó để lướt qua các kết quả từ iframe nhỏ đó, vì vậy bạn có thể xem đầu ra tập lệnh trong một trang đầy đủ (thay vào đó URL đó không có giấy tờ để điều này có thể không hoạt động mãi mãi). Trong trường hợp các liên kết đó chết một ngày nào đó, tôi cũng đặt mã lên pastebin .

Ranh giới giữa những gì "nên là đúng" và những gì không nên là khá độc đoán; dữ liệu tôi sử dụng được phân loại dựa trên nhu cầu và sở thích thẩm mỹ của tôi, dữ liệu của bạn có thể khác nhau.


Chức năng này hoạt động hoàn hảo, cảm ơn bạn! Nhưng các liên kết của bạn hiện là 404.
servermanfail

3

Tôi đang sử dụng cấu trúc này để biến các chuỗi thành booleans, vì bạn muốn truecho hầu hết các giá trị khác:

$str = "true";
$bool = !in_array($str, array("false", "", "0", "no", "off"));

1

Có một hàm nào trong PHP để phân tích các chuỗi "true" và "false" thành boolean không?

Không - cả hai đều là chuỗi và cả hai (như bạn nói) đều đánh giá true. Chỉ các chuỗi rỗng đánh giá falsetrong PHP.

Bạn sẽ cần phải kiểm tra điều này bằng tay. Tuy nhiên, nếu có thể, tốt hơn là làm việc với các giá trị boolean "thực" thay thế.


1
Không phải tất cả các chuỗi đánh giá truetrong PHP.
coreyward

1
Không sửa, chỉ cần làm rõ. Nói "cả hai đều là chuỗi [và đánh giá thành true]" có thể khiến người mới có ấn tượng sai, đặc biệt là từ một ngôn ngữ khác có quy tắc gõ nghiêm ngặt hơn trong đó chuỗi là một chuỗi và nội dung không quan trọng khi nó được chuyển đổi thành boolean (như Hồng ngọc).
coreyward

1
"Chỉ các chuỗi rỗng đánh giá thành sai trong PHP." Nhưng những gì về chuỗi không trống "0"? Điều này cũng không đánh giá false?
Sepster 27/8/2015

0

Cách dễ nhất để chuyển đổi một cách an toàn sang boolean;

    $flag = 'true';

    if( filter_var( $flag,FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ) !== null) {
      $flag = filter_var($flag,FILTER_VALIDATE_BOOLEAN);
    }

    gettype($flag); // Would Return 'Boolean'
    echo 'Val: '.$flag; // Would Output 'Val: 1'

0

Nếu API của bạn chỉ chấp nhận chuỗi "đúng" hoặc "sai", với mọi thứ khác sẽ trở thànhnull , hãy thử:

$boolean = ['true' => true, 'false' => false][$inputString] ?? null;

Điều này giả định rằng đó $inputkhông phải là một đối tượng. Null coalesce ( ??) đã được giới thiệu trong PHP 7.0.

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.