m6uのエンジニアっぽい日記

PHP利用開発やFuelPHP利用開発、PostgreSQL利用開発、Androidアプリ開発、CentOS7サーバー構築など、テクニカルでエンジニアっぽい内容の日記

疑問:配列を関数のように使いたい、その下ごしらえを効率化したい→as_object()を試す

今回の疑問

今日もFuelPHPPostgreSQLシステム開発しております。
 modelクラスで高度なSELECT文の実行結果を返すメソッドを書いてます。 例えばこんな感じ。

$sql = <<<EOT
SELECT a, b, c, x, y, z
FROM (
  SELECT … FROM  … 
) LEFT JOIN (
  SELECT … FROM  … 
);
EOT;
return DB::query($sql)->as_assoc()->execute();

 結果に含まれるa, b, cの取りうる範囲がそれぞれ違っていて、その値の範囲を表組みする前にチェックしておくのも大事で。
クエリー結果を単純に連想配列管理してしまうと、最終的に欲しいデータ(例でいうところのxやyやz)を簡単に取り出しにくくなるじゃないですか。
 たまたま、a, b, c が数値だったので、a~cを連結した文字列を作って個々の連想配列でx,y,zを管理しようと考えて、こんなふうにしました。

$dat_x = array();
$dat_y = array();
$dat_z = array();
foreach ($result as $rec)
{
  $dat_x[$rec['a'].'<>'.$rec['b'].'<>'.$rec['c'] = $rec['x'];
  $dat_y[$rec['a'].'<>'.$rec['b'].'<>'.$rec['c'] = $rec['y'];
  $dat_z[$rec['a'].'<>'.$rec['b'].'<>'.$rec['c'] = $rec['z'];
}

 これってcontrollerクラスの仕事なのかなぁ。
 こうやって加工したのを、viewクラスでループ変数で回して表組みするんですけど、効率よくする方法ってあるのかなぁ。

as_assoc()でなく、as_object()を試す

 アドバイス、いただきました。 ありがとうございます。 引用しちゃいます。


 そういえば、as_object()って試したことがなかった。 書き換えてみました。

$sql = <<<EOT
SELECT a, b, c, x, y, z
FROM (
  SELECT … FROM  … 
) LEFT JOIN (
  SELECT … FROM  … 
);
EOT;
return DB::query($sql)->as_object()->execute()->as_array();
$dat_x = array();
$dat_y = array();
$dat_z = array();
for ($i = 0; $i < count($result); $i++)
{
  $dat_x[$result[$i]->a.'<>'.$result[$i]->b.'<>'.$result[$i]->c = $result[$i]->x;
  $dat_y[$result[$i]->a.'<>'.$result[$i]->b.'<>'.$result[$i]->c = $result[$i]->y;
  $dat_z[$result[$i]->a.'<>'.$result[$i]->b.'<>'.$result[$i]->c = $result[$i]->z;
}

 クエリーの結果のカラム名(フィールド名)をプロパティとして利用できて、読みやすくなりました。
 これがもし、こうだったら。

$sql = <<<EOT
SELECT a || '<>' || b || '<>' || c as k, x, y, z
FROM (
  SELECT … FROM  … 
) LEFT JOIN (
  SELECT … FROM  … 
);
EOT;
return DB::query($sql)->as_object()->execute();

 モデル側でas_array()してないので、受けるコントローラー側でas_array()できますね、こうなります。

$dat_x = $result->as_array('k', 'x');
$dat_y = $result->as_array('k', 'y');
$dat_z = $result->as_array('k', 'z');

 コントローラー側で連結処理せずにクエリー結果上で連結させてしまえば、連想配列として管理するのは簡単になりますね。
 ただ、これをやってしまうと、クエリー結果からaやbやcの値の範囲をチェックすることができなくなる。 何かもう一工夫必要な感じに。