PHP Array, Are Array Indexes Case Sensitive

PHP array, Are array indexes case sensitive?

Yes. They are case sensitive.

PHP array indexes act as hash tables in your example. A capital letter "A" and a lowercase letter "a" have different hash values, therefore they will be different indexes.

Why are php array keys case sensitive?

PHP arrays are implemented with hash tables. The way a hash table works, to first order: it hashes the input and uses that as an index to find the right memory location to insert an object.

Now imagine your arrays are case-insensitive. Rather than doing a single hash lookup, you now have to do 2^(length of your string) hash lookups. Furthermore, of these locations, which one do you choose? Suddenly your elegant, simple hash table has become much more complicated, both computationally and in its implementation.

Furthermore, in most other languages, Key and key are treated differently. PHP certainly doesn't always adhere to the principle of least surprise, but in this case it does -- and that's how it should be.

As other users have pointed out, this behavior is easy to obtain if you desire it: simply convert your keys to lowercase before inserting and/or referencing them.

php: Array keys case *insensitive* lookup?

Option 1 - change the way you create the array

You can't do this without either a linear search or altering the original array. The most efficient approach will be to use strtolower on keys when you insert AND when you lookup values.

 $myArray[strtolower('SOmeKeyNAme')]=7;

if (isset($myArray[strtolower('SomekeyName')]))
{

}

If it's important to you to preserve the original case of the key, you could store it as a additional value for that key, e.g.

$myArray[strtolower('SOmeKeyNAme')]=array('SOmeKeyNAme', 7);

Option 2 - create a secondary mapping

As you updated the question to suggest this wouldn't be possible for you, how about you create an array providing a mapping between lowercased and case-sensitive versions?

$keys=array_keys($myArray);
$map=array();
foreach($keys as $key)
{
$map[strtolower($key)]=$key;
}

Now you can use this to obtain the case-sensitive key from a lowercased one

$test='somekeyname';
if (isset($map[$test]))
{
$value=$myArray[$map[$test]];
}

This avoids the need to create a full copy of the array with a lower-cased key, which is really the only other way to go about this.

Option 3 - Create a copy of the array

If making a full copy of the array isn't a concern, then you can use array_change_key_case to create a copy with lower cased keys.

$myCopy=array_change_key_case($myArray, CASE_LOWER);

Check if array key exists, case insensitive

You can use array_change_key_case() to convert all cases to lower, and check on the lowercase key in array_key_exists(). array_change_key_case() changes all keys to lowercase by default (but you can also change them to uppercase, by supplying the CASE_UPPER to the second argument - CASE_LOWER is default).

This of course means that the key you're looking for, must be lowercase when you're passing it to the first argument of array_key_exists(). You pass a variable through, you can use strtolower() to ensure that it is.

$headers = array(
'User-Agent' => 'Mozilla',
);
$headers = array_change_key_case($headers); // Convert all keys to lower
$keyExists = array_key_exists('user-agent', $headers);
var_dump($keyExists);

It's worth noting that if you have multiple keys that become the same when they are lowercased (e.g. if you have Foo and foo as keys in the original array), only the last value in the array would remain. As it reads in the manual: "If an array has indices that will be the same once run through this function (e.g. "keY" and "kEY"), the value that is later in the array will override other indices."

  • Live demo
  • PHP.net on array_change_key_case()

PHP access value using case insensitive index

That is just not the way strings / array work, in PHP.

In PHP, "a" and "A" are two different strings.

Array keys are either integers or strings.

So, $a["a"] and $a["A"] point to two distinct entries in the array.


You have two possible solutions :

  • Either always using lower-case (or upper-case) keys -- which is probably the best solution.
  • Or search through all the array for a possible matching key, each time you want to access an entry -- which is a bad solution, as you'll have to loop over (in average) half the array, instead of doing a fast access by key.


In the first case, you'll have to use strtolower() each time you want to access an array-item :

$array[strtolower('KEY')] = 153;
echo $array[strtolower('KEY')];

In the second case, mabe something like this might work :

(Well, this is a not-tested idea ; but it might serve you as a basis)

if (isset($array['key'])) {
// use the value -- found by key-access (fast)
}
else {
// search for the key -- looping over the array (slow)
foreach ($array as $upperKey => $value) {
if (strtolower($upperKey) == 'key') {
// You've found the correct key
// => use the value
}
}
}

But, again it is a bad solution !

Make array keys insensitive in php

You can extend ArrayObject from the SPL.
This way at least you only have to "touch" the functions/methods that get the data from the database.

$row = getRow();
echo $row['userId'];

function getRow() {
$row = array ( 'USERID' => 4, 'FOO'=>123, 'BAR'=>456 );
return new UCArrayObject($row);
}

class UCArrayObject extends ArrayObject
{
public function offsetExists ($index) { return parent::offsetExists(strtoupper($index)); }
public function offsetGet($index) { return parent::offsetGet(strtoupper($index)); }
public function offsetSet ($index, $newval) { parent::offsetSet(strtoupper($index), $newval); }
public function offsetUnset ($index) { parent::offsetUnset(strtoupper($index)); }
}

How to ignore case sensitivity and count array values?

I would use array_map but as an alternate, join into a string, change case, split into an array:

print_r(array_count_values(str_split(strtolower(implode($arr)))));


Related Topics



Leave a reply



Submit