web-dev-qa-db-fra.com

Vérification des tableaux vides: count vs empty

Cette question sur ' Comment savoir si un tableau PHP est vide ' m'a fait penser à cette question

Existe-t-il une raison pour que count soit utilisé à la place de empty lors de la détermination si un tableau est vide ou non?

Ma pensée personnelle serait que si les 2 sont équivalents pour le cas de tableaux vides, vous devriez utiliser empty car cela donne une réponse booléenne à une question booléenne. De la question liée ci-dessus, il semble que count($var) == 0 est la méthode populaire. Pour moi, bien que techniquement correct, cela n’a aucun sens. Par exemple. Q: $ var, êtes-vous vide? A: 7. Hmmm ...

Y a-t-il une raison pour laquelle je devrais utiliser count == 0 à la place ou juste pour des raisons de goût personnel?

Comme d'autres l'ont souligné dans les commentaires d'une réponse maintenant supprimée, count aura des répercussions sur les performances des tableaux de grande taille car il devra compter tous les éléments, alors que empty peut s'arrêter dès qu'il sait qu'il n'est pas vide. Donc, s’ils donnent les mêmes résultats dans ce cas, mais que count est potentiellement inefficace, pourquoi utiliserions-nous jamais count($var) == 0?

88
Dan McGrath

J'utilise généralement empty. Je ne suis pas sûr de savoir pourquoi les gens utiliseraient vraiment le compte - Si le tableau est grand, le compte prend plus de temps/a plus de temps système. Si vous avez simplement besoin de savoir si le tableau est vide ou non, utilisez vide.

87
prodigitalson

J'étais curieux de voir laquelle était réellement plus rapide, j'ai donc créé un script simple pour comparer ces fonctions.

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

Depuis que je le faisais, j'ai également essayé de vérifier les performances en effectuant des opérations normalement associées à count ()/empty ()

Avec 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

Utilisation de 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

Conclusions si vous utilisez PHP:

  1. empty () est beaucoup plus rapide que count () dans les deux scénarios, avec un tableau vide et rempli

  2. count () effectue la même chose avec un tableau complet ou vide.

  3. Faire un simple IF ou juste une opération booléenne est la même chose.

  4. IF/ELSE est très légèrement plus efficace que (?:). À moins que vous ne fassiez des milliards d'itérations avec des expressions au milieu, cela est complètement insignifiant.

Conclusions si vous utilisez HHVM:

  1. empty () est un tout petit peu plus rapide que count () mais de manière insignifiante.

    [Le reste est le même que dans PHP]

En conclusion de la conclusion, si vous avez juste besoin de savoir si le tableau est vide, utilisez toujours empty ();

C'était juste un test curieux simplement fait sans tenir compte de beaucoup de choses. Ce n'est qu'une preuve de concept et peut ne pas refléter les opérations en production.

39
Satake

Je pense que ce n'est que la préférence personnelle. Certaines personnes pourraient dire que empty est plus rapide (par exemple http://jamessocol.com/projects/count_vs_empty.php ), tandis que d'autres pourraient dire que count est préférable, car il a été créé à l'origine pour les tableaux. empty est plus général et peut être appliqué à d'autres types.

php.net donne l'avertissement suivant pour count cependant:

count () peut renvoyer 0 pour une variable non définie, mais également 0 pour une variable initialisée avec un tableau vide. Utilisez isset () pour vérifier si une variable est définie.

En d'autres termes, si la variable n'est pas définie, vous recevrez une notification de PHP indiquant qu'elle n'est pas définie. Par conséquent, avant d'utiliser count, il serait préférable de vérifier la variable avec isset. Ce n'est pas nécessaire avec empty.

15

Y a-t-il une raison pour laquelle count devrait être utilisé au lieu de vide pour déterminer si un tableau est vide ou non?

Il y a des cas où vous devez faire quelque chose sur un tableau non vide en sachant que sa taille est:

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

Mais je ne recommanderais pas d'utiliser count, à moins que vous ne soyez sûr à 100%, que ce que vous comptez est un tableau. Dernièrement, je déboguais du code, où, en cas d'erreur, la fonction retournait FALSE au lieu d'un tableau vide, et ce que j'ai découvert était

var_dump(count(FALSE));

sortie:

int 1

