phpで連想配列のキーが存在するかを確認する方法ですが、やり方によってはwarningが出力されたりと、何も考えずに使うとやっかいなこともあります。
今回は、速度面も含め自分が日ごろから利用する方法を紹介します。
キーの存在を確認する方法
phpで下記のような連想配列を扱う場合に、キーが存在するかを見る場合に、この様に記述しているものを見かけます。
Example – 1
<?php
$ary = [
'a' => 1,
'b' => 2,
'c' => 3
];
if (isset($ary['a'])) {
echo $ary['a'];
}
この様な場合は、特に問題はなく動きますが、下記のような場合にはwarningが発生します。
Example – 2
<?php
$ary = [
'a' => 1,
'b' => 2,
'c' => 3
];
if (isset($ary['d'])) {
echo $ary['d'];
}
上記の2つの例についての違いは、配列($ary)にキーが存在している、存在しないの違いとなります。
※ただし、Example – 2の場合には実行した際に、warningが発生してしまいます。
決められた連想配列の場合には、キーの存在を気にしなくていいので、Example – 1の様な記述で問題ありませんが、Example – 2の様にキーが存在しない場合を考える必要がある場合には、この記述では問題があります。
では、どのようにするのがいいか?と言う正解を下記に記述します。
確実な方法
<?php
$ary = [
'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 = [
'a' => 1,
'b' => 2,
'c' => 3
];
$start = 0;
$marge = 0;
for ($i = 0; $i < 10; $i++) {
$start = measure();
if (isset($ary['a'])) { }
$marge += measure() - $start;
}
echo ($marge / 10).PHP_EOL;
$start = 0;
$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);
}
実行結果
# 実行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 = [
'a' => 1,
'b' => 2,
'c' => 3
];
$start = 0;
$marge = 0;
for ($i = 0; $i < 10; $i++) {
$start = measure();
if (isset($ary['d'])) { }
$marge += measure() - $start;
}
echo ($marge / 10).PHP_EOL;
$start = 0;
$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);
}
実行結果
# 実行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でチェックするのが最良の方法ではないかと思われます。
コメント
>>では、どのようにするのがいいか?と言う正解を下記に記述します。
の箇所が
if (array_key_exists($ary[‘a’]))
となってますが、
if (array_key_exists(‘a’,$ary))
の誤りではないでしょうか。
ご指摘頂きありがとうございます!
こちら記載内容を修正させて頂きましたm(_ _m)