PHP判斷關聯數組的鍵值是否存在,使用empty或isset或array_key_exists

本文目的

前幾天工作中,需要頻繁判斷數組中的鍵值對是否存在,起初使用的”!empty($arr[‘key’])”來判斷,覺得這樣讀起來比較舒服,但是寫出的代碼無法通過單元測試(單元測試太好了)。排查很久,終於發現,當$arr[‘key’] == 0時,empty仍然返回true,這樣破壞了業務邏輯!

今天終於有空,就將判斷數組鍵值對存在的方法查閱了一下,記錄於此,作爲備忘。

 

一個例子

猜猜看,下面的例子會輸出什麼?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$a = array('a'=>1, 'b'=>0, 'c'=>NULL);
 
echo 'a test by empty: ' , empty($a['a']) ? 'not exist' : 'exist', PHP_EOL;
echo 'a test by isset: ' , isset($a['a']) ? 'exist' : 'not exist', PHP_EOL;
echo 'a test by array_key_exists: ' , array_key_exists('a', $a) ? 'exist' : 'not exist', PHP_EOL, PHP_EOL;
 
echo 'b test by empty: ' , empty($a['b']) ? 'not exist' : 'exist', PHP_EOL;
echo 'b test by isset: ' , isset($a['b']) ? 'exist' : 'not exist', PHP_EOL;
echo 'b test by array_key_exists: ' , array_key_exists('b', $a) ? 'exist' : 'not exist', PHP_EOL, PHP_EOL;
 
echo 'c test by empty: ' , empty($a['c']) ? 'not exist' : 'exist', PHP_EOL;
echo 'c test by isset: ' , isset($a['c']) ? 'exist' : 'not exist', PHP_EOL;
echo 'c test by array_key_exists: ' , array_key_exists('c', $a) ? 'exist' : 'not exist', PHP_EOL, PHP_EOL;

 

輸出結果如下:

========================================================

a test by empty: exist

a test by isset: exist

a test by array_key_exists: exist

 

 

 

 

b test by empty: not exist

b test by isset: exist

b test by array_key_exists: exist

 

 

 

c test by empty: not exist

c test by isset: not exist

c test by array_key_exists: exist

========================================================

注意紅色高亮部分

 

三種方式的語法區別

  • empty: 參數爲0或爲NULL時(如上面列子),empty均返回TRUE,詳細情況可以參見empty官方手冊
  • isset: 參數爲NULL時,返回FALSE,0與NULL在PHP中是有區別的,isset(0)返回TRUE
  • array_key_exists: 純粹的判斷數組鍵值對是否存在,無論值是多少

 

所以,從準確性的角度來看,array_key_exists是最準確的!

 

三種方式的性能比較

從網上拿到一組數據,參見這裏或參考資料,如下所示:

For a small array:

array_key_exists: float(0.18357992172241)

empty: float(0.072798013687134)

isset: float(0.070242881774902)

For a relative big array:

array_key_exists: float(0.57489585876465)

empty: float(0.0068421363830566)

isset: float(0.0069410800933838)

 

可以看到在大數據情況下,empty和isset的性能比array_key_exists快了2個數量級,差別還是很大。如果頻繁判斷,還是需要優化。產生這麼大性能差別的原因,個人猜測,可能是isset和empty作爲php語法結構不是函數,php解釋器做了優化,而array_key_exists作爲函數,沒有相關優化。具體原因,有待通過源碼考究。

 

三種方式的使用建議

(鑑於empty與isset性能類似,但是isset準確性較高,這裏就只比較isset與array_key_exists)

  • 如果數組不可能出現值爲NULL的情況,建議使用isset
  • 如果數組中經常出現值爲NULL的情況,建議使用array_key_exists
  • 如果數組中可能出現值爲NULL,但是較少的情況,建議結合isset與array_key_exists使用,如“if (isset($arr[‘key’]) || array_key_exists(‘key’, $arr)){/*do somthing*/}”。此方法兼顧了性能和準確性,但是代碼變長了。

 

參考資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章