空の配列のチェック:カウントと空


98

PHP配列が空かどうかを確認する方法」に関するこの質問で、この質問について考えていました。

配列が空かどうかを判断するときcountに、代わりに使用すべき理由はありemptyますか?

私の個人的な考えは、2つが空の配列の場合と同等であるかどうかです。空の配列の場合empty、ブールの質問に対してブールの回答が得られるためです。上にリンクされている質問から、それcount($var) == 0が人気のある方法のようです。私には、技術的には正しいが、意味がありません。例Q:$ var、あなたは空ですか?A:7。うーん...

count == 0代わりに、または単に個人的な好みの問題を使用する理由はありますか?

削除された回答に対するコメントで他の人が指摘したように、countすべての要素をカウントする必要があるため、大規模な配列のパフォーマンスに影響を与えますemptyが、空でないことがわかるとすぐに停止できます。したがって、この場合に同じ結果が得られても、count非効率的である可能性がある場合、なぜ使用するのcount($var) == 0でしょうか。


会話を配列に限定することを意図していると思いますが、オブジェクト(Countable、Iteratorなどを実装しているオブジェクト)を操作している場合は、ゲームが完全に変わることに注意してください。

8
空の配列はfalsePHP と同じです- empty()またはは必要ありませんcount()
コビー

@コビーコードしてください。
TheRealChx101 2017

:ただやる、中TheRealChx101として@ if (!$myArray) { echo "array is empty"; } sandbox.onlinephpfunctions.com/code/...を
Cobby

現在、リンクされた質問で人気のあるオプションはを使用していempty()ます。
PhoneixS 2017年

回答:


97

一般的に使用しますempty。なぜ人々が本当にcountを使用するのかわかりません-配列が大きい場合、countは長くかかります/オーバーヘッドが多くなります。単に配列が空であるかどうかを知る必要がある場合は、emptyを使用します。


4
これらの関数は、配列が空でない場合は実際に異なります。
ジャッコ

2
@ジャッコ:私はそれを争っていない。しかし、あなたがそれを空でテストしている場合、私はそれが何の関連性を持っているのか分かりません-関数が返すものであるブール結果の質問です。空と見なされるものについては、テストが配列でない場合を除いて、これらの基準がどのように間違った答えを生成するかは、まったく別の問題です。
prodigitalson、2010

23
@prodigitalson O(1)PHPは要素の数を内部に保存するので、数はと言えます。この回答をチェックしてくださいstackoverflow.com/a/5835419/592454
elitalon

4
@eliton:しかし、それでも-パフォーマンスに違いがないか、ほとんどない場合でも、カウントが必要ないのになぜカウントを使用するのですか?
prodigitalson

