[PHP] 連想配列内の検索

2023年1月28日

PHP Tips

eyecatch Javascriptばっかり書いていてたまにPHPを書くと、セミコロンを付け忘れます。 他にも、Classインスタンスを->ではなく、.(コロン)でつないでしまってエラーがでます。 そうです、マルチ言語プログラマーのよく陥る、言語コンフリクトに陥ってしまうんですよね。 でも、コレ、2秒で解決するので、さほど問題ではないんですよ。 この間、仕事で、データを整形する作業をPHPで書いていた時に、Javascriptのfindのような機能がPHPに無いことに気がついた。 配列関数を山程持っているPHPなのに、こんな便利な機能を設けていないなんて、こんなんだから、PHPはオワコンって言われちゃうんだよな・・・と頭の中で暴言を吐いてしまった事は言わないでおきます。

PHPにおける配列の計算方法

とりあえず、PHPで配列(連想配列)の検索について、いくつか方法があるので、考えられる限り書いてみる。

in_array

(PHP 4, PHP 5, PHP 7, PHP 8) <?php $arr = ['A','B','C']; echo in_array('C' , $arr); // > 1 echo in_array('c' , $arr); // > 大文字小文字の判定も厳密に行うので、曖昧な検索はできません。 返り値が1またはblankなので、true/falseという点も、覚えておきましょう。

array_search

(PHP 4 >= 4.0.5, PHP 5, PHP 7, PHP 8) <?php $arr = ['A','B','C']; echo array_search('C' , $arr); // > 2 echo array_search('c' , $arr); // > こちらは、ヒットした場合に配列の番号(0スタート)の値が返ります。 ヒットしなかった場合は、nullですね。

array_column

(PHP 5 >= 5.5.0, PHP 7, PHP 8) <?php $arr = [ ['a'=>'A', 'b'=>'B', 'c'=>'C'], ['a'=>'D', 'b'=>'E', 'c'=>'F'], ['a'=>'G', 'b'=>'H', 'c'=>'I'], ]; print_r(array_column($arr , 'C')); // Array() print_r(array_column($arr , 'c')); // Array( // [0] => C // [1] => F // [2] => I // ) 基本的に配列内に連想配列のパターンで、連想配列内のkeyを含んでいる値を配列で取得するという命令です。 ヒットしなければ、空配列が返ります。 データベースでSELECTした返り値などの場合に任意のカラム情報だけ抜き出したい時に使えますね。

JavascriptのfindをPHPで実行する方法

<?php $arr = [ ['id'=>'1', 'name'=>'Yamada', 'info'=>'A'], ['id'=>'2', 'name'=>'Takeda', 'info'=>'B'], ['id'=>'3', 'name'=>'SUzuki', 'info'=>'C'], ]; $res = $arr[array_search(2 , array_column($arr , 'id'))]; print_r($res); // Array // ( // [id] => 2 // [name] => Takeda // [info] => B // ) array_columnで、keyの一覧を取得してから、array_searchで配列内の順番を取得してから、配列内の値を取得するという連結技です。 どうやらこれ、PHPの定番らしいです。 頼むから、array_find関数作ってくれ!!! ただ、この方法だと、バグが発生してしまいます。 $res = $arr[array_search(5 , array_column($arr , 'id'))]; print_r($res); // Array // ( // [id] => 1 // [name] => Yamada // [info] => A // ) おわかりだろうか? array_searchで存在しない値が返ってきた場合に、$array[*]の*がnullを0と勘違いして値を返してしまうんですよ。 なので、一行で書かずにちゃんと判定をしてあげないといけないですね。 ただ、idが数値型で判定してくれるのは、有り難いと思いました。 もはや自力で解決するしかないので、この記事のおわりにおまけとして、array_find関数を作っておきました。 使いたい人は存分に使ってくだされ!!

もう一つ問題に直面(体験談)

今回のコードは、PHP8の環境で検証したんですが、仕事上記のfind処理を書いてみた所、array_columnがエラーになって、作業が止まってしまいました。 何度やってもエラー文字ばかりが返ってくるので、ちゃんとエラーを読んでみると、undefinedと書いてある。 ん?もしかしてPHPのバージョンが古いのか?と思ってサーバー側のバージョンを調べてみたら・・・PHP5.4・・・orz array_columnは、PHP5.5からの機能・・・ PHP5.5は、2013年06月20日から実施されたアップデートで、PHP5.4という事はそれより前に設置されたサーバーということがわかった。 参考 : https://ja.wikipedia.org/wiki/PHP_(プログラミング言語) 現時点でブログが2023年1月という事を考えると、10年間PHPがノーメンテナンス状態という、アホな運用をしている事が判明。 とある会社のサーバーなんだが、この会社終わってるわ・・・とりあえず、動けば良いものを作ればいいのだが・・・

おまけ

array_columnが動かないので、次の関数を作って対応することにした。 function array_column($datas=[] , $key=''){ $res_datas = []; for($i=0; $i<count($datas); $i++){ $d = $datas[$i]; $res_datas[] = isset($d[$key]) ? $datas[$i][$key] : ''; } return $res_datas; } あと、いっそのこと、array_findも作ってみました。 <?php function array_find($array=[] , $key='' , $value=''){ $column = array_column($array , $key); $search = array_search($value , $column); if($search === false){return [];} return $array[$search]; } こんな風に使ってください。 $arr = [ ['id'=>'1', 'name'=>'Yamada', 'info'=>'A'], ['id'=>'2', 'name'=>'Takeda', 'info'=>'B'], ['id'=>'3', 'name'=>'SUzuki', 'info'=>'C'], ]; $res = array_find($arr , 'id' , 4); echo '<pre>--'.PHP_EOL; print_r($res); echo '</pre>'

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。