PHPの2次元配列を使うと、データベースの表データと同じようにデータをもてます。その配列を検索する方法です。
『DBのSQL使えよ!』って話ですが、PHPだけでも同じように検索できます。しかし、実用的ではありません。遊びのプログラミングに近い。
サイトにテーブル(表)を表示するとき、検索機能が必要になることってありますよね?
ただこの場合、まず先に考えるべきなのはDBのSQLを使うことです。
(テーブル操作でDBに勝てるものはない。)
それでダメならJavaScriptを使う。
(サーバーへのアクセス負荷がない。速い。)
今回の話は3番めの候補になるPHPでやってしまう方法です。
多次元配列でよく使う - array_column()
テーブルの情報は二次元配列データです。
(タテ(列)とヨコ(行)の2つあるから。)
PHPの多次元配列データでは、キーになる一次元の配列を使います。array_column()は多次元配列から一次元配列を取り出す関数です。
(名前のとおりカラム(列)を取り出す。)
<?php
$table = [
[ 'No' => '1', 'name' => '太郎', 'score' => '56', 'sexuality' => '男' ],
[ 'No' => '2', 'name' => '花子', 'score' => '80', 'sexuality' => '女' ],
[ 'No' => '3', 'name' => '次郎', 'score' => '35', 'sexuality' => '男' ],
[ 'No' => '4', 'name' => 'みか', 'score' => '70', 'sexuality' => '女' ],
[ 'No' => '5', 'name' => 'ジョン', 'score' => '67', 'sexuality' => '男' ],
[ 'No' => '6', 'name' => 'ステファニー', 'score' => '96', 'sexuality' => '女' ],
];
$name = array_column( $table, 'name');
var_export( $name );
array (
0 => '太郎',
1 => '花子',
2 => '次郎',
3 => 'みか',
4 => 'ジョン',
5 => 'ステファニー',
)
多次元配列は、[]が何層あるか?で判断します。
テーブルは2層なので2次元配列です。
多次元配列のデータで何かをするとき、けっこう使うので覚えましょう。
ひとつのデータを取り出す - array_search()
テーブルの中から1件のデータを取り出すときは、array_search()が便利です。
さっきのテーブルから学生番号が3のデータを取り出しましょう。
<?php
$table = [
[ 'No' => '1', 'name' => '太郎', 'score' => '56', 'sexuality' => '男' ],
[ 'No' => '2', 'name' => '花子', 'score' => '80', 'sexuality' => '女' ],
[ 'No' => '3', 'name' => '次郎', 'score' => '35', 'sexuality' => '男' ],
[ 'No' => '4', 'name' => 'みか', 'score' => '70', 'sexuality' => '女' ],
[ 'No' => '5', 'name' => 'ジョン', 'score' => '67', 'sexuality' => '男' ],
[ 'No' => '6', 'name' => 'ステファニー', 'score' => '96', 'sexuality' => '女' ],
];
$no = array_column( $table, 'No');
$key = array_search( '3', $no );
var_export( $table[ $key ] );
array (
'No' => '3',
'name' => '次郎',
'score' => '35',
'sexuality' => '男',
)
array_search()は、最初に見つかった配列のインデックスを返します。複数のデータが一致するものには使えません。
複数のデータを取り出す - array_filter()
複数のデータを取り出すときはarray_filter()を使って、一致する条件式を作りましょう。
<?php
$table = [
[ 'No' => '1', 'name' => '太郎', 'score' => '56', 'sexuality' => '男' ],
[ 'No' => '2', 'name' => '花子', 'score' => '80', 'sexuality' => '女' ],
[ 'No' => '3', 'name' => '次郎', 'score' => '35', 'sexuality' => '男' ],
[ 'No' => '4', 'name' => 'みか', 'score' => '70', 'sexuality' => '女' ],
[ 'No' => '5', 'name' => 'ジョン', 'score' => '67', 'sexuality' => '男' ],
[ 'No' => '6', 'name' => 'ステファニー', 'score' => '96', 'sexuality' => '女' ],
];
$result = array_filter( $table, function( $row ){
if ( '男' === $row[ 'sexuality' ] ) {
return true;
} else {
return false;
}
});
var_export( $result );
array (
0 =>
array (
'No' => '1',
'name' => '太郎',
'score' => '56',
'sexuality' => '男',
),
2 =>
array (
'No' => '3',
'name' => '次郎',
'score' => '35',
'sexuality' => '男',
),
4 =>
array (
'No' => '5',
'name' => 'ジョン',
'score' => '67',
'sexuality' => '男',
),
)
コールバック関数(ここでは無名関数)内で、いろいろな条件の組み合わせができます。
複数条件
AND条件
OR条件
データベースSQLのWHERE句みたいなものですが、『それなりの条件を作るならSQL使うほうがよくね?』と個人的には思います。
(ファイル管理のデータなどでは使う場面がある。あとDB負荷をかけたくないときとか。)
もちろん、1件のデータを取得するのにも使えます。そうなるとarray_search()は、いらないっちゃ、いらないですね?
サンプル - 平均点以上のメンバーを出す
さいごに、平均点以上のメンバーを取り出してみましょう。PHPには配列データの合計を出す関数もあるのでかんたんです。
<?php
$table = [
[ 'No' => '1', 'name' => '太郎', 'score' => '56', 'sexuality' => '男' ],
[ 'No' => '2', 'name' => '花子', 'score' => '80', 'sexuality' => '女' ],
[ 'No' => '3', 'name' => '次郎', 'score' => '35', 'sexuality' => '男' ],
[ 'No' => '4', 'name' => 'みか', 'score' => '70', 'sexuality' => '女' ],
[ 'No' => '5', 'name' => 'ジョン', 'score' => '67', 'sexuality' => '男' ],
[ 'No' => '6', 'name' => 'ステファニー', 'score' => '96', 'sexuality' => '女' ],
];
$score = array_column( $table, 'score');
$sum = array_sum( $score );
$avg = $sum / count( $table ) ;
$result = array_filter( $table, function( $row ) use ( $avg ) {
if ( $avg <= $row[ 'score' ] ) {
return true;
} else {
return false;
}
});
echo 'average:' . round( $avg, 2 ) . PHP_EOL;
var_export( $result );
average:67.33
array (
1 =>
array (
'No' => '2',
'name' => '花子',
'score' => '80',
'sexuality' => '女',
),
3 =>
array (
'No' => '4',
'name' => 'みか',
'score' => '70',
'sexuality' => '女',
),
5 =>
array (
'No' => '6',
'name' => 'ステファニー',
'score' => '96',
'sexuality' => '女',
),
)
適当にデータを作ったんですけど、男はアホばっかりになっちゃいました。
『array_****()の関数よりもシンプルなループ処理のほうが速い』という、ベンチマークテスト結果つきで公開してくれてる素晴らしい情報もあります。
ボクは、array_****()を多用(とくに入れ子で多く使う)くらいなら、SQLクエリを使ってDBにおまかせする派です。