データベースクラスを作成するぞ - vol.5

#まえがき
少し時間が空いてしまい、前回までのコードを見ても
いまいちピンとこないんですが…。（汗
えーっと、何がどうだったっけ？？

うーむ。。。
とにかく一連の流れの、復習とか修正とかをやってみる。

#前回からの復習と修正
```php:
// DB::getInstance()->select("users", array("username", "=", "tarou"));

// 1) ここからスタートして… 
public function select($table, $where = array()) {
    return $this->action1('SELECT *', $table, $where);
}

// 2) 上の select() が action1() を呼び出し…
public function action1($action, $table, $where = null) {
    if(!empty($where) {

        $field = $where[0];
        $operator = $where[1];
        $value = $where[2];

        $sql = "{$action} FROM {$table} WHERE {$field} {$operator} ?";
        return $this->action2($sql, array($value));
    } else {
        echo '$where に何も入ってないよ!!';
        // エラーにするべきか…そのまま通す方法も…
    }
}

// 3) 最後に action2 を呼び出すと…
public function action2($sql, $value = array)) {
    $stmt = $this->_pdo->prepare($sql);
    $num = 1;
    if(count($value)) {
        foreach($value as $val) {
            $stmt->bindValue($num, $val);
            $num++;
        }
    }
    if($stmt->execute()) {
        // 新たなプロパティ $_results 作成する。
        $this->_results = $stmt->fetchAll(PDO::FETCH_OBJ);
        // 取得は FETCH_OBJ か FETCH_CLASS が良いの？
        // そんな事を風の噂で耳にしまして…
    }

    return $this;
}

// 4) $_results は private の予定なので取得メソッド
public function results() {
    return $this->_results;
}
```

と、まあ、こんな感じで。（大丈夫かな…動くよね…？

#insertメソッドの作成

さて、次は insert に挑戦してみようかなー、と。
コイツが多分、一番めんどいと思われる。
（ただただ、配列が苦手な奴ってだけなんですけど…

ま、そうは言っても、感覚的には action1() とかと似た感じ…なはず。
分解・組立していく部分で、躓かなければきっと大丈夫！ww

##考察

例えば、action1() でいうとこの $action は、
"INSERT INTO" 確定なので必要なし。

$table は必ず必要。（おいおい、どこに入れるんだよー？ってことになるからねww

$where の条件指定だった部分が、insert のメイン部分で
複数分（カラム数）必要になるので、array() で渡す。

なおかつ、array() の **$key(キー)** と **$value(値)** 部分で、

* $key = フィールド名
* $value = 挿入する値

となれば、insert しやすい。よね？（…自信薄
だから最終的には、

```php:
$sql = "INSERT INTO {$table} ({$key}) VALUES ({?, ?, ?})";
$value = insert 予定の配列 (複数の $key => $value);
```

こんな感じで action2() へ渡して execute() したいということ。

##DBクラス - insert部分の作成
ちなみに、先ほど言った通り **"配列がちょーっと苦手な奴"** が作成してくので、
ここからは **細かく区切って** 進んでいくので、あしからず…。

```php:DBクラス(insert)
/*
    DB::getInstance()->insert('users', array(
        'name' => 'tarou',
        'email' => 'tarou@example.com',
        'password' => 'password1234'
    ));
    のような呼び出し方を想定。
*/

public function insert($table, $field = array()) {

    // 現状、思いつく最終地点はこんな感じ。
    $sql = "INSERT INTO {$○○○} ({$○○○}) VALUES ({$○○○})";

    // ま、テーブルは確定しているので…
    $sql = "INSERT INTO {$table} () VALUES ()";

    // で、配列から 'キー' を取って当てはめる
    $keys = array_keys($field);
    $sql = "INSERT INTO {$table} (" . implode(', ', $keys) . ") VALUES ()";

    // 現状の $sql を分解すると…
    $sql = "INSERT INTO users (username, email, password) VALUES ()"

    // VALUES の ()内には、以前に言っていたように
    // "?"を使って、疑問符プレースホルダを使いたい。
    // （この後 action2() へ飛ばすことを想定。）

    // まず入れ物を用意して、そこへ foreach() で $field 内の数だけループ
    // その際 "?" を入れていくループの中で、
    // next() 関数を使って "最後だけ" 処理を抜ける。
    $val = '';
    foreach($field as $fid) {
        $val .= '?';
        if(next($field)) {
            $val .= ', ';
        }
    }

    // $val の中身はというと…
    $val = '?, ?, ?';
    // となっているので、このまま $sql にぶち込む。

    $sql = "INSERT INTO {$table} (" . implode(', ', $keys) . ") VALUES ({$val})";

    // ラスト、action2() の呼び出し。
    if($this->action2($sql, $field)) {
        return true;
    }

    return false;
}
```

後になると、そんなに難しいことしてないのに
ムチャクチャ疲れるんですよね。…配列は。

$val = '?, ?, ?' の疑問符部分では
案の定、詰まってしまいました。
next() なんて初めて見ましたよ！

なんとか動いたので、今回は
ひとまずOKとさせてくださいww

###今回、作成にあたって参考にしたページ

>・[PHPマニュアル : array_keys](http://php.net/manual/ja/function.array-keys.php)
・[PHPマニュアル : implode]
(http://php.net/manual/ja/function.implode.php)
・[オンズ : 【PHP】ループ処理［foreach］で最後だけ違う処理をする方法。]
(http://on-ze.com/archives/1914)

#あとがき
ひとつ、気になっていることが…

**エラー処理** 的なこと。してないよね…。
（今さらそんなとこに気づくww）
つーか今回に限らず、今までも。だよね。

うーむ。どういった方法が、スマートな方法でしょうかねー。