Comme indiqué par l'OP:
PHP traite tous les tableaux associatifs
il n'est pas tout à fait raisonnable (à mon humble avis) écrire une fonction qui vérifie si un tableau associatif. Donc, la première chose d'abord: qu'est ce qu'une clé dans un tableau PHP?:
La clé peut être un entier ou une chaîne de caractères.
Qui signifie qu'il y a 3 cas possibles:
- Cas 1. toutes les touches sont numériques / les entiers.
- Cas 2. toutes les clés sont des chaînes.
- Cas 3. certaines clés sont des chaînes de caractères, certaines touches sont numériques / les entiers.
Nous pouvons vérifier chaque cas, avec les fonctions suivantes.
Cas 1: toutes les touches sont numériques / les entiers.
Remarque: Cette fonction renvoie vrai pour les tableaux vides.
//! Check whether the input is an array whose keys are all integers.
/*!
\param[in] $InputArray (array) Input array.
\return (bool) \b true iff the input is an array whose keys are all integers.
*/
function IsArrayAllKeyInt($InputArray)
{
if(!is_array($InputArray))
{
return false;
}
if(count($InputArray) <= 0)
{
return true;
}
return array_unique(array_map("is_int", array_keys($InputArray))) === array(true);
}
Cas 2: toutes les clés sont des chaînes de caractères.
Remarque: Cette fonction renvoie vrai pour les tableaux vides.
//! Check whether the input is an array whose keys are all strings.
/*!
\param[in] $InputArray (array) Input array.
\return (bool) \b true iff the input is an array whose keys are all strings.
*/
function IsArrayAllKeyString($InputArray)
{
if(!is_array($InputArray))
{
return false;
}
if(count($InputArray) <= 0)
{
return true;
}
return array_unique(array_map("is_string", array_keys($InputArray))) === array(true);
}
Cas 3. certaines clés sont des chaînes de caractères, certaines touches sont numériques / les entiers.
Remarque: Cette fonction renvoie vrai pour les tableaux vides.
//! Check whether the input is an array with at least one key being an integer and at least one key being a string.
/*!
\param[in] $InputArray (array) Input array.
\return (bool) \b true iff the input is an array with at least one key being an integer and at least one key being a string.
*/
function IsArraySomeKeyIntAndSomeKeyString($InputArray)
{
if(!is_array($InputArray))
{
return false;
}
if(count($InputArray) <= 0)
{
return true;
}
return count(array_unique(array_map("is_string", array_keys($InputArray)))) >= 2;
}
Il s'ensuit que:
Maintenant, pour un tableau à une "véritable" matrice que nous sommes tous habitués à, sens:
- Ses touches sont toutes numériques / les entiers.
- Ses touches sont séquentielle (c'est à dire par l'augmentation de l'étape 1).
- Ses touches de commencer à partir de zéro.
Nous pouvons le vérifier avec la fonction suivante.
Cas 3a. les touches sont numérique / entiers, séquentielle, et de base zéro.
Remarque: Cette fonction renvoie vrai pour les tableaux vides.
//! Check whether the input is an array whose keys are numeric, sequential, and zero-based.
/*!
\param[in] $InputArray (array) Input array.
\return (bool) \b true iff the input is an array whose keys are numeric, sequential, and zero-based.
*/
function IsArrayKeyNumericSequentialZeroBased($InputArray)
{
if(!is_array($InputArray))
{
return false;
}
if(count($InputArray) <= 0)
{
return true;
}
return array_keys($InputArray) === range(0, count($InputArray) - 1);
}
Mises en garde / Pièges (ou, encore plus propre des faits à propos de la matrice de touches en PHP)
Entier clés
Les clés de ces tableaux sont des entiers:
array(0 => "b");
array(13 => "b");
array(-13 => "b"); // Negative integers are also integers.
array(0x1A => "b"); // Hexadecimal notation.
Clés de chaîne
Les clés de ces tableaux sont des chaînes de caractères:
array("fish and chips" => "b");
array("" => "b"); // An empty string is also a string.
array("stackoverflow_email@example.com" => "b"); // Strings may contain non-alphanumeric characters.
array("stack\t\"over\"\r\nflow's cool" => "b"); // Strings may contain special characters.
array('$tα€k↔øv∈rflöw⛄' => "b"); // Strings may contain all kinds of symbols.
array("functіon" => "b"); // You think this look fine? Think again! (see http://stackoverflow.com/q/9246051/1402846)
array("ま말轉转ДŁ" => "b"); // How about Japanese/Korean/Chinese/Russian/Polish?
array("fi\x0sh" => "b"); // Strings may contain null characters.
array(file_get_contents("https://www.google.com.hk/images/nav_logo114.png") => "b"); // Strings may even be binary!
Entier clés qui ressemblent à des cordes
Si vous pensez que la clé en array("13" => "b")
est une chaîne de caractères, vous avez tort. À partir de la doc ici:
Les chaînes contenant un entier valide sera lancé pour le type integer. E. g. la touche "8" seront effectivement stockées sous 8. Sur l'autre main "08" ne soient pas jetés, car elle n'est pas valide d'un nombre décimal.
Par exemple, la clé pour ces tableaux sont des entiers:
array("13" => "b");
array("-13" => "b"); // Negative, ok.
Mais la clé pour ces tableaux sont des chaînes de caractères:
array("13." => "b");
array("+13" => "b"); // Positive, not ok.
array("-013" => "b");
array("0x1A" => "b"); // Not converted to integers even though it's a valid hexadecimal number.
array("013" => "b"); // Not converted to integers even though it's a valid octal number.
array("18446744073709551616" => "b"); // Not converted to integers as it can't fit into a 64-bit integer.
Qui plus est, selon le doc,
La taille d'un entier est dépend de la plateforme, bien que d'une valeur maximale d'environ deux milliards de dollars, c'est l'habituel (valeur 32 bits signés). Plates-formes 64 bits ont généralement une valeur maximale d'environ 9E18. PHP ne supporte pas des entiers non signés.
Donc, la clé pour ce tableau peut ou ne peut pas être un nombre entier , ça dépend de votre plate-forme.
array("60000000000" => "b"); // Array key could be integer or string, it can fit into a 64-bit (but not 32-bit) integer.
Pire encore, PHP tend à être buggy si l'entier est à proximité de la 231 = 2,147,483,648 limite (voir bug 51430, bug 52899). Par exemple, sur mon environnement local (PHP 5.3.8 sur XAMPP 1.7.7 sur Windows 7), var_dump(array("2147483647" => "b"))
donne
array(1) {
[2147483647]=>
string(1) "b"
}
mais sur cette démo en direct sur codepad (PHP 5.2.5, la même expression donne
array(1) {
["2147483647"]=>
string(1) "b"
}
Donc, la clé est un nombre entier dans un environnement, mais une chaîne dans une autre, même si 2147483647
est valable signé de 32 bits entier.