5

I try to find the right way to check, in a CASE-INSENSITIVE manner, if an array key exists.

I have an array - a list of HTTP headers:

$headers = [
    'User-Agent' => 'Mozilla',
];

Basically, I want to be able to give something like this (with small character 'u'):

$keyExists = array_key_exists('user-Agent', $headers);

and to receive a boolean true when applying a var_dump:

var_dump($keyExists); // I need TRUE to be returned.

Thank you for your help.

  • 2
    you can try with `array_map` – Jayveer Parmar Sep 16 '17 at 17:50
  • @jParmar I've implemented your idea. Comparing with the one from Qirel, in this situation only, it requires more code by defining + calling a callback. In other cases though, your idea would provide a powerful way to deeply customize the array items. So, good point! ;-) But for now I need the other approach. Thank you! –  Sep 16 '17 at 19:20

3 Answers3

9

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

Qirel
  • 25,449
  • 7
  • 45
  • 62
  • You need to set the first argument of `array_key_exists()` to lowercase too. Your example [returns `false`](https://3v4l.org/UNo9O). – ishegg Sep 16 '17 at 17:56
  • Ah, indeed - an oversight on my end. I'll fix it, @ishegg. Thanks! – Qirel Sep 16 '17 at 17:57
  • 1
    What I mean is, to ensure case doesn't matter at all, you can use `strtolower()` on the first argument, then it'll be always compare lowercase against lowercase, and just check if the words are the same. That might be overdoing it a bit though, depending on what OP needs. – ishegg Sep 16 '17 at 17:59
  • @Qirel I just wanted to answer to your first comment, but it wasn't there anymore :-) Thanks. I'll try this in about 10 minutes. –  Sep 16 '17 at 18:00
  • Very good point there about the values being overwritten with 2 same keys after lowercasing! +1 – ishegg Sep 16 '17 at 18:03
  • @ishegg I was actually editing in a note about `strtolower()` when you commented, but thanks none the less! :-) Cheers! – Qirel Sep 16 '17 at 18:05
  • 2
    @Qirel Well, I didn't think that it will take so much time to test all the proposed solutions (including reading the docs) - more than 10 minutes for sure :-) All solutions are viable and interesting. But, in the end, I decided to choose your idea, because it is an elegant and solid one, and it is, in this case, exactly what I need. Thank you very much for the time invested in your explanations and implementation. P.S: You provided a beautiful answer. Especially the last phrase is VERY good to know about! Good luck! –  Sep 16 '17 at 19:12
  • @aendeerei what a goddamn good OP. I wish everyone was like you, researching every answer and taking the time to reply to everyone. Kudos! – ishegg Sep 16 '17 at 20:07
  • 2
    @ishegg Well, each user deserves an answer for his answer or comment, because her/his contribution is a gift, given to you, the SO, with only one thought in mind: to help. I just learned a new word right now: "Kudos". I appreciate, thanks ;-) –  Sep 16 '17 at 20:21
0

create an array providing a mapping between lowercased and case-sensitive versions

$headers = array(
    'User-Agent' => 'Mozilla',
);
$keys=array_keys($headers);
$map=array();
foreach($keys as $key)
{
     $map[strtolower($key)]=$key;
}

$name=strtolower('user-Agent');
var_dump(isset($map[$name]))
Sachila Ranawaka
  • 39,756
  • 7
  • 56
  • 80
  • Sachila, I have tested your solution. It works perfectly and, I must say, from all the answers, your approach is the most interesting one. I'd probably never thought of such an implementation :-) I will certainly use it in the future. So, thank you for your effort and... originality! –  Sep 16 '17 at 19:25
0

You can either use array_change_key_case method (a bit expensive) to convert all keys into lower case and then compare it. Or write your own function for it.

<?php

function lowerCase($header,$compareKey){
    foreach ($header as $key => $value) {
        if(strtolower($key)==strtolower($compareKey)){
            return true;
        }       
    }
    return false;
}

$headers = array(
    'User-Agent' => 'Mozilla',
);

$keyExists = array_key_exists(strtolower('user-Agent'), array_change_key_case($headers,CASE_LOWER));

var_dump($keyExists);

$keyExists2 = lowerCase($headers,'user-Agent');
var_dump($keyExists2);
?>
Sumit Parakh
  • 1,098
  • 9
  • 19
  • In fact, `array_change_key_case()` is cheaper than the function you have there. Your `lowerCase()` is slower than `array_change_key_case()` (I ran a little speedtest to compare the two). Where'd you read that it's expensive, I'm genuinely curious? – Qirel Sep 16 '17 at 18:24
  • @Qirel it might be slower if you take into account the whole operation, no? In @SumitParkak's function you only iterate the array once, while doing `array_change_key_case()` and then `array_key_exists()` that's 2 iterations, isn't it? It must be negligible though. – ishegg Sep 16 '17 at 18:57
  • 2
    @ishegg Actually it's about twice as fast to use `array_change_key_case()` with `array_key_exists()` rather than the function provided in this answer, or that's what I found from my speed-test anyways. Generally speaking, it's always better to use native PHP functions than to write own functions that does the same. But you're right though, in either case its negligible. – Qirel Sep 16 '17 at 19:22
  • 1
    Right. I forgot that native functions are one level lower, written directly in C so they're bound to be faster. – ishegg Sep 16 '17 at 19:24
  • Sumit, thank you for your answer. It works very good! The classical, straight-forward way. I liked it. And I appreciate your time invested in giving me a solution! –  Sep 16 '17 at 19:33