Donc, depuis lors, j'utilise empty ou if(array() === $array) pour m'assurer que j'ai array qui est vide.

10
dev-null-dweller

Vous pouvez également convertir la variable en booléen (implicitement ou explicitement):

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

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

Cette méthode génère un E_NOTICE si la variable n'est pas définie, de la même manière que count().

Pour plus d'informations, voir la page de manuel PHP sur les comparaisons de types .

5
user212218

count() semble mieux fonctionner avec les interfaces de type tableau qui implémentent ArrayAccess/Countable. empty() renvoie true pour ces types d'objets même s'ils ne contiennent aucun élément. Généralement, ces classes implémenteront l'interface Countable. Par conséquent, si la question est "Cette collection contient-elle des éléments?" sans supposer la mise en oeuvre, alors count() est une meilleure option.

5
Ryan

Ma préférence personnelle est davantage pour l’élégance du codage (par rapport à mon cas d’utilisation spécifique). Je suis d'accord avec Dan McG en ce sens que count () ne répond pas avec le type de données correct (dans ce cas, boolean) pour le test en question, ce qui oblige le développeur à écrire davantage de code pour remplir une instruction 'if'.

La question de savoir si cela a un impact significatif sur les performances ne peut être discutée que pour les baies extrêmement volumineuses (pour lesquelles, de toute façon, la mémoire allouée ne sera probablement pas suffisante dans la plupart des configurations).

En particulier en ce qui concerne le tableau $ _POST de PHP, il semble beaucoup plus "logique" à mon avis d'écrire/voir:

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

J'espère que cela pourra aider quelqu'un même s'il a déjà reçu une réponse (et débattu de quoi). Dans mon propre scénario, je sais que tous mes tableaux contiennent 7 éléments (des vérifications ont été effectuées précédemment dans mon code) et j'effectue un array_diff qui renvoie bien sûr un tableau égal à zéro.

J'ai eu 34 secondes pour count et 17 secondes pour empty. Les deux me donnent les mêmes calculs pour que mon code soit toujours correct.

Cependant, vous pouvez aussi essayer le == ou le === comme dans PHP - Vérifiez si deux tableaux sont égaux . Le meilleur que je dirais est d'essayer count vs empty vs == empty array, puis voir ce qui donne vos meilleurs perfs. Dans mon cas, count était la plus lente, donc j'utilise empty maintenant ... vérifiera serialize suivant

3
xchiltonx

Parfois, utiliser vide est un must. Par exemple ce code:

$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);

Si vous exécutez ce code comme ceci: http://phpfiddle.org/main/code/g9x-uwi

Vous obtenez cette sortie:

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

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

Donc, si vous count la sortie glob vide, vous obtenez une sortie erronée. Vous devriez vérifier le vide.

De glob documentation:

Retourne un tableau contenant les fichiers/répertoires correspondants, un .__ vide. array si aucun fichier ne correspond ou FALSE si une erreur survient.
Remarque: sur certains systèmes, il est impossible de faire la distinction entre une correspondance vide et une erreur.

Cochez également cette question: Pourquoi compter (faux) renvoyer 1?

1
trante

Il n’existe aucune raison valable de préférer count($myArray) == 0 à empty($myArray). Ils ont une sémantique identique. Certains pourraient trouver l'un plus lisible que l'autre. L’un peut légèrement mieux fonctionner que l’autre, mais il n’est pas susceptible d’être un facteur important dans la grande majorité des applications php. À toutes fins utiles, le choix est une question de goût.

1
Asaph

Puisqu’une variable analysée comme négative renverrait int(1) avec count()

Je préfère ($array === [] || !$array) pour tester un tableau vide.

Oui, nous devrions nous attendre à un tableau vide, mais nous ne devrions pas nous attendre à une bonne implémentation de fonctions sans types de retour forcés.

Exemples avec count()

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

J'ai refait mon esprit les gars, merci.

Ok, il n'y a pas de différence entre l'utilisation de empty et count. Techniquement, count devrait être utilisé pour les tableaux, et empty pourrait être utilisé pour les tableaux ainsi que les chaînes. Donc dans la plupart des cas, ils sont interchangeables et si vous voyez les documents php, vous verrez la liste de suggestions de count si vous êtes à empty et vice versa.

0
Sarfraz