วิธีตรวจสอบว่าวัตถุว่างเปล่าใน PHP?


105

วิธีค้นหาว่าวัตถุว่างเปล่าหรือไม่ใน PHP

ต่อไปนี้เป็นรหัสที่$objเก็บข้อมูล XML ฉันจะตรวจสอบได้อย่างไรว่าว่างหรือไม่?

รหัสของฉัน:

$obj = simplexml_load_file($url);

อาจทำซ้ำได้ของวัตถุ PHP ที่มีข้อมูล XML
Pekka

คำตอบ:


130

คุณสามารถส่งไปยังอาร์เรย์แล้วตรวจสอบว่าว่างหรือไม่

$arr = (array)$obj;
if (!$arr) {
    // do stuff
}

9
การพิมพ์ไม่ได้ผลสำหรับฉันเพราะฉันได้รับข้อผิดพลาด: ข้อผิดพลาดในการแยกวิเคราะห์ PHP : ข้อผิดพลาดทางไวยากรณ์ '(อาร์เรย์)' ที่ไม่คาดคิด (อาร์เรย์) (T_ARRAY_CAST) ใน ... ฉันใช้ PHP เวอร์ชัน 5.4.28 และตัวเลือกแรกกับ รหัสสองบรรทัดใช้ได้กับฉัน
Coanda

มีข้อผิดพลาดเดียวกันเมื่ออัปโหลดปลั๊กอิน WordPress ดูเหมือนว่าพวกเขาจะใช้ PHP เวอร์ชันเก่ากว่าด้วย
Asaf

4
ว่างไม่จริงตรวจสอบว่าอาร์เรย์ว่างเปล่าเทียบเท่าempty($var) (!isset($var) || !$var)คุณสามารถแทนที่empty($arr)s ของคุณได้!$arrตั้งแต่array() == FALSE
Timothy Zorn

2
เหตุผลที่ใช้empty((array) $obj)ไม่ได้ใน PHP 5.4+ ไม่เกี่ยวข้องกับการพิมพ์ดีดในบรรทัดเดียว คุณได้รับข้อผิดพลาดเนื่องจากempty()ใช้การอ้างอิงไปยังตัวแปรที่ส่งผ่านไปและไม่สามารถรับการอ้างอิงเมื่อพิมพ์ดีดได้เว้นแต่คุณจะเก็บตัวแปรประเภทที่พิมพ์ไว้ในตัวแปรอื่นก่อน เป็นเพราะสิ่งที่ฉันอธิบายไว้ในความคิดเห็นก่อนหน้านี้ ค่อนข้างน่าผิดหวังที่นี่เป็นคำตอบที่ได้รับการยอมรับเนื่องจากสามารถทำให้ผู้คนเชื่อว่าการempty()ตรวจสอบว่าอาร์เรย์ "ว่างเปล่า" ซึ่งไม่เป็นความจริงนั่นเป็นเพียงผลข้างเคียงของสิ่งที่ทำจริง
Timothy Zorn

มันจะทำงานใน php 7+ หรือเป็นวิธีที่ถูกต้องในการแก้ไข
kantsverma

32

แก้ไข : ฉันไม่รู้ว่าพวกเขาต้องการตรวจสอบโดยเฉพาะว่าวัตถุ SimpleXMLElement ว่างเปล่าหรือไม่ ฉันทิ้งคำตอบเก่าไว้ด้านล่าง

คำตอบที่อัปเดต (SimpleXMLElement) :

สำหรับ SimpleXMLElement:

ถ้าว่างคุณหมายถึงไม่มีคุณสมบัติ:

$obj = simplexml_load_file($url);
if ( !$obj->count() )
{
    // no properties
}

หรือ

$obj = simplexml_load_file($url);
if ( !(array)$obj )
{
    // empty array
}

หาก SimpleXMLElement อยู่ในระดับลึกหนึ่งระดับและโดยการว่างเปล่าคุณหมายความว่ามีเพียงคุณสมบัติที่PHP พิจารณาว่าเป็นเท็จ (หรือไม่มีคุณสมบัติ):

$obj = simplexml_load_file($url);
if ( !array_filter((array)$obj) )
{
    // all properties falsey or no properties at all
}

หาก SimpleXMLElement มีความลึกมากกว่าหนึ่งระดับคุณสามารถเริ่มต้นด้วยการแปลงเป็นอาร์เรย์บริสุทธิ์:

