普通にphp-mysqliを使ってCRUDするコード例

公開: 2009年06月04日01時, 最終更新: 2009年06月04日01時

普通にMysqliを使ってみます。特別なネタがあるわけではありません。リファレンスが分かりにくいという声を近くで聞いたので、まあだいたいこんな風にすれば良いんじゃない? というのをメモとして残しておきます。

個人ユースのデータベースといえばやはり住所録ということで、これにデータを出し入れする部分だけMysqliを使って書いてみます。住所録のデータスキームはこんな感じ:

create table addresses(
    id int unsigned not null primary key auto_increment,
    name varchar(32) not null,
    kana varchar(64) not null,
    zipcode char(8) not null,
    address1 varchar(64) not null,
    address2 varchar(64) not null,
    tel char(13) not null,
    email varchar(255) not null,
    index(kana)
);

IDを指定してデータを取得する関数は、だいたいこんな感じに書ける (実際はもっとまじめにエラー処理とかすべき):

// インスタンス変数として$con = new Mysqli("ホスト名", "ユーザ名", "パスワード", "データベース名");が存在することを前提としている。以下同様
function getAddressById($id) {
    $result = array();
    $sql = "select name, kana, zipcode, address1, address2, tel, email from addresses where id = ?";
    $stmt = $this->con->prepare($sql);
    $stmt->bind_param("i", $id);
    $stmt->execute();
    $stmt->bind_result($name, $kana, $zipcode, $address1, $address2, $tel, $email);
    if($stmt->fetch()) {
        $result = compact("id", "name", "kana", "zipcode", "address1", "address2", "tel", "email");
    }
    $stmt->close();
    return $result;
}

1ページに20件表示させるとして、その20件分を持ってくる関数はこんな感じに書ける:

// $page: ページ数。最初のページは1
function getAddresses($page, $limit = 20) {
    $result = array();
    $sql = "select id, name, kana, zipcode, address1, address2, tel, email from addresses order by kana limit ?, ?";
    $offset = ($page - 1) * $limit;
    $stmt = $this->con->prepare($sql);
    $stmt->bind_param("ii", $offset, $limit);
    $stmt->execute();
    $stmt->bind_result($id, $name, $kana, $zipcode, $address1, $address2, $tel, $email);
    while($stmt->fetch()) {
        $result[] = compact("id", "name", "kana", "zipcode", "address1", "address2", "tel", "email");
    }
    $stmt->close();
    return $result;
}

指定したカナに前方一致するものを取得したいならこんな感じ:

function getAddressesByKana($kana, $page, $limit = 20) {
    $result = array();
    $sql = "select id, name, kana, zipcode, address1, address2, tel, email from addresses where kana like ? order by kana limit ?, ?";
    $offset = ($page - 1) * $limit;
    $like = "{$kana}%";
    $stmt = $this->con->prepare($sql);
    $stmt->bind_param("sii", $like, $offset, $limit);
    $stmt->execute();
    $stmt->bind_result($id, $name, $kana, $zipcode, $address1, $address2, $tel, $email);
    while($stmt->fetch()) {
        $result[] = compact("id", "name", "kana", "zipcode", "address1", "address2", "tel", "email");
    }
    $stmt->close();
    return $result;
}

新しいエントリを挿入するのはこんな感じ:

// $addressはnameやkanaなどのキーがある連想配列
function insert($address) {
    $result = 0;
    $sql = "insert into addresses(name, kana, zipcode, address1, address2, tel, email) values(?,?,?,?,?,?,?)";
    $stmt = $this->con->prepare($sql);
    $stmt->bind_param("sssssss", $name, $kana, $zipcode, $address1, $address2, $tel, $email);
    extract($address, EXTR_OVERWRITE);
    $stmt->execute();
    $result = $this->con->insert_id;
    $stmt->close();
    return $result;
}

まとめて挿入するなら:

// $addressesはnameやkanaなどのキーがある連想配列の配列
function insertAll($addresses) {
    $result = array();
    $sql = "insert into addresses(name, kana, zipcode, address1, address2, tel, email) values(?,?,?,?,?,?,?)";
    $stmt = $this->con->prepare($sql);
    $stmt->bind_param("sssssss", $name, $kana, $zipcode, $address1, $address2, $tel, $email);
    foreach($addresses as $address) {
        extract($address, EXTR_OVERWRITE);
        $stmt->execute();
        $result[] = $this->con->insert_id;
    }
    $stmt->close();
    return $result;
}

更新するなら:

function update($address) {
    $sql = "update addresses set name = ?, kana = ?, zipcode = ?, address1 = ?, address2 = ?, tel = ?, email = ? where id = ?";
    $stmt = $this->con->prepare($sql);
    $stmt->bind_param("sssssssi", $name, $kana, $zipcode, $address1, $address2, $tel, $email, $id);
    extract($address, EXTR_OVERWRITE);
    $stmt->execute();
    $stmt->close();
}

ついでに削除:

function delete($id) {
    $sql = "delete from addresses where id = ?";
    $stmt = $this->con->prepare($sql);
    $stmt->bind_param("i", $id);
    $stmt->execute();
    $stmt->close();
}

function deleteAll($id_list) {
    $sql = "delete from addresses where id = ?";
    $stmt = $this->con->prepare($sql);
    $stmt->bind_param("i", $id);
    foreach($id_list as $id) {
        $stmt->execute();
    }
    $stmt->close();
}

実際はフレームワークとかでささっとやってしまう部分かもしれませんが、あえてフルスクラッチするならこんな感じでしょうか。