と言ってもおかしくないくらい、『PHP』を扱う時には『配列(連想配列)』の出番が数多くあります。
『配列』ってこんな形で、
$seito = ['本田','香川','長友','乾','大迫'];
1つの変数の中に、たくさんのデータを入れられる仕組みです。
『連想配列』はこんな形。
$seito = [ 'name' => '本田', 'age' => 6, 'position' => 'MF', ];
キー(key)とバリュー(value)によって構成されています。
- 名前 (キー) => 本田 (バリュー)
- 年齢 (キー) => 6 (バリュー)
- ポジション (キー) => MF (バリュー)
ですね。
こういった、シンプルな『配列(連想配列)』なら扱いやすいのですが、
実際には『配列』の中に『配列』が組み合わさったデータ構造を扱う事も多いです。
$seito = [ 0 => [ 'name' => '本田', 'age' => '6' ], 1 => [ 'name' => '香川', 'age' => '6' ], ];
『多次元配列』や『2次元配列』なんて言われたりします。
参考記事
Webページをつくっていると、
- フォームにデータ(配列)を入力する
- データベースに保存する
という流れがしょっちゅうでてきます。
シンプルな『配列(連想配列)』ならわりと簡単なのですが、『多次元配列』の場合、
- フォームにデータ(配列)を入力する
- データベースに保存する
というだけではうまくいかない場合もよくあるんですよね。
なんせ、配列の中に配列が入ってくるので、
ってなっちゃうので。
なので、
- フォームにデータ(配列)を入力する
- データベースに保存する
の間に
受け取ったデータを保存したい順番に整形する
という手順を踏む必要があります。
- フォームにデータ(配列)を入力する
- 受け取ったデータを保存したい順番に整形する
- データベースに保存する
こうですね。
PHP 多次元配列 フォーム編
今回作成したフォーム(イメージ)です。
編集画面を想定していて、
- 選手名を変えられる
- 表示順番を変えられる
- 表示/非表示を切り替えられる
- まとめて保存
というつくりになっています。
画面側のコードはこんな感じ( 『Laravel』で書いてますが普通のphpと大差ないかと (CSS周りははしょってます))
<form method="post" action="/update"> //フォーム保存のお約束 <table> <thead> <tr> <th>id</th> <th>選手名</th> <th>表示順</th> <th>表示/非表示</th> </tr> </thead> <tbody> @foreach ($members as $member) <tr> <td> {{$member['member_id']}} </td> <td> <input type="text" name="name[]" value="{{$member['name']}}" required> </td> <td> <input type="text" name="sortNo[]" value="{{$member['sortNo']}}" required> </td> <td> <input type="text" name="visible_flag[]" class="input" value="{{$member['visible_flag']}}" required> </td> </tr> @endforeach </tbody> </table> <input type="hidden" name="_token" value="{{csrf_token()}}"> //フォーム保存のお約束 <input type="submit" value="更新"> </form>
- formタグで囲って
- メソッドはPOSTで (フォーム保存のお約束)
- アクション・・保存する処理を書いているファイル(今回はupdate)
- foreachで選手名・表示順・表示/非表示を1つずつ表示
させています。
変更できる箇所はこんなコード。
<input type="text" name="name[]" value="{{$member['name']}}" required>
name の値として name[] とカギカッコをつけているので『配列』になり、カギカッコの中に数字がはいってきます。
今回の場合、
name[0] //大迫 name[1] //長友 name[2] //本田
ですね。
このフォームで更新ボタンを押すと、こんなデータ構造でデータが流れてきていました。
$sensyu = [ 'name' => [ 0 => '大迫', 1 => "長友", 2 => "本田", ], 'sortNo' => [ 0 => "1", 1 => "2", 2 => "3", ], 'visible_flag' => [ 0 => "1", 1 => "1", 2 => "1", ] ];
連想配列で、
1段目のキーがnameやsortNo、visible_flag、
キーに対するバリューの中に、また連想配列があるというつくりです。
データベースに保存する時は、
- 名前・・大迫
- 表示順・・1
- 表示フラグ・・1
というように、選手ごとに保存させたいなと。
こういった、2段階の連想配列で便利なのが、『array_column』 という関数になります。
PHP 多次元配列 保存処理編 array_column
『array_column』はPHP5.5.0から追加された関数で、
2次元配列や多次元配列で、特定の位置の値だけを配列で返せるという、
ややわかりづらい関数ではあるのですが、
ググっていると図解でとてもわかりやすいPHP配列関数一覧がありました。
図解でわかるPHP配列関数一覧
array_columnの説明はこれ。
で、他にもいくつかググって、できあがったコードが以下になります(こちらも『Laravel』想定です)。
<?php public function update(Request $request) { //リクエスト全部取得 $inputs = $request->all(); //連想配列のキーを取得 $keys = array_keys($inputs); // キー1つめの、2段目の数を取得 $count = count($inputs[$keys[0]]); $id = 1; // idは1スタート for($i = 0; $i < $count; $i++) //2段目の数の分だけループ { $members = Member::findorFail($id); //保存用インスタンス取得 $input = array_column($inputs, $i); //二次元配列の値の列を取得 $members->name = $input[0]; // 選手名 $members->sortNo = $input[1]; // 表示順 $members->visible_flag = $input[2]; //表示/非表示 $members->save(); //保存 $id++; //idを1増やす }; }
正直もっとキレイな書き方がありそうな気もするんですが、
まずは意図通りデータ取得できたのでよしとすることに。
PHPの2次元(多次元)配列ならarray_columnが使いやすいでっせ
フォームで1つずつ保存するならまだしも、
まとめて保存するとなったら、2次元(多次元)の配列を使うととても便利になる反面、
そのままデータ保存できない場合もでてくるので、
- フォームにデータ(配列)を入力する
- 受け取ったデータを保存したい順番に整形する
- データベースに保存する
という順番で、意図通りのデータに加工してから保存させる必要がでてきます。
今回は、『array_column』の他に、『array_keys』や『count』などの関数を使いましたが、
なんせPHPの配列関数は80(!?)近くあるようで、
うまく組み合わせて、いい感じでデータ取得できるようにしたいですね。
残念ながら『パーフェクトPHP』は5.3.3想定なのでarray_columnは掲載されていないのですが、それでも超優良書だと思います。
『PHP(Laravel)』ではこんな記事も読まれています。
1. 【PHP/Laravel】初心者向けの動画をリリースしました【Udemy】2. 【Laravel(PHP)】初心者向け アプリのつくり方 をリリースしました【techpit】
3. 【PHP】【Laravel】CSVエクスポートの方法〜5つのポイント〜
4. 【PHP】オブジェクトと連想配列の違いについて調べてみた【初心者向け】
5. 【PHP】CSVインポートの方法〜大量データもバルクインサートでバッチリ!〜【laravel】
6. 【PHP】【図解】クラスと抽象クラスとインターフェースとトレイトとDIをまとめてみた【初心者向け】
7. 【PHP】配列や連想配列が覚えづらかったので学校に例えてみた【初心者向け】
8. 【PHP】ホームページに天気予報を表示させる方法【Webスクレイピング】【初心者向け】
9. 【Laravel】Webアプリ環境構築の仕方【Vue.js】【初心者向け】
10. 【PHP】2次元(多次元)配列でデータ取得したいならarray_columnがめっさ便利
アオキのツイッターアカウント。
この記事へのコメントはありません。