最近仕事がヒマだったせいか、くだらないPHPプログラムをいろいろ作ったんだけど。
ActiveRecordAnywhereクラスです。
といっても、そんなクラスは一度も呼ばないです。
DAOを超自動生成します。超自動です。
どれくらい自動かというと、1個requireするだけ。テーブル定義もなにも必要ないです。
あとはDBにテーブル作って、PDOオブジェクトを生成して、
$hoge = hoge::find($pdo , 'id = ?' , array($id));
いきなりそんなクラスがあるような顔でテーブル名のクラスのfind()という静的メソッドにWHERE句を投げると、hogeオブジェクトが配列で返ってきます。
あとは
$hogeName = $hoge$_lb0$_rb->name;
みたいにフィールドの値を取得したり
$hoge$_lb0$_rb->name = 'piyo';
とかでいろいろ値をセットしてから
$hoge$_lb0$_rb->update();
$hoge$_lb0$_rb->insert();
$hoge$_lb0$_rb->delete();
とかでDB更新みたいな。ふつうのアクティブレコードですね。
そんなクラスがあるような顔で継承とかもできるはず。
ちょーっと貼りつけるには長いですが。
<?php
function __autoload($class) {
$classBody = "
class {$class} extends ActiveRecordAnywhere {
protected \$table = '{$class}';
public static function find
(&\$pdo , \$where , \$params = array()) {
\$sql = \"SELECT * FROM {$class} WHERE \$where\";
\$sth = \$pdo->prepare(\$sql);
\$sth->execute(\$params);
\$ret = array();
while(\$row = \$sth->fetch(PDO::FETCH_ASSOC)) {
\$ret[] = new self(\$pdo , \$row);
}
return \$ret;
}
}";
eval($classBody);
}
class ActiveRecordAnywhere {
protected $pdo;
protected $row;
protected $where;
public $DBCharCode = 'UTF-8';
public function __construct(&$pdo , $row = array()) {
$this->pdo = &$pdo;
$this->row = $row;
$this->_init();
}
public function __set($aname , $avalue) {
$this->row[$aname] = mb_convert_encoding(
$avalue , $this->DBCharCode , mb_internal_encoding());
}
public function __get($aname) {
return mb_convert_encoding($this->row[$aname]
, mb_internal_encoding() , $this->DBCharCode);
}
public function insert() {
$sql = "INSERT INTO {$this->table}("
. join(" , " , array_keys($this->row)). ")"
. " VALUES (" . join(',' , array_fill(0 , $c , '?')) . ")";
$sth = $this->pdo->prepare($sql);
$sth->execute(array_values($this->row));
$this->_init();
$this->id = @$this->pdo->lastInsertId();
return $id;
}
public function update() {
$sql = "UPDATE {$this->table} SET ";
$set = array();
foreach($this->row as $k => $v) {
$set[] = "{$k} = ?";
$sqlParams[] = $v;
}
$sql .= join(',' , $set) . " WHERE " . $this->where;
$sth = $this->pdo->prepare($sql);
$sth->execute($sqlParams);
$affectedRows = $sth->rowCount();
$this->_init();
return $affectedRows;
}
public function delete() {
$sql = "DELETE FROM {$this->table} WHERE {$this->where}";
$sth = $this->pdo->prepare($sql);
$sth->execute();
$affectedRows = $sth->rowCount();
unset($this->row);
$this->_init();
return $affectedRows;
}
protected function _init() {
$wheres = array();
foreach($this->row as $k => $v) {
$wheres[] = "$k = " . $this->pdo->quote($v);
}
$this->where = join(' AND ' , $wheres);
}
}
?>
ぜんぜんちゃんと書いてないので、このままだといろいろ問題ある気がしますが。
ようするにあれだ。PHP5の謎機能__autoload()(←知らないクラスが呼ばれたら勝手に呼ばれる謎関数)で、クラスをeval生成です。
あと、知らないメンバ変数にアクセスすると勝手に呼ばれる謎メソッド__get()と__set()も使ってますねー。
冗談なのでちゃんと書いてないし、このまま使うのはやめたほうがいいけど。こんなんでも、データアクセス層がないよりはマシだと思うんだ……。
で、そんなことやっててすごく思うんだが、きっとこのサイト見る人にPHPプログラマはいないよな(笑) まあいっか。