$obj = simplexml_load_file($url);
// `json_decode(json_encode($obj), TRUE)` can be slow because
// you're converting to and from a JSON string.
// I don't know another simple way to do a deep conversion from object to array
$array = json_decode(json_encode($obj), TRUE);
if ( !array_filter($array) )
{
    // empty or all properties falsey
}


คำตอบเก่า (วัตถุธรรมดา) :

หากคุณต้องการตรวจสอบว่าวัตถุอย่างง่าย (ประเภทstdClass) ว่างเปล่าหรือไม่ (ไม่มีคีย์ / ค่า) คุณสามารถดำเนินการดังต่อไปนี้:

// $obj is type stdClass and we want to check if it's empty
if ( $obj == new stdClass() )
{
    echo "Object is empty"; // JSON: {}
}
else
{
    echo "Object has properties";
}

ที่มา: http://php.net/manual/en/language.oop5.object-comparison.php

แก้ไข : เพิ่มตัวอย่าง

$one = new stdClass();
$two = (object)array();

var_dump($one == new stdClass()); // TRUE
var_dump($two == new stdClass()); // TRUE
var_dump($one == $two); // TRUE

$two->test = TRUE;
var_dump($two == new stdClass()); // FALSE
var_dump($one == $two); // FALSE

$two->test = FALSE;
var_dump($one == $two); // FALSE

$two->test = NULL;
var_dump($one == $two); // FALSE

$two->test = TRUE;
$one->test = TRUE;
var_dump($one == $two); // TRUE

unset($one->test, $two->test);
var_dump($one == $two); // TRUE

ไม่ทำงานใน PHP7.2:PHP Warning: Uncaught Error: Call to undefined method stdClass::count()
Juha Untinen

2
@ juha-untinen การแก้ปัญหาโดย->count()เฉพาะสำหรับอินสแตนซ์ของSimpleXMLElementและไม่ใช่สำหรับอินสแตนซ์ของstdClass. ฉันเชื่อว่าทั้งหมดนี้ยังใช้งานได้ใน PHP7.2
Timothy Zorn


12

ลองนึกดูว่าถ้าวัตถุนั้นไม่ว่างเปล่าและมีขนาดค่อนข้างใหญ่ทำไมคุณจะเสียทรัพยากรเพื่อส่งไปยังอาร์เรย์หรือทำให้เป็นอนุกรม ...

นี่เป็นวิธีแก้ปัญหาที่ง่ายมากที่ฉันใช้ใน JavaScript ซึ่งแตกต่างจากโซลูชันที่กล่าวถึงที่ส่งอ็อบเจ็กต์ไปยังอาร์เรย์และตรวจสอบว่าว่างหรือไม่หรือเข้ารหัสเป็น JSON ฟังก์ชันง่ายๆนี้มีประสิทธิภาพมากสำหรับทรัพยากรที่ใช้เพื่อทำงานง่ายๆ

function emptyObj( $obj ) {
    foreach ( $obj AS $prop ) {
        return FALSE;
    }

    return TRUE;
}

การแก้ปัญหาการทำงานในลักษณะที่ง่ายมาก: มันเป็นนิสัยใส่ห่วง foreach trueที่ทุกคนถ้าวัตถุเป็นที่ว่างเปล่าและมันจะกลับมา หากไม่ว่างเปล่ามันจะเข้าสู่foreachลูปและย้อนกลับfalseทันทีโดยไม่ผ่านทั้งชุด


8

การใช้empty()จะไม่ทำงานตามปกติเมื่อใช้กับวัตถุเนื่องจาก__isset()วิธีการโอเวอร์โหลดจะถูกเรียกใช้แทนหากมีการประกาศ

ดังนั้นคุณสามารถใช้count()(ถ้าวัตถุนั้นนับได้ )

หรือโดยใช้get_object_vars()เช่น

get_object_vars($obj) ? TRUE : FALSE;

7

อีกวิธีหนึ่งที่เป็นไปได้ซึ่งไม่จำเป็นต้องหล่อไปที่array:

// test setup
class X { private $p = 1; } // private fields only => empty
$obj = new X;
// $obj->x = 1;


// test wrapped into a function
function object_empty( $obj ){
  foreach( $obj as $x ) return false;
  return true;
}


