【WordPressカスタマイズ相談】現役プログラマが解決策を教えます

WordPress(ワードプレス)のお悩み、うまくいかなくてお困りなこと、不具合調査、新規制作依頼まで、ウェブアプリケーションエンジニアがあなたをサポートします。

PHP多次元配列、特定キーの値を検索しindexを取得する(ループ不要)

f:id:jsaz:20171210155520p:plain

WordPressoptionテーブルに独自のデータを管理する場合、連想配列を使うのですが、 その中の配列からIDやCODEから対象のデータを探す際にループさせて1件ずつ探していく面倒だったので、もう少し良い方法はないかと調べてみました。

array_columnarray_search を使うことで2行で対象のデータを取得することができます。 具体的なサンプルも合わせて載せていきます。

参考にしたサイト

qiita.com

今回使うデータは駅データ

使ったサンプルデータは 駅データ.jp です。 www.ekidata.jp

一応、福岡在住ということで都道府県APIから福岡(40)を指定しLINE CODE 36001 の西鉄天神大牟田線をサンプルデータとしました。

西鉄天神大牟田線の各駅名を取得する駅データURLは下記です。 json形式のデータです。

http://www.ekidata.jp/api/l/36001.json

---
{
    "line_cd": 36001, 
    "line_lat": 33.33736616073844, 
    "line_lon": 130.469530100445, 
    "line_name": "西鉄天神大牟田線", 
    "line_zoom": 10, 
    "station_l": [
        {
            "lat": 33.588937, 
            "lon": 130.399733, 
            "station_cd": 3600101, 
            "station_g_cd": 3600101, 
            "station_name": "西鉄福岡(天神)"
        }, 
        {
            "lat": 33.581957, 
            "lon": 130.401683, 
            "station_cd": 3600102, 
            "station_g_cd": 3600102, 
            "station_name": "薬院"
        }, 
        {
            "lat": 33.573631, 
            "lon": 130.406254, 
            "station_cd": 3600103, 
            "station_g_cd": 3600103, 
            "station_name": "西鉄平尾"
        }, 
        {
            "lat": 33.567138, 
            "lon": 130.414743, 
            "station_cd": 3600104, 
            "station_g_cd": 3600104, 
            "station_name": "高宮"
        }, 
        {
            "lat": 33.559128, 
            "lon": 130.426559, 
            "station_cd": 3600105, 
            "station_g_cd": 3600105, 
            "station_name": "大橋"
        }, 
:
略
:
        {
            "lat": 33.038453, 
            "lon": 130.450001, 
            "station_cd": 3600147, 
            "station_g_cd": 3600147, 
            "station_name": "新栄町"
        }, 
        {
            "lat": 33.029701, 
            "lon": 130.443249, 
            "station_cd": 3600148, 
            "station_g_cd": 1190328, 
            "station_name": "大牟田"
        }
    ]
}

これがDBに保存されている前提でWordPressにてget_optionで取得できるデータという想定で進めます。
わかりやすいように$station_lには上記jsonのstation_lが配列で入っているとします。

station_cdだけがわかっている状態で、その駅情報を取得するのが目標です。

普通に考えるとループで検索

station_cdがわかっているので、たとえば「大牟田」の情報が欲しい場合、

”station_cd": 3600148, 

なので、

<?php
foreach ($station_l as $station) {
    if ($station['station_cd'] == '3600148') {
        var_dump($station);
    }
}

こんな方法で1件ずつstation_cdを比較して一致するものを探さないといけません。
ソースコードがごちゃごちゃしてしまう恐れがあります。
(今回は処理速度は置いておく)

array_columnで検索対象のカラムのみ取得

station_cdだけわかっているので、array_columnを使いstation_cdだけの配列を作ります。下記サイトを参考にします。

qiita.com

実際のプログラムはこんな感じ。

<?php
$list_station_cd= array_column($station_l, 'station_cd');
var_dump($list_station_cd);

---
array(49) {
  [0] =>
  int(3600101)
  [1] =>
  int(3600102)
  [2] =>
  int(3600103)
  [3] =>
  int(3600104)
  [4] =>
  int(3600105)
  [5] =>
  int(3600106)
  [6] =>
  int(3600107)
  [7] =>
  int(3600108)
:
略

array_searchを使い対象のインデックスを取得

配列の何番目か(またはキー)を返します。 今回は$list_station_cdから対象のstation_cdが何番目になるかを求めます。

<?php
$result_index = array_search($target_station_cd, $list_station_cd);

array_columnとarray_searchを組み合わせることで簡単に配列の情報を取得することができます。WordPressのoptionデータに限られた話ではありません。 実際に西鉄電車の駅の情報を取得するサンプルを書いていきます。

(サンプル)大橋駅の情報が欲しいとき

<?php
$target_station_cd = '3600105';
$list_station_cd= array_column($station_l, 'station_cd');
$result_index = array_search($target_station_cd, $list_station_cd);
var_dump($station_l[$result_index ]);

---
array(5) {
  'station_cd' =>
  int(3600105)
  'station_g_cd' =>
  int(3600105)
  'station_name' =>
  string(6) "大橋"
  'lon' =>
  double(130.426559)
  'lat' =>
  double(33.559128)
}

ループしたり、if分もないしbreakもしないのでシンプルに記述できますね。

WordPressでの利用時のサンプルコード

実際に私がこの方法で作成したWordPressプラグインの一部を抜粋して記述します。

<?php
$html = '';
//保存データ取得
$data = get_option( self::KEY );
$array_keys = array_column($data, 'id');
$data_index = array_search($id, $array_keys);
$param = $data[$data_index];
require_once 'site/view.php';
return output($param );

やっていることは下記のような流れです。

  • KEY で指定したoptionデータからid=$idの条件でデータを取得
  • $idはGETパラメータ
  • $idのデータ$param をテンプレートの引数としてセット

ただでさえ冗長になりやすいWordPressソースコードなので、この方法できれいすっきりと記述することができます。