4
empty()はエラーを許容しすぎます。スーパークラスのプライベートメンバー変数でempty()をテストするサブクラスのデバッグに2時間費やしただけです(スーパークラスのメンバー変数のスコープは保護されているはずですが、empty()はエラーを返しませんでした。発生した、発生しなかった:サブクラスにメンバー変数が存在しないことは、このメンバー変数である配列が空であるのとまったく同じ方法で処理されました(つまり、要素がないかのように)。これは問題があり、PHPが寛容すぎるもう1つの例です。
マシュー・スライマン2017

46

実際にどちらが速いか知りたくて、それらの関数をベンチマークする簡単なスクリプトを作成しました。

<?php

function benchmark($name, $iterations, $action){
    $time=microtime(true);
    for($i=0;$i<=$iterations;++$i){
        $action();
    }
    echo $name . ' ' . round(microtime(true)-$time, 6) . "\n";
}

$iterations = 1000000;
$x = array();
$y = range(0, 10000000);
$actions = array(
    "Empty empty()" => function() use($x){
        empty($x);
    },
    "Empty count()" => function() use($x){
        count($x);
    },
    "Full empty()" => function() use($y){
        empty($y);
    },
    "Full count()" => function() use($y){
        count($y);
    },
    ############
    "IF empty empty()" => function() use($x){
        if(empty($x)){ $t=1; }
    },
    "IF empty count()" => function() use($x){
        if(count($x)){ $t=1; }
    },
    "IF full empty()" => function() use($y){
        if(empty($y)){ $t=1; }
    },
    "IF full count()" => function() use($y){
        if(count($y)){ $t=1; }
    },
    ############
    "OR empty empty()" => function() use($x){
        empty($x) OR $t=1;
    },
    "OR empty count()" => function() use($x){
        count($x) OR $t=1;
    },
    "OR full empty()" => function() use($y){
        empty($y) OR $t=1;
    },
    "OR full count()" => function() use($y){
        count($y) OR $t=1;
    },
    ############
    "IF/ELSE empty empty()" => function() use($x){
        if(empty($x)){ $t=1; } else { $t=2; }
    },
    "IF/ELSE empty count()" => function() use($x){
        if(count($x)){ $t=1; } else { $t=2; }
    },
    "IF/ELSE full empty()" => function() use($y){
        if(empty($y)){ $t=1; } else { $t=2; }
    },
    "IF/ELSE full count()" => function() use($y){
        if(count($y)){ $t=1; } else { $t=2; }
    },
    ############
    "( ? : ) empty empty()" => function() use($x){
        $t = (empty($x) ? 1 : 2);
    },
    "( ? : ) empty count()" => function() use($x){
        $t = (count($x) ? 1 : 2);
    },
    "( ? : ) full empty()" => function() use($y){
        $t = (empty($y) ? 1 : 2);
    },
    "( ? : ) full count()" => function() use($y){
        $t = (count($y) ? 1 : 2);
    }
);

foreach($actions as $name => $action){
    benchmark($name, $iterations, $action);
}
//END

私はそれをしていたので、通常count()/ empty()に関連付けられている操作を実行するパフォーマンスも確認しようとしました

PHP 5.4.39を使用:

Empty empty() 0.118691
Empty count() 0.218974
Full empty() 0.133747
Full count() 0.216424
IF empty empty() 0.166474
IF empty count() 0.235922
IF full empty() 0.120642
IF full count() 0.248273
OR empty empty() 0.123875
OR empty count() 0.258665
OR full empty() 0.157839
OR full count() 0.224869
IF/ELSE empty empty() 0.167004
IF/ELSE empty count() 0.263351
IF/ELSE full empty() 0.145794
IF/ELSE full count() 0.248425
( ? : ) empty empty() 0.169487
( ? : ) empty count() 0.265701
( ? : ) full empty() 0.149847
( ? : ) full count() 0.252891

HipHop VM 3.6.1(dbg)の使用

Empty empty() 0.210652
Empty count() 0.212123
Full empty() 0.206016
Full count() 0.204722
IF empty empty() 0.227852
IF empty count() 0.219821
IF full empty() 0.220823
IF full count() 0.221397
OR empty empty() 0.218813
OR empty count() 0.220105
OR full empty() 0.229118
OR full count() 0.221787
IF/ELSE empty empty() 0.221499
IF/ELSE empty count() 0.221274
IF/ELSE full empty() 0.221879
IF/ELSE full count() 0.228737
( ? : ) empty empty() 0.224143
( ? : ) empty count() 0.222459
( ? : ) full empty() 0.221606
( ? : ) full count() 0.231288

PHPを使用している場合の結論:

  1. empty()は、両方のシナリオでcount()よりもはるかに高速です。

  2. count()は、完全な配列または空の配列で同じことを実行します。

  3. 単純なIFやブール演算だけでも同じです。

  4. IF / ELSEは(?:)よりもわずかに効率的です。途中で式を使用して数十億回の反復を行わない限り、それはまったく重要ではありません。

HHVMを使用している場合の結論:

  1. empty()はcount()より少し高速ですが、重要ではありません。

    [残りはPHPと同じです]

結論の結論として、配列が空かどうかを知る必要がある場合は、常にempty();を使用します。

これは、多くのことを考慮せずに、単に行われた好奇心旺盛なテストでした。これは単なる概念実証であり、本番環境での運用を反映していない場合があります。


サンプルのテストコードをありがとう...私はそれを使用したところ、それif($x){がより速いことがわかりましたif(empty($x)){$x宣言されていることがわかっている場合にのみ機能します)。
Redzarf

あなたのテストコードは本当に悪いです。匿名関数呼び出しなど、多くの追加要素を追加します。削除して裸のコードを実行するだけの場合(サイクルごとに)、大きな違いが生じます。そして、その場合、ifステートメントにcountand empty呼び出しがない場合、より高速になります。それから来てempty、持続しcountます。しかし、ベアケースの場合と比較すると、空は10倍速くなります。単純な配列テスト:0.104662、空:0.177659、カウント:PHP 5.6では1.175125さもなければ、あなたのコードはあなたが言及したようにこのバージョンでも同じ結果を与えます。ちょうどそれは偽の結果です。
golddragon007

16

個人的な好みだと思います。もともとは配列用に作成されたため、emptyより速いと言う人もいます(例:http : //jamessocol.com/projects/count_vs_empty.phpcountemptyより一般的で、他のタイプに適用できます。

php.netは次の警告を出しcountます:

count()は、設定されていない変数に対して0を返す場合がありますが、空の配列で初期化された変数に対して0を返す場合もあります。isset()を使用して、変数が設定されているかどうかをテストします。

つまり、変数が設定されていない場合、PHPから未定義であるという通知が届きます。したがって、を使用する前にcount、で変数を確認することをお勧めしますisset。これは、では必要ありませんempty


3
おもしろいのは、count元々は配列用に作成されたということCountableですが、オブジェクトはを実装でき、スカラー値を渡しcount()て有効な結果を得ることができます。

1
カウント()設定されていない変数に0を返しますが、それはよいも...。モーダル動詞を使用してその不確実性を表現する公式ドキュメント:p
nawfal 2015年

isset()要点についてのコメント。PHPでの通知について心配している場合は、配列をすでに宣言しているはずです。PHPに動的に配列を宣言させると、その時点でも通知が届きます。php.netの警告の本当のポイントはcount、空の配列と同じ結果が得られるため、配列が宣言されているかどうかを判断するために使用すべきではないということです。
ノアダンカン

12

配列が空かどうかを判断するときに、空ではなくcountを使用する必要がある理由はありますか?

サイズがわかっている空ではない配列で何かをする必要がある場合があります:

if( 0 < ( $cnt = count($array) ) )
{
 echo "Your array size is: $cnt";
}
else
 echo "Too bad, your array is empty :(";

ただし、100%確実でない限り、countを使用することはお勧めしません。最近、コードをデバッグしていますが、エラー時FALSEに空の配列ではなく関数が返されていました。

var_dump(count(FALSE));

出力:

int 1

だから、それ以来、私は使っていemptyたりif(array() === $array)、私が持っていることを確認するために、配列は空です。


6

count()を実装する配列のようなインターフェースでよりよく機能するようArrayAccess/Countableです。empty()これらの種類のオブジェクトは、要素がない場合でもtrueを返します。通常、これらのクラスはCountableインターフェースを実装するため、「このコレクションには要素が含まれていますか?」実装についての仮定をせずにcount()、より良いオプションです。


「これらの種類のオブジェクトは、要素がない場合でもfalseempty返す」という意味ですか?
alexw

はい。クラスが「空」かどうかを定義できるインターフェースはありません。そして、それが存在しても意味がありません。
ライアン

使い方+1 count今までそれがコレクションを受け入れるようにあなたのコードのために理にかなっている場合は、より柔軟で拡張性の解決策になるには、「一般的な」方法を実装し... IMOそれはあなたが使用している場合定義するための唯一の適切な基準であるかもしれないcountか、他の方法...
ClemC

count()7.2 の大きな欠点は、空の変数を取得できないことです。
ライアン

5

または、変数をブール値として(暗黙的または明示的に)キャストできます。

if( $value )
{
  // array is not empty
}

if( (bool) $value )
{
  // array is still not empty
}

このメソッドはE_NOTICE、と同様に、変数が定義されていない場合にを生成しcount()ます。

詳細については、型の比較に関するPHPのマニュアルページを参照してください


1
これはチェックする最良の方法empty()です。E_NOTICEをトリガーすることを明示的に回避しようとしている場合にのみ使用してください(これは一般に悪い考えです、IMO)。空想的に空を使用すると、バグのあるコードにつながります。
コビー

3

私の個人的な好みは、(私の特定のユースケースに関連して)エレガンスをコーディングすることです。問題のテストに対してcount()が正しいデータ型(この場合はブール値)で応答していないため、Dan McGに同意します。

これがパフォーマンスに大きな影響を与えるかどうかは、非常に大規模なアレイでのみ議論の余地があります(おそらく、ほとんどの設定では、十分なメモリ割り当てがありません)。

特にPHPの$ _POST配列に関しては、私の意見では次のように記述/参照する方がはるかに「論理的」に思えます。

if ( !empty ( $_POST ) ) {
    // deal with postdata
}

3

これがすでに回答されている(そして何が議論されている)場合でも、これが誰かの助けになることを願っています。私のシナリオでは、すべての配列にすべて7つの要素があることを確認し(コードの前半でチェックを行いました)、array_diffもちろん等しい場合にゼロの配列を返すを実行しています。

には34秒、countには17秒ありましたempty。どちらも同じ計算を行うので、コードはまだ問題ありません。

ただし、PHPのように、==または2つの配列が等しいかどうかを確認することもできます。私が言う最高のことは、vs vsを試して、それからあなた自身の最高のパフォーマンスを与えることを見てください。私の場合は最も遅かったので私は使ってます... 次にチェックします===countempty== empty arraycountemptyserialize


2

好む強い理由がないcount($myArray) == 0以上はempty($myArray)。それらは同じセマンティクスを持っています。一部の人は、一方が他方より読みやすいと感じるかもしれません。1つは他よりわずかに優れたパフォーマンスを発揮する可能性がありますが、大多数のphpアプリケーションでは重要な要素にはなりません。すべての実用的な目的のために、選択は好みの問題です。


1
「パフォーマンス」についてはどうですか?「実践的な目的」の説明を使用すると、悪い習慣につながります。使用countあなたは、使用を数える必要がemptyあなたは、コレクションが空であるかどうかを確認する必要がある場合。もちろん、文字列やnullのようなエッジケースがありますが、プログラマは自分のコードについて考える必要があります。あなたは反対するかもしれません、あなたは許されています。
Namek

count($ myArray)で、$ myArrayが値FALSEのようなブール値である場合、カウントが機能しないことがあります(php5.3でテスト済み)。
Mimouni 2017年

1

空を使用する必要がある場合があります。たとえば、次のコード:

$myarray = array();

echo "myarray:"; var_dump($myarray); echo "<br>";
echo "case1 count: ".count($myarray)."<br>";
echo "case1 empty: ".empty($myarray)."<br>";

$glob = glob('sdfsdfdsf.txt');

echo "glob:"; var_dump($glob); echo "<br>";
echo "case2 count: ".count($glob)."<br>";
echo "case2 empty: ".empty($glob);

このコードを次のように実行した場合:http : //phpfiddle.org/main/code/g9x-uwi

次の出力が得られます。

myarray:array(0) { } 
case1 count: 0
case1 empty: 1

glob:bool(false) 
case2 count: 1
case2 empty: 1

したがってcount、空のグロブ出力の場合、誤った出力が得られます。空かどうかを確認する必要があります。

グロブのドキュメントから:

一致したファイル/ディレクトリを含む配列を返します。一致するファイルがない場合は空の配列を返し、エラーの場合はFALSEを返します。
注:一部のシステムでは、空の一致とエラーを区別できません。

また、この質問を確認してください: なぜcount(false)は1を返すのですか?


1

負として解析された変数はint(1)count()

($array === [] || !$array)空の配列をテストすることを好みます。

はい、空の配列を期待する必要がありますが、強制的な戻り値の型がない関数の適切な実装を期待するべきではありません。

の例 count()

var_dump(count(0));
> int(1)
var_dump(count(false));
> int(1)

0

私は心の人たちを作り直した、ありがとう。

emptyとの使用法に違いはありませんcount。技術的にcountは、配列に使用する必要がemptyあり、文字列だけでなく配列にも使用できます。そのため、ほとんどの場合、それらは交換可能であり、php docsを参照すると、現在かどうかの提案リストcountが表示されますempty

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.