Skip to content

Zeroplex 生活隨筆

軟體開發、伺服器和生活瑣事

小 縮小字型大小。 中 重設字型大小。 大 放大字型大小。

PHP array_merge() 在資料型別上行為的差異

Posted on 2014 年 11 月 25 日2021 年 3 月 12 日 By 日落 在〈PHP array_merge() 在資料型別上行為的差異〉中有 2 則留言

array_merge() 可合併多個陣列,遇到相同的陣列索引,將由後方陣列的值取代前一個值。

如:

$d = array(
  'a' => 111,
  'b' => 222,
);
 
$e = array(
  'a' => 123,
  'c' => 333,
);
var_dump(array_merge($d, $e));

執行結果為:

array(3) {
  ["a"]=>
  int(123)
  ["b"]=>
  int(222)
  ["c"]=>
  int(333)
}

此特性常被用來做設定選項合併,如:

function__construct(array $config){
  $defaultsStyle = array(
    'display' => true,
    'color' => 'red',
    'size' => '14px',
  );

  $settings = array_merge($defaultStyle, $config);

  // initialize by $settings
}

上面的寫法可以讓預設的三項索引「display」、「color」、「size」一定存在,不需特別在做 array_key_exists() 檢查,且外部傳入的數值,會將內定的預設值覆蓋掉。

不過只有字串型態的陣列索引,經過 array_merge() 以後可以保留原有的索引名稱,若為數字型態的陣列索引,array_merge() 會將原有索引打掉重新排列。

如:

$d = array(
  0 => 111,
  1 => 222,
);
 
$e = array(
  9 => 123,
  7 => 333,
);
var_dump(array_merge($d, $e));

執行的結果會是:

array(4) {
  [0]=>
  int(111)
  [1]=>
  int(222)
  [2]=>
  int(123)
  [3]=>
  int(333)
}

另外 array_merge() 有個很奇怪的行為,假設陣列的索引是「類似數字」的字串 (不曉得判斷規則為何),像是 “100”、”200″,經過 array_merge() 時會被當成數字型索引處理。

如:

$d = array(
  '100' => 111,
  '200' => 222,
);
 
$e = array(
  '100' => 100,
  '300' => 333,
);
var_dump(array_merge($d, $e));

執行後為:

array(4) {
  [0] =>
  int(111)
  [1] =>
  int(222)
  [2] =>
  int(100)
  [3] =>
  int(333)
}

若索引名稱為 “001”、”002″,經過 array_merge() 才會被當成字串,不會有上述情況發生。

要避免索引被吃掉,可以改用 array unioin operator:

$d = array(
  '100' => 111,
  '200' => 222,
);
 
$e = array(
  '100' => 100,
  '300' => 333,
);
var_dump($d + $e));

陣列索引會被保留下來:

array(3) {
  [100] =>
  int(111)
  [200] =>
  int(222)
  [300] =>
  int(333)
}

不過要注意的是,array union operator 遇到相同索引時,陣列值並不會被後方的陣列取代 ($merged[‘100’] 會是 111 而非 100),所以使用時要注意順序問題。

總之,’100’、’200′ 被 array_merge() 當成數字讓我極度不爽。

Tags:PHP

文章導覽

Previous Post: Vim Arrow Key Alias
Next Post: irssi 快速鍵

Comments (2) on “PHP array_merge() 在資料型別上行為的差異”

  1. 日落 Zero表示:
    2014 年 12 月 2 日03:43

    備註:
    array_merge() 中可能是用 is_numeric() 去判斷 key 是否為數字
    而 is_numeric( strval("123") ) === true

    回覆
  2. 日落 Zero表示:
    2014 年 12 月 12 日06:46

    看來有人問過這問題,而且發問的人快要起笑了 XD

    https://bugs.php.net/bug.php?id=25470

    回覆

發佈留言 取消回覆

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


其他

關於我  (About me)

小額贊助

  文章 RSS Feed

  留言 RSS Feed

Apache AWS Bash C/C++ Docker FreeBSD GCP Git Google Java JavaScript Laravel Linux Microsoft MSSQL MySQL Nginx PHP PHPUnit PostgreSQL Python Qt Ubuntu Unix Vim Web Windows WordPress XD 作業系統 分享 好站推薦 專題 攝影 新奇搞笑 新聞 旅遊 生活雜記 程式設計 網路架站 網頁設計 資訊學習 資訊安全 遊戲 音樂


創用 CC 授權條款
本著作係採用創用 CC 姓名標示-相同方式分享 4.0 國際 授權條款授權.