// inline test
$object_empty = true;
foreach( $obj as $object_empty ){ // value ignored ... 
  $object_empty = false; // ... because we set it false
  break;
}


// test    
var_dump( $object_empty, object_empty( $obj ) );

2

ไม่มีวิธีพิเศษที่ปลอดภัยในการตรวจสอบว่าวัตถุว่างเปล่าหรือไม่

php's count () ถูกส่งไปยังอาร์เรย์เป็นอันดับแรก แต่การแคสต์สามารถสร้างอาร์เรย์ที่ว่างเปล่าได้ขึ้นอยู่กับวิธีการใช้งานอ็อบเจ็กต์ (อ็อบเจ็กต์ส่วนขยายมักได้รับผลกระทบจากปัญหาเหล่านั้น)

ในกรณีของคุณคุณต้องใช้ $ obj-> count ();

http://it.php.net/manual/th/simplexmlelement.count.php

(นั่นไม่ใช่จำนวน php http://www.php.net/count )


1

หากคุณร่ายอะไรใน PHP เป็น (บูล) มันจะบอกคุณทันทีว่ารายการนั้นเป็นวัตถุประเภทดั้งเดิมหรือค่าว่าง ใช้รหัสต่อไปนี้:

$obj = simplexml_load_file($url);

if (!(bool)$obj) {
    print "This variable is null, 0 or empty";
} else {
    print "Variable is an object or a primitive type!";
}

1
ไม่ถูกต้อง. $ x = ใหม่ \ stdClass (); var_dump ((บูล) $ x); พิมพ์ 'จริง'; ในกรณีของคุณ simpleXml อาจส่งคืนเท็จในบางกรณี
Quamis

แก้ไข. stdClass ใหม่ () เป็นวัตถุที่ถูกต้องนั่นเป็นเหตุผลว่าทำไมจึงเป็นจริง คู่มือ PHP กล่าวว่า simplexml_load_file () "ส่งคืนอ็อบเจ็กต์ของคลาส SimpleXMLElement พร้อมคุณสมบัติที่มีข้อมูลที่เก็บไว้ในเอกสาร XML หรือ FALSE เมื่อเกิดความล้มเหลว" ดังนั้นหากคุณส่ง (bool) simplexml_load_file () มันจะเป็นจริง (เพราะฟังก์ชันส่งคืนวัตถุ) แต่เป็นเท็จ (เนื่องจากฟังก์ชันส่งคืนเป็นเท็จ)
roosevelt

0

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

PHP เองถือว่าทุกอินสแตนซ์ของคลาสไม่ว่างเปล่า

class Test { }
$t = new Test();
var_dump(empty($t));

// results in bool(false)

ไม่มีคำจำกัดความทั่วไปสำหรับอ็อบเจ็กต์ "ว่าง" คุณอาจโต้แย้งในตัวอย่างข้างต้นผลของempty()ควรเป็นtrueเพราะวัตถุไม่ได้แสดงถึงเนื้อหาใด ๆ แต่ PHP จะรู้ได้อย่างไร? วัตถุบางอย่างไม่ได้มีไว้เพื่อแสดงถึงเนื้อหา (เช่นโรงงาน) ส่วนวัตถุอื่น ๆ มักแสดงถึงคุณค่าที่มีความหมาย (คิดว่าnew DateTime())

ในระยะสั้นคุณจะต้องกำหนดเกณฑ์ของคุณเองสำหรับวัตถุเฉพาะและทดสอบตามนั้นไม่ว่าจะจากภายนอกวัตถุหรือจากisEmpty()วิธีการเขียนเองในวัตถุ


0
$array = array_filter($array);
if(!empty($array)) {
    echo "not empty";
}

หรือ

if(count($array) > 0) {
    echo 'Error';
} else {
    echo 'No Error';
}

แม้ว่าสิ่งนี้อาจตอบคำถามได้คุณควรใส่ข้อความในคำตอบของคุณเพื่ออธิบายสิ่งที่คุณกำลังทำอยู่ อ่านวิธีการเขียนคำตอบที่ดี
Jørgen R

-1

ฉันใช้ json_decode ของสตริงในคำขอโพสต์ ข้างต้นไม่ได้ผลสำหรับฉันในที่สุดฉันก็ใช้สิ่งนี้:

$post_vals = json_decode($_POST['stuff']);

if(json_encode($post_vals->object) != '{}')
{
    // its not empty
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.