phpの連想配列でキーの存在を確認する

phpで連想配列のキーが存在するかを確認する方法ですが、やり方によってはwarningが出力されたりと、何も考えずに使うとやっかいなこともあります。

 

今回は、速度面も含め自分が日ごろから利用する方法を紹介します。

 

phpで下記のような連想配列を扱う場合に、キーが存在するかを見る場合に、この様に記述しているものを見かけます。

example1

<?php

$ary = array('a' => 1, 'b' => 2, 'c' => 3);

if (isset($ary['a'])) {
  echo $ary['a'];
}

 

この様な場合は、特に問題はなく動きますが、下記のような場合にはwarningが発生します。

example2

<?php

$ary = array('a' => 1, 'b' => 2, 'c' => 3);

if (isset($ary['d'])) {
  echo $ary['d'];
}

 

上2つの違いは、配列($ary)にキーが存在している、存在しないの違いとなります。
ただし、example2の場合には実行した際に、warningが発生してしまいます。

決められた連想配列の場合には、キーの存在を気にしなくていいので、example1の様な記述で問題ありませんが、example2の様にキーが存在しない場合を考える必要がある場合には、この記述では問題があります。

 

では、どのようにするのがいいか?と言う正解を下記に記述します。

<?php

$ary = array('a' => 1, 'b' => 2, 'c' => 3);

if (array_key_exists('a', $ary)) {
  echo $ary['a'];
}

if (array_key_exists('d', $ary)) {
  echo $ary['d'];
}

 

issetではなく、array_key_existsを利用することでwarningも出さずに連想配列のキーが存在しているかを確認することができます。

 

では、速度面での違いはあるのか?と言う点も確認しておきましょう。

 

パターン1:キーが存在する連想配列の場合

<?php

$ary = array('a' => 1, 'b' => 2, 'c' => 3);

$start = 0;
$marge = 0;

for ($i = 0; $i < 10; $i++) {
  $start = measure();
  if (isset($ary&#91;'a'&#93;)) {
  }
  $marge += measure() - $start;
}
echo ($marge / 10).PHP_EOL;
$marge = 0;

for ($i = 0; $i < 10; $i++) {
  $start = measure();
  if (array_key_exists('a', $ary)) {
  }
  $marge += measure() - $start;
}
echo ($marge / 10).PHP_EOL;

function measure() {
  list($usec, $sec) = explode(' ', microtime());
  return ((float)$usec + (float)$sec);
}
&#91;/php&#93;

<strong>実行結果</strong>
[php]
# 実行1回目
1.1277198791504E-5
6.2704086303711E-6

# 実行2回目
6.6041946411133E-6
3.0517578125E-6

# 実行3回目
1.2421607971191E-5
6.2942504882812E-6

# 実行4回目
1.1610984802246E-5
2.3174285888672E-5

# 実行5回目
1.0013580322266E-5
4.9591064453125E-6

 

パターン2:キーが存在しない連想配列の場合

<?php

$ary = array('a' => 1, 'b' => 2, 'c' => 3);

$start = 0;
$marge = 0;

for ($i = 0; $i < 10; $i++) {
  $start = measure();
  if (isset($ary&#91;'d'&#93;)) {
  }
  $marge += measure() - $start;
}
echo ($marge / 10).PHP_EOL;
$marge = 0;

for ($i = 0; $i < 10; $i++) {
  $start = measure();
  if (array_key_exists('d', $ary)) {
  }
  $marge += measure() - $start;
}
echo ($marge / 10).PHP_EOL;

function measure() {
  list($usec, $sec) = explode(' ', microtime());
  return ((float)$usec + (float)$sec);
}
&#91;/php&#93;

<strong>実行結果</strong>
[php]
# 実行1回目
1.218318939209E-5
6.3180923461914E-6

# 実行2回目
1.3494491577148E-5
6.2942504882812E-6

# 実行3回目
1.1587142944336E-5
6.2942504882812E-6

# 実行4回目
1.4185905456543E-5
6.2227249145508E-6

# 実行5回目
1.2993812561035E-5
8.392333984375E-6

 

キーが存在しない場合の速度が明らかに違うのがわかります。
※検証の方法が正しいかは微妙ですが・・・。

 

これらのことを踏まえ、キーが絶対に存在する場合にはisset、キーが存在するか不明な場合にはarray_key_existsでチェックするのが最良の方法ではないかと思われます。

関連する記事

記事へのコメント (2 件)

  1. ytaro より:

    >>では、どのようにするのがいいか?と言う正解を下記に記述します。
    の箇所が
    if (array_key_exists($ary[‘a’]))
    となってますが、
    if (array_key_exists(‘a’,$ary))
    の誤りではないでしょうか。

    • errorcode より:

      ご指摘頂きありがとうございます!
      こちら記載内容を修正させて頂きましたm(_ _m)

コメントを残しませんか?