PHP:数组键大小写*不敏感*查找?

$myArray = array ('SOmeKeyNAme' => 7); 

我想$myArray['somekeyname']返回7
有没有办法做到这一点,没有操纵数组?

我不创build数组,因此无法控制它的关键

选项1 – 更改您创buildarrays的方式

如果不进行线性search或更改原始数组,则无法执行此操作。 当您在查找值时插入AND时,最有效的方法是在键上使用strtolower 。

  $myArray[strtolower('SOmeKeyNAme')]=7; if (isset($myArray[strtolower('SomekeyName')])) { } 

如果保留密钥的原始情况对您来说很重要,您可以将其作为该密钥的附加值存储,例如

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

选项2 – 创build一个辅助映射

当你更新了这个问题,以表明你不可能做到这一点,那么你如何创build一个数组提供小写和大小写敏感的版本之间的映射?

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

现在,您可以使用它从小写字母获取区分大小写的键

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

这样就避免了需要使用小写键创build数组的完整副本,这是唯一的解决方法。

选项3 – 创buildarrays的副本

如果不需要考虑数组的完整副本,那么可以使用array_change_key_case创build一个包含较低的外键的副本。

 $myCopy=array_change_key_case($myArray, CASE_LOWER); 

我知道这是一个老问题,但处理这个问题的最优雅的方法是使用:

 array_change_key_case($myArray); //second parameter is CASE_LOWER by default 

在你的例子中:

 $myArray = array ('SOmeKeyNAme' => 7); $myArray = array_change_key_case($myArray); 

之后$ myArray将包含所有小写键:

 echo $myArray['somekeyname'] will contain 7 

或者,您可以使用:

 array_change_key_case($myArray, CASE_UPPER); 

文档可以在这里看到: http : //us3.php.net/manual/en/function.array-change-key-case.php

您可以使用ArrayAccess接口来创build一个与数组语法配合使用的类。

 $lower_array_object = new CaseInsensitiveArray; $lower_array_object["thisISaKEY"] = "value"; print $lower_array_object["THISisAkey"]; //prints "value" 

要么

 $lower_array_object = new CaseInsensitiveArray( array( "SoMeThInG" => "anything", ... ) ); print $lower_array_object["something"]; //prints "anything" 

 class CaseInsensitiveArray implements ArrayAccess { private $_container = array(); public function __construct( Array $initial_array = array() ) { $this->_container = array_map( "strtolower", $initial_array ); } public function offsetSet($offset, $value) { if( is_string( $offset ) ) $offset = strtolower($offset); if (is_null($offset)) { $this->container[] = $value; } else { $this->container[$offset] = $value; } } public function offsetExists($offset) { if( is_string( $offset ) ) $offset = strtolower($offset); return isset($this->_container[$offset]); } public function offsetUnset($offset) { if( is_string( $offset ) ) $offset = strtolower($offset); unset($this->container[$offset]); } public function offsetGet($offset) { if( is_string( $offset ) ) $offset = strtolower($offset); return isset($this->container[$offset]) ? $this->container[$offset] : null; } } 

一个简单但也许是代价高昂的方法是复制一个数据,然后使用array_change_key_case($array_copy, CASE_LOWER) ,然后访问array_copy['somekeyname']

我将Paul Dixon的创build键映射的想法与Kendall Hopkins使用ArrayAccess接口保留熟悉的访问PHP数组的方法相结合。

其结果是避免复制初始数组,并允许透明的不区分大小写访问的类,同时在内部保留键的情况。 限制:如果初始数组中包含不区分大小写的相等键(例如“Foo”和“foo”),或者dynamic添加,则后面的条目将覆盖以前的条目(使这些条目无法访问)。

无可否认,在很多情况下,它的(imo)更简单,只需要小写$lowercasedKeys = array_change_key_case($array, CASE_LOWER); ,正如Mikpa所build议的那样。

CaseInsensitiveKeysArray类

 class CaseInsensitiveKeysArray implements ArrayAccess { private $container = array(); private $keysMap = array(); public function __construct(Array $initial_array = array()) { $this->container = $initial_array; $keys = array_keys($this->container); foreach ($keys as $key) { $this->addMappedKey($key); } } public function offsetSet($offset, $value) { if (is_null($offset)) { $this->container[] = $value; } else { $this->container[$offset] = $value; $this->addMappedKey($offset); } } public function offsetExists($offset) { if (is_string($offset)) { return isset($this->keysMap[strtolower($offset)]); } else { return isset($this->container[$offset]); } } public function offsetUnset($offset) { if ($this->offsetExists($offset)) { unset($this->container[$this->getMappedKey($offset)]); if (is_string($offset)) { unset($this->keysMap[strtolower($offset)]); } } } public function offsetGet($offset) { return $this->offsetExists($offset) ? $this->container[$this->getMappedKey($offset)] : null; } public function getInternalArray() { return $this->container; } private function addMappedKey($key) { if (is_string($key)) { $this->keysMap[strtolower($key)] = $key; } } private function getMappedKey($key) { if (is_string($key)) { return $this->keysMap[strtolower($key)]; } else { return $key; } } } 

将数组分配给数组时,可以使用小写字母,而在查找数值时也可以使用小写字母。

不用修改数组,而是整个数据结构:

一个非常麻烦的方法涉及到创build神奇的getter / setter方法,但真的值得付出努力(注意其他方法也必须被实现)?

 <?php class CaseInsensitiveArray { protected $m_values; public function __construct() { $this->m_values = array(); } public function __get($key) { return array_key_exists($key, $this->m_values) ? $this->m_values[$key] : null; } public function __set($key, $value) { $this->m_attributes[$key] = $value; } } 

您可以手动循环访问数组并search匹配项。

 foreach( $myArray as $key => $value ) { if( strtolower( $key ) == 'somekeyname' ) { // match found, $value == $myArray[ 'SOmeKeyNAme' ] } } 

来自PHP网站

 function array_ikey_exists($key, $haystack){ return array_key_exists(strtolower($key), array_change_key_case($haystack)); } 

Referance: http ://us1.php.net/manual/en/function.array-key-exists.php#108226

我还需要一种方法来返回(第一个)不区分大小写的键匹配。 以下是我想到的:

 /** * Case-insensitive search for present array key * @param string $needle * @param array $haystack * @return string|bool The present key, or false */ function get_array_ikey($needle, $haystack) { foreach ($haystack as $key => $meh) { if (strtolower($needle) == strtolower($key)) { return (string) $key; } } return false; } 

所以,要回答原来的问题:

 $myArray = array('SOmeKeyNAme' => 7); $test = 'somekeyname'; $key = get_array_ikey($test, $myArray); if ($key !== false) { echo $myArray[$key]; } 

我知道这是旧的,但如果有其他人需要一个快速简单的方法来做到这一点,而不实际改变原来的数组:

 function array_key_i($needle, $haystack){ $key=array_search(strtolower($search), array_combine(array_keys($array),array_map('strtolower', array_keys($array)))); return ($key!==false); } $array=array('TeSt1'=>'maybe'); $search='test1'; array_key_i($search, $array); // returns true