การแยกสตริงเป็นค่าบูลีนใน PHP


126

วันนี้ฉันเล่นกับ PHP และฉันพบว่าค่าสตริง "จริง" และ "เท็จ" ไม่ได้ถูกแยกวิเคราะห์เป็นบูลีนในเงื่อนไขอย่างถูกต้องตัวอย่างเช่นเมื่อพิจารณาถึงฟังก์ชันต่อไปนี้:

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

ถ้าฉันดำเนินการ:

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

ดูเหมือนว่าจะใช้ได้กับค่า "1" และ "0" เท่านั้น:

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

มีฟังก์ชันเนทีฟใน PHP เพื่อแยกวิเคราะห์สตริง "จริง" และ "เท็จ" เป็นบูลีนหรือไม่?


ในโค้ดของคุณisBoolean("")ควรส่งคืนเท็จ
BoltClock

คุณควรพิจารณาเปลี่ยนคำตอบที่ยอมรับเป็นคำตอบของ Eric Caron จะแสดงฟังก์ชันดั้งเดิมที่ทำในสิ่งที่คุณถาม
Code Commander

1
PHP ไม่ได้คิดถึงสิ่งที่สตริงพูดว่า "false" เป็นเพียงอักขระห้าตัวที่ไม่มีความหมาย พวกเขามีบางสิ่งบางอย่างแม้ว่าดังนั้นประเมินค่าบูลีนไปแม้ว่าผู้อ่านของมนุษย์ก็จะดูเหมือนง่ายขึ้นว่ามันหมายถึงtrue FALSE
zeel

คำตอบ:


414

มีวิธี PHP ดั้งเดิมในการทำสิ่งนี้ซึ่งใช้เมธอด filter_var ของ PHP:

$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN);

ตามคู่มือของ PHP :

ส่งคืนค่า TRUE สำหรับ "1", "true", "on" และ "yes" ส่งกลับค่า FALSE เป็นอย่างอื่น

หากตั้งค่า FILTER_NULL_ON_FAILURE ไว้ FALSE จะถูกส่งกลับสำหรับ "0", "false", "off", "no" และ "" เท่านั้นและจะส่งคืนค่า NULL สำหรับค่าที่ไม่ใช่บูลีนทั้งหมด


นี่น่าจะเป็นคำตอบที่ได้รับการยอมรับ ฟังก์ชั่น PHP ในตัวดีกว่าสร้างเอง ไม่จำเป็นต้องสร้างล้อใหม่! เสียดายที่มันสายไป: P
casraf

1
มันตัวพิมพ์เล็กค่าสำหรับการเปรียบเทียบด้วยหรือไม่?
Mobiletainment

3
@Mobiletainment ใช่ - มันจัดการปลอกใด ๆ ที่คุณสามารถจินตนาการได้ในราคา $ (เท็จเท็จเท็จ ฯลฯ )
Eric Caron

Borked testcase ในตอนท้ายของฉัน ใช้ == แทน === เพื่อเปรียบเทียบ จะลบความคิดเห็นก่อนหน้านี้ของฉันเพื่อไม่ให้ผู้คนสับสน
andig

6
คำตอบทำให้ฉันไม่ทันระวังเพราะคุณต้องเพิ่มแฟล็กFILTER_NULL_ON_FAILUREลงในfilter_var()ฟังก์ชันและไม่แทนที่ด้วยFILTER_VALIDATE_BOOLEANอย่างที่ฉันคิด สิ่งนี้จะส่งผลให้รหัสต่อไปนี้เป็นเคล็ดลับสำหรับฉัน:$bool = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)
Dragon54

14

เหตุผลก็คือสตริงทั้งหมดจะประเมินtrueเมื่อแปลงเป็นบูลีนยกเว้น"0"และ""(สตริงว่าง)

ฟังก์ชั่นต่อไปนี้จะทำสิ่งที่คุณต้องการ: มันทำงานเหมือนกับ PHP แต่จะประเมินสตริง"false"เป็นfalse:

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

เอกสารอธิบายว่า: http://php.net/manual/en/language.types.boolean.php :

เมื่อแปลงเป็นบูลีนค่าต่อไปนี้ถือเป็น FALSE:

  • บูลีน FALSE เอง
  • จำนวนเต็ม 0 (ศูนย์)
  • ลอย 0.0 (ศูนย์)
  • สตริงว่างและสตริง "0"
  • อาร์เรย์ที่มีองค์ประกอบเป็นศูนย์
  • ประเภทพิเศษ NULL (รวมถึงตัวแปรที่ไม่ได้ตั้งค่า)
  • วัตถุ SimpleXML ที่สร้างจากแท็กว่าง

ค่าอื่น ๆ ถือว่าเป็น TRUE (รวมถึงทรัพยากรใด ๆ )


2
+1 ดี (สามารถโยน strtolower ไว้ที่นั่นได้ แต่มันเกี่ยวกับเรื่องนี้)
John Parker

ฉันคิดว่า middaparka หมายถึงการเปรียบเทียบ strtolower ($ value) กับ 'false' การส่ง 'เท็จ' ตามตัวอักษรไปยัง strtolower เป็นเพียงเล็กน้อย .... บ้า? :)
Paul Dixon

@ Paul Dixon Yup นั่นคือสิ่งที่ฉันอ้างถึง :-)
John Parker

