遊星ゲームズ
FrontPage | RSS


DAOを超自動生成
 プログラム

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


DAOを超自動生成を