【PHP】配列を扱う上でのisset()とempty()を再勉強したら配列関数の勉強もし直すことに【WordPress】

WordPress上に構築したデータ管理ツールのメンテナンスをしてたんですがー。

少し機能改善をしようとコードを変更していたところ。

カスタムフィールドをグループ化していたり、複数選択のチェックボックスやセレクトボックスなど。

配列として保存されるフィールドの値を判定条件にする時に、思ったのと違う動作が続いてしまったので。

勉強し直すことにしました。

月に数回しか触らなくなってきたことの弊害ですが、お付き合いいただければとw

まずは基本を復習

PHP・・・でなくともですが。

基本的には、変数に値を格納して取り回しやすくします。

なので、その変数に格納されているかチェックすることが条件判定の入口だったりしますね。

「安全のためにisset()で〜」「empty()でチェックしておくと〜」など。

当然のように無意識で書いていることも多いです。

まずは基本的な内容をサラッと復習しておきます。

isset()

isset()は変数が存在するかどうかと、値が何かしら入っているかを判定します。

NULL以外はtrueを返してくれます。

書きやすいのでついつい使ってしまいますが、ちょっと判定が広め。

PHPリファレンス:isset

empty()

言葉のとおりですが、変数が空かどうかを判定します。

個人的には!empty()で「空じゃない場合」の判定を良く使います。

空と判定されるのは、空文字列(“")、整数や文字列の0、浮動小数点の0.0、NULL、真偽判定のfalse、空の配列、未定義の変数、といったあたり。

フォームから値を受け取るときは良く使いますかね。

PHPリファレンス:empty

is_null()

変数がNULLかどうかを判定します。

かなり狭いですし、未定義の変数に対して使用すると、エラーになる可能性も。

一応empty()でもNULL判定をできるので、期待した動作にならず、値がNULLになる場合に使ってます。

比較表

表にもしておきます。

isset()empty()is_null()
“文字列"truefalsefalse
“"(空文字列)truetruefalse
“ "(スペース)truefalsefalse
1(数値)truefalsefalse
0(整数のゼロ)truetruefalse
0.0truetruefalse
“0"(文字列のゼロ)truetruefalse
NULLfalsetruetrue
false(真偽)truetruefalse
未定義の変数truefalsefalse

isset()は変数が存在して値があるかなので、NULL以外はすべてtrueです。

この並びだと少し混乱するかもしれませんが、empty()は空であればtrueを返すのでこの表のようになります。

配列を扱うと?

値が配列になっても、基本的な動作は変わりません。

・・・というか、変わったら困りますがー。

配列は要するに値の集合体なので、どのような判定をしたいかで使うものが変わる・・・というイメージです。

isset():配列が定義されているか?

変数の判定の場合は、「変数が存在して値が格納されているか?」でしたが。

配列の判定の場合は、「配列が定義されているか?」のみとなります。

なので、配列が空でも存在すればtrueを返してくれます。

配列の定義が間違ってなくて、後で要素を格納する・・・という時に使いますかね。

とは言え、isset()の動作を考えれば、配列の要素が格納されているか?という判定に使う方が良いでしょう。

連想配列のkeyを使って、isset(array['key’])とすれば、keyが配列に存在し値がNULLでなければtrueを返してくれます。

empty():配列が要素を持つか?

empty()は変わらず「空かどうか?」を配列でも判定してくれます。

empty(array['key’])と書くと、配列内のkeyが持つ値に対しempty()の空判定をしてくれます。

あんまり配列全体への空判定はしないので・・・。

keyを指定して、値があるかどうかという判定の方が利用します。

is_null():配列の要素のNULLをチェック

配列に対して使うことはまず思い浮かびませんが、一応。

基本で書いた通り、NULLかどうかの判定なので。

配列のkeyが持つ値の判定で使用します。

正直な話

とまぁ、ここまで書いてきたものの。

配列に対する操作で、ここらへんの関数を使うことはあんまりないと思います。

WordPressの配列の値はだいたい連想配列で格納されるので、isset(array['key’])やempty(array['key’])は使いますが。

配列に対する判定であれば、in_array()などの配列関数を使う方が効率的です。

in_array()

配列に判定を適用する場合・・・というと硬いですね。

値があるかどうかを調べることができる関数が、in_array()です。

PHPリファレンス:in_array

「配列を制するものがPHPを制する」という言葉を聞いたことがありまが、色んな配列操作の関数が用意されている中で。

まずは通るのがin_array()だと思います。(個人の見解です)

//in_array()の引数
in_array( "検索する値", 検索する配列, true か false )

第一引数に「検索する値」を。

第二引数に「検索する値」を探したい配列を。変数に格納している場合は変数名ですね。

第三引数は、trueにするとデータの型も同じかどうかを判定します。基本的にはtrueです。

配列内に値が存在するかどうかを判定し、そこから比較をしたりと、使うことは多いですね。

!in_array()で「配列内に値が存在しない」場合も良く使います。

配列じゃないと動作はしない

型比較もin_array()の注意点の一つにはなりますが。

もう一つ、意外と抜けがちなのがin_array()は対象が配列じゃないと正常に動作しないことです。

WordPressの場合、自作ならあまりないかもしれませんが。

プラグインによってはチェックボックスなど配列で返されると予想していたものが、単一選択の場合文字列で返される場合があります。

デバックでどのように返ってくるかを調べることが大切ですがー。

is_array()で配列かどうかの判定をして、配列に変換しておけば安心です。

PHPリファレンス:is_array

//配列じゃなかったら、配列にする
if( !is_array( $test_array ) ){
 $test_array = [$test_array];
}

簡単に書くとこんな感じです。

今回のメンテナンスで引っかかってたのはこれでした。

テストが少ないとこうなります。反省。

どんな判定をしたいのか?

他にも、array_key_exists()とempty()の組み合わせなど。

頭から抜けていたものを入れ直したんですが。

ここらへんのコードを書く時によく思うのが、「そもそも何を判定したいのか?」を明確にしないとなぁということです。

この記事で書いた通り、空判定に使える関数にもそれぞれ特徴があり、判定したい内容によっての向き不向きがあります。

手癖で書いてしまい、期待した動作にならない・・・ということを割けるためには。

要件定義みたいな話にはなりますが、「判定した結果どのような動作をするのか?」ということをはっきりさせないと、効率の悪いコードが出来上がってしまうでしょう。

AIを利用してコーディングする機会も増えた弊害なのかはわかりませんが。

特に個人開発のような時に、見切り発射でAIに指示を出してしまい、そもそも前提が間違っていた。

・・・というような事をたまにやってしまいます。

どんなに便利になり、コードを書く時間が減ったとしても。

設計の部分には手を抜いてはいけないという、当たり前の結論に至った再勉強でした。