PHPでオブジェクトが空であることを確認する方法は?


104

PHPでオブジェクトが空かどうかを確認する方法。

以下は、$objXMLデータを保持しているコードです。空かどうかを確認するにはどうすればよいですか?

私のコード:

$obj = simplexml_load_file($url);


回答:


130

配列にキャストして、それが空かどうかを確認できます

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

9
次のエラーが発生するため、型キャストは機能しません 。PHP解析エラー:構文エラー、予期しない '(配列)'(配列)(T_ARRAY_CAST)...で PHPバージョン5.4.28と最初のオプションを使用します2行のコードでうまくいきます。
コアンダ

WordPressプラグインをアップロードするときに同じエラーが発生したため、古いバージョンのPHPも使用しているようです。
Asaf 2015年

4
配列は、空の場合、空は実際にチェックしませんempty($var)と等価(!isset($var) || !$var)。あなたempty($arr)のsは!$arrそれ以降に置き換えることができますarray() == FALSE
Timothy Zorn '20

2
empty((array) $obj)PHP 5.4以降で機能しない理由は、1行の型キャストとは関係ありません。empty()渡された変数への参照を取得するためエラーが発生します。型キャストされた変数を別の変数に最初に格納しない限り、型キャスト時に参照を取得できません。これは、以前のコメントで説明したことが原因です。empty()配列が「空」であるかどうかを確認することを人々に信じさせる可能性があるので、これが受け入れられた答えであることにかなり苛立たしいですが、これは真実ではありません。
ティモシーゾーン

それはphp 7+で動作しますか、それともそれを修正する正しい方法ですか?
kantsverma 2018年

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が1レベルの深さであり、空の場合、実際には、PHPがfalseと見なす(またはプロパティなし)プロパティのみを持っていることを意味します。

$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でも機能すると思います。
ティモシーゾーン

21

オブジェクトを配列にキャストし、その数を次のようにテストできます。

if(count((array)$obj)) {
   // doStuff
}

12

オブジェクトが空ではなく、ある意味で非常に大きい場合、なぜそれを配列にキャストまたはシリアル化するためにリソースを無駄にするのでしょうか。

これは私がJavaScriptで使用する非常に簡単なソリューションです。オブジェクトを配列にキャストして空かどうかをチェックする、またはJSONにエンコードする前述のソリューションとは異なり、この単純な関数は、単純なタスクを実行するために使用されるリソースに関して非常に効率的です。

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

    return TRUE;
}

ソリューションは非常に単純な方法で機能します。オブジェクトが空の場合はforeachループに入ることがなく、が返されtrueます。空でない場合、foreachループに入り、falseセット全体を通過せずに、すぐに戻ります。


8

使用してempty()いるため、オブジェクトにそれを使用するときにいつものように動作しません__isset()宣言した場合のオーバーロードメソッドは、代わりに呼び出されます。

したがって、使用できますcount()(オブジェクトがCountableの場合)。

または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のcount()は最初に配列にキャストしますが、キャストすると空の配列が生成される可能性があります。これは、オブジェクトの実装方法によって異なります(拡張機能のオブジェクトは、多くの場合、これらの問題の影響を受けます)

あなたのケースでは$ obj-> count();を使用する必要があります。

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

(それはphpの数ではありませんhttp://www.php.net/count


1

PHPで何かを(ブール値)としてキャストすると、アイテムがオブジェクト、プリミティブ型、またはnullのいずれであるかがすぐにわかります。次のコードを使用します。

$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 = new \ stdClass(); var_dump((bool)$ x); 「true」を出力します。あなたのケースでは、simpleXmlがfalseを返す場合があります
Quamis

正しい。新しいstdClass()は有効なオブジェクトです。そのため、これがtrueになっています。PHPマニュアルによると、simplexml_load_file()は、「XMLドキュメント内に保持されているデータを含むプロパティを持つSimpleXMLElementクラスのオブジェクトを返します。失敗した場合はFALSEを返します。」したがって、(bool)simplexml_load_file()をキャストすると、(関数がオブジェクトを返したため)trueになりますが、(関数がfalseを返したため)falseになります。
ルーズベルト2015年

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ørgenR 2015

-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.