ログ日記

作業ログと日記とメモ

O/RマッパーとビューをトリガにしたイテレータでDB接続

$map =
array('voPropertyName' => 'tableColumnName',
      ...
     );

という配列があるとき

$bind = array();
// $stmt = PDOStatement
foreach ($map as $key => $value){
    $binds[$key] = $$key = null;
    $stmt->bindColumn($value, $binds[$key]);
}


このようにbindする。
そうすると$bindを使ってORM用の変数名に対応した値をforeachで表示できる。



何がしたかったかというと、DBから100件のデータを取得する場合に、普通なら一度配列やオブジェクトに100件の値を格納する。
そしてビュークラスでforeachを使って順次出力する。

  1. DBから取得したデータを配列(オブジェクト)に格納
  2. 配列(オブジェクト)からforeachで出力

ループを二回繰り返しているので、その回数を減らしたかった。
そのためにイテレータを用意し

public function rewind(){
    $this->value = $this->dao->getBind($this->stmt); // 上記コードの$bindが返る
    $this->isContinue = $this->stmt->fetch(PDO::FETCHBOUND);
}

public function current(){
    return $this->value;
}

public next(){
    $this->isContinue = $this->stmt->fetch(PDO::FETCH_BOUND);
}

public function valid(){
    return $this->isContinue;
}

このクラスに対してforeachを行うことによって、foreachの中でDBに接続して一行取得する処理を行う。



副作用のある処理を遅延評価してる感覚なのでforeachでトランザクションを完結しなければならないし、ビジネスロジックの順序に依存する処理は行えない。しかしDBのデータを単純に一覧する機会は多いので、foreachを減らすことによって速度アップをはかっている。もちろん表示用の単純なエスケープ処理はFlexyがやってくれるし、個別の処理をイテレータに書いても良い。
複雑なエラー処理をしたい場合などにも向いていないが、ちゃんと実装すれば複雑な処理もイテレータで書けるかも。