PHPでMySQLを使う - PHP入門
目次
- PHP入門
- PHPの概要
- PHP環境のインストール(XAMPP)・PHPの設定
- PHPの基本・簡単なプログラム
- 文法1
- 文法2
- 様々な関数を使う
- フォームの基本
- システム作成
- オブジェクト指向
- データベースとSQL
- PHPでMySQLを使う
- ブログを作る
- ECサイト(ショッピングサイト)を作る
このページの内容
はじめに
この章ではPHPからMySQLのデータベースを操作する方法を解説します。PDO(PHP Data Objects)クラスを使うと、簡単に汎用的なデータベースアクセスのコードを書くことができます。
レコードの表示はテーブルなどで行をループして行い、レコードの挿入・更新はフォームを介して行うのが一般的です。
データベースの準備
この章では前章の「men」データベースと「udon」テーブルをそのまま使います。もしmenデータベースが無ければ、phpMyAdminを立ち上げ、SQLタブから以下のSQL文を発行してください。データベース・テーブル・レコードが一気に作成されます。レコードの内容は適当でかまいません。
CREATE DATABASE men;
USE men;
CREATE TABLE udon(name TEXT, price INT);
INSERT INTO udon VALUES('たぬきうどん', 340);
INSERT INTO udon VALUES('てんぷらうどん', 440);
INSERT INTO udon VALUES('カレーうどん', 420);
INSERT INTO udon VALUES('うどん定食', 520);
「USE」はデータベースを選択するSQL文です。これを書かないと、それ以下のCREATE TABLE文やINSERT文が対象にしているデータベースが判別できないのでエラーになります。レコードの表示
データベースが用意できたら、以下のソースを入力してブラウザで確認してみてください。udonテーブルに登録してあるレコードの一覧が表示されます。udon_list.php
<table border="1">
<tr><th>名前</th><th>価格</th></tr>
<?php
$pdo = new PDO("mysql:dbname=men", "root");
$st = $pdo->query("SELECT * FROM udon");
while ($row = $st->fetch()) {
$name = htmlspecialchars($row['name']);
$price = htmlspecialchars($row['price']);
echo "<tr><td>$name</td><td>$price 円</td></tr>";
}
?>
</table>
PDOについて
PHPからMySQLのデータベースを扱うにはたくさんの方法があり、どれを選択するかは時と場合によるのですが、今回は汎用性が高くて高速な「PDO」クラスを使います。PDOを使ってデータベースを操作する際の基本的な流れは「PDOオブジェクトの作成」→「SQLの発行」→「結果レコードの参照」になります。
レコードの表示プログラムの解説
$pdo = new PDO("mysql:dbname=men", "root");
PDOオブジェクトの作成を行っています。第1引数で接続するためのDSNを指定します。DSNとはデータベースに接続するために必要な情報で、データベース名・ホスト名・ポート番号などが含まれます。MySQL DSN構文
mysql:dbname=データベース名;host=ホスト名;port=ポート番号
ここではデータベース名のみ指定して、その他は省略してデフォルト値を使っています。省略するとホスト名は「localhost」、ポート番号は「3306」になります。第2引数でデータベース接続のID、第3引数でデータベース接続のパスワードを指定します。XAMPPインストール時のデフォルトIDは「root」、パスワードは無しです。ローカルで試すとき以外は、必ずIDとパスワードを設定してください。
DSNは開発サーバと本番サーバで変わることが多いでしょう。例えば、本番サーバのデータベースホストが「db.example.com」、データベース名が「db」、接続IDが「user」、接続パスワードが「pass」だった場合、以下のように書きます。
$pdo = new PDO("mysql:dbname=db;host=db.example.com", "user", "pass");
$st = $pdo->query("SELECT * FROM udon");
ここでSQL文の発行を行います。PDOクラスのqueryメソッドでSQLの発行ができます。戻り値としてPDOStatementクラスのオブジェクトが返ります。PDOStatementクラスは「結果セット」という、SQL実行の結果を所持します。
while ($row = $st->fetch()) {
$name = htmlspecialchars($row['name']);
$price = htmlspecialchars($row['price']);
echo "<tr><td>$name</td><td>$price 円</td></tr>";
}
結果セットからレコードを一行取得します。PDOStatementクラスのfetchメソッドは、結果セットの先頭から一行ずつ順番に取得します。最後の行まで達して、取得できるデータが無くなったらfalseが返るので、ループを抜けます。fetchメソッドの戻り値は、カラム名をキーとした連想配列になります。$row['name']にnameカラムの値、$row['price]にpriceカラムの値が入るわけです。
レコードの挿入
次にレコードの挿入ですが、ウェブアプリっぽく、フォームから挿入してみましょう。udon_insert.html
<form action="udon_insert.php" method="post">
名前<br>
<input type="text" name="name"><br>
価格<br>
<input type="text" name="price"><br>
<input type="submit">
</form>
udon_insert.php
<?php
$pdo = new PDO("mysql:dbname=men", "root");
$st = $pdo->prepare("INSERT INTO udon VALUES(?,?)");
$st->execute(array($_POST['name'], $_POST['price']));
?>
レコードを追加しました。
udon_insert.htmlを開くとフォームが現れ、POSTメソッドで名前(name)と価格(price)のデータが送られます。udon_insert.phpはフォームから送られたデータを受け、udonテーブルに挿入します。登録したら、udon_list.phpを開いて登録したデータが反映されているか確認してみてください。
レコードの挿入プログラムの解説
$st = $pdo->prepare("INSERT INTO udon VALUES(?,?)");
prepateメソッドでSQL文を「準備」します。発行はまだしません。「?」は、後から値を入れるために、とりあえず仮に置いておくものです(「プレースホルダ」と言います)。
$st->execute(array($_POST['name'], $_POST['price']));
executeメソッドで、実際にSQL文を発行します。引数で配列を受け取り、先ほど準備したSQL文の「?」に配列の先頭から値を入れて行きます。ここでは最初の「?」にフォームの名前欄に入力した文字列、次の「?」に価格欄に入力した文字列が入ります。レコードを挿入する場合にqueryメソッドを使うこともできます。その場合は
$pdo->query("INSERT INTO udon VALUES('{$_POST['name']}',{$_POST['price']})");
このように直接フォームの値をセットしますが、「SQLインジェクション」という攻撃を受ける可能性があるので、prepareとexecuteメソッドを使うようにしてください。レコードの更新
レコードの更新は、まず「どの」レコードを更新するのか、という情報が必要です。そのために、レコードの一覧(udon_list.php)を以下のように変更してudon_list2.phpの名前で保存してください。udon_list2.php
<table border="1">
<tr><th>名前</th><th>価格</th><th>操作</th></tr>
<?php
$pdo = new PDO("mysql:dbname=men", "root");
$st = $pdo->query("SELECT * FROM udon");
while ($row = $st->fetch()) {
$name = htmlspecialchars($row['name']);
$price = htmlspecialchars($row['price']);
echo "<tr><td>$name</td><td>$price 円</td><td><a href='udon_update.php?name=$name'>修正</a></td></tr>";
}
?>
</table>
修正部分は以下の2行です。
<tr><th>名前</th><th>価格</th><th>操作</th></tr>
echo "<tr><td>$name</td><td>$price 円</td><td><a href='udon_update.php?name=$name'>修正</a></td></tr>";
次に、修正フォームを表示するプログラムを以下に示します。udon_update.php
<?php
$name = htmlspecialchars($_GET['name']);
$pdo = new PDO("mysql:dbname=men", "root");
$st = $pdo->prepare("SELECT * FROM udon WHERE name=?");
$st->execute(array($name));
$row = $st->fetch();
$price = htmlspecialchars($row['price']);
?>
<form action="udon_update2.php" method="post">
名前<br>
<input type="text" name="name" value="<?php echo $name ?>"><br>
価格<br>
<input type="text" name="price" value="<?php echo $price ?>"><br>
<input type="hidden" name="old_name" value="<?php echo $name ?>">
<input type="submit">
</form>
次に、実際にレコードを修正するプログラムを以下に示します。udon_update2.php
<?php
$pdo = new PDO("mysql:dbname=men", "root");
$st = $pdo->prepare("UPDATE udon SET name=?,price=? WHERE name=?");
$st->execute(array($_POST['name'], $_POST['price'], $_POST['old_name']));
?>
レコードを修正しました。
それぞれの行の「修正」リンクからレコードを修正できることを確認してみてください。udon_list2.phpの解説
各行の「修正」リンクはudon_update.phpにジャンプするものですが、その際にGETパラメータ「name」にレコードのnameカラムの値を渡しています。
echo "<tr><td>$name</td><td>$price 円</td><td><a href='udon_update.php?name=$name'>修正</a></td></tr>";
このパラメータによって、受け取った側で修正すべきレコードを判別することができるのです。udon_update.phpの解説
修正するレコードの値をフォームに表示して変更できるようにしています。
$name = htmlspecialchars($_GET['name']);
「修正」リンクから受け取ったnameカラムの値を変数$nameに代入します。
$st = $pdo->prepare("SELECT * FROM udon WHERE name=?");
$st->execute(array($name));
$row = $st->fetch();
$nameの値をもとに修正すべきレコードのデータを取得しています。
名前<br>
<input type="text" name="name" value="<?php echo $name ?>"><br>
価格<br>
<input type="text" name="price" value="<?php echo $price ?>"><br>
value属性の値として修正すべきレコードの値をセットしています。
<input type="hidden" name="old_name" value="<?php echo $name ?>">
隠しフィールド「old_name」として修正前のnameカラムの値をセットしています。udon_update2.phpの解説
$st = $pdo->prepare("UPDATE udon SET name=?,price=? WHERE name=?");
$st->execute(array($_POST['name'], $_POST['price'], $_POST['old_name']));
フォームから送られたカラムの値をもとにUPDATE文でレコードを更新します。隠しフィールドold_nameによって修正すべきレコードを判別しています。レコードの削除
レコードの削除も、更新と同じく「どの」レコードを削除するのか、という情報が必要です。そのために、レコードの一覧(udon_list2.php)を以下のように変更してudon_list3.phpの名前で保存してください。udon_list3.php
<table border="1">
<tr><th>名前</th><th>価格</th><th>操作</th></tr>
<?php
$pdo = new PDO("mysql:dbname=men", "root");
$st = $pdo->query("SELECT * FROM udon");
while ($row = $st->fetch()) {
$name = htmlspecialchars($row['name']);
$price = htmlspecialchars($row['price']);
echo "<tr><td>$name</td><td>$price 円</td><td><a href='udon_update.php?name=$name'>修正</a> <a href='udon_delete.php?name=$name' onclick=\"return confirm('削除してよろしいですか?')\">削除</a></td></tr>";
}
?>
</table>
修正部分は以下の1行のみです。
echo "<tr><td>$name</td><td>$price 円</td><td><a href='udon_update.php?name=$name'>修正</a> <a href='udon_delete.php?name=$name' onclick=\"return confirm('削除してよろしいですか?')\">削除</a></td></tr>";
次に、実際にレコードを削除するプログラムを以下に示します。udon_delete.php
<?php
$pdo = new PDO("mysql:dbname=men", "root");
$st = $pdo->prepare("DELETE FROM udon WHERE name=?");
$st->execute(array($_GET['name']));
?>
レコードを削除しました。