2
@Marco - if ($ value && strtolower ($ value)! == "faux") {if you're working in French; if ($ value && strtolower ($ value)! == "falsch") {ในภาษาเยอรมัน; if ($ value && strtolower ($ value)! == "onwaar") {ในภาษาดัตช์ ... คุณสามารถเข้าใจได้ว่าเหตุใด PHP จึงไม่มีสิ่งนี้ในตัวเป็นมาตรฐาน
Mark Baker

1
" สตริงที่ไม่ว่างเปล่าทั้งหมดจะประเมินค่าเป็นจริงเมื่อแปลงเป็นบูลีนยกเว้น" 0 "
BoltClock

5

ใน PHP เท่านั้น"0"หรือสตริงว่างบังคับให้เป็นเท็จ สตริงอื่น ๆ ที่ไม่ว่างเปล่าบังคับให้เป็นจริง จากคู่มือ :

เมื่อแปลงเป็นบูลีนจะพิจารณาค่าต่อไปนี้FALSE:

  • สตริงว่างและสตริง "0"

คุณต้องเขียนฟังก์ชั่นของคุณเองที่จะจัดการกับสตริงVS"true" "false"ที่นี่ฉันถือว่าทุกอย่างเริ่มต้นเป็นเท็จ:

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

หมายเหตุด้านข้างที่สามารถย่อได้ง่าย

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

4

เมื่อเร็ว ๆ นี้ฉันต้องการฟังก์ชันการแปลงบูลีนแบบ "หลวม" เพื่อจัดการกับสตริงเช่นเดียวกับที่คุณกำลังถามถึง (เหนือสิ่งอื่นใด) ฉันพบวิธีการที่แตกต่างกันสองสามวิธีและได้รับข้อมูลการทดสอบจำนวนมากเพื่อดำเนินการเหล่านั้น ไม่มีอะไรที่ตรงกับความต้องการของฉันดังนั้นฉันจึงเขียนของตัวเอง:

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

โปรดทราบว่าสำหรับอ็อบเจ็กต์ที่มีทั้งแบบนับได้และแบบสตริงคาสต์ได้สิ่งนี้จะให้ความสำคัญกับการนับค่าสตริงเพื่อกำหนดความจริง นั่นคือถ้า$object instanceof Countableสิ่งนี้จะส่งกลับ(boolean) count($object)โดยไม่คำนึงถึงค่าของ(string) $object.

ท่านสามารถเข้าดูพฤติกรรมสำหรับข้อมูลการทดสอบผมใช้เช่นเดียวกับผลสำหรับฟังก์ชั่นอื่น ๆ อีกหลายที่นี่ เป็นการยากที่จะดูผลลัพธ์จาก iframe เล็กน้อยดังนั้นคุณจึงสามารถดูผลลัพธ์ของสคริปต์ในแบบเต็มหน้าแทนได้ (URL นั้นไม่มีเอกสารดังนั้นจึงอาจใช้ไม่ได้ตลอดไป) ในกรณีที่ลิงก์เหล่านั้นหายไปในบางวันฉันก็ใส่รหัสบน pastebinเช่นกัน

เส้นแบ่งระหว่างสิ่งที่ "ควรจะเป็นจริง" และสิ่งที่ไม่ควรเป็นไปตามอำเภอใจ ข้อมูลที่ฉันใช้ถูกจัดหมวดหมู่ตามความต้องการและความชอบด้านความงามของฉันข้อมูลของคุณอาจแตกต่างกัน


ฟังก์ชั่นนี้ทำงานได้อย่างไม่มีที่ติขอบคุณ! แต่ตอนนี้ลิงก์ของคุณเป็น 404 แล้ว
servermanfail

3

ฉันใช้โครงสร้างนี้เพื่อแปลงสตริงเป็นบูลีนเนื่องจากคุณต้องการtrueค่าอื่น ๆ ส่วนใหญ่:

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

1

มีฟังก์ชันใน PHP เพื่อแยกวิเคราะห์สตริง "จริง" และ "เท็จ" เป็นบูลีนหรือไม่?

ไม่มี - ทั้งสตริงและที่ทั้งสอง (ตามที่คุณกล่าวว่า) trueประเมิน เฉพาะสตริงว่างเท่านั้นที่ประเมินเป็นfalsePHP

คุณจะต้องทดสอบด้วยตนเอง แต่ถ้าเป็นไปได้ก็ควรใช้ค่าบูลีน "จริง" แทน


1
ไม่ใช่ทุกสตริงที่ประเมินเป็นtruePHP
coreyward

1
ไม่ได้รับการแก้ไขเพียงแค่ชี้แจง การพูดว่า "ทั้งสองเป็นสตริง [และประเมินเป็นtrue]" อาจทำให้มือใหม่รู้สึกผิดโดยเฉพาะอย่างยิ่งจากภาษาอื่นที่มีกฎการพิมพ์ที่เข้มงวดกว่าโดยที่สตริงเป็นสตริงและเนื้อหาไม่สำคัญเมื่อถูกแปลงเป็นบูลีน (เช่น ทับทิม).
coreyward

1
"เฉพาะสตริงว่างเท่านั้นที่ประเมินเป็นเท็จใน PHP" แต่สตริงที่"0"ไม่ว่างเปล่าล่ะ? นี่ยังไม่ประเมินถึงfalse?
58

0

วิธีที่ง่ายที่สุดในการแปลงเป็นบูลีนอย่างปลอดภัย

    $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

หาก API ของคุณยอมรับเฉพาะสตริง "true" หรือ "false" โดยให้ทุกอย่างกลายเป็นอื่นnullให้ลอง:

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

สิ่งนี้ถือว่า$inputไม่ใช่วัตถุ Null coalesce ( ??) ถูกนำมาใช้ใน PHP 7.0

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.