最近仕事がヒマだったせいか、くだらない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プログラマはいないよな(笑) まあいっか。