PHPからデータベースに接続するには、PHPで用意されたAPIを使用します。 PHPからMySQLに接続するためのAPIは3つ用意されています。mysql関数とmysqli、PDOです。
今回はPDOを利用してMySQLに接続してみたいと思います。
従前の方法
データベースへの接続方法として、従前はmysql関数を使用されることがよくありました。 mysql関数がよく利用された理由としては、mysql関数だとプログラムが簡単に記載できるからです。
$con = mysql_connect('ホスト名','ユーザー名','パスワード') or die('接続失敗'); print '接続成功'; mysql_select_db('データベース名'); //処理を記載 mysql_close($con);
上記のようにmysql関数を使用すれば、簡単に接続することができるのですが、mysql関数を使用したMySQLへの接続は、PHP 5.5.0では非推奨になり、PHP7.0.0では削除されました。
ですので、通常PHPからMySQLを使用する場合は、mysqliかPDOを使用します。
※どちらを利用するかについては下記をご覧ください。
PDOとは
この記事では、PDOを使ってMySQLに接続する方法を扱いたいと思います。 PDOはPHP5.1.0から使用できます。
PDOはPHP Data Objectの略で、データベースを操作するためのメソッドが用意されたクラスのことです。
ですので、mysql関数とは異なり、PDOを利用してデータベースを操作するには、PDOクラスからインスタンスを生成し、その上で、PDOクラスのメソッドを利用し、データベースを操作します。
それと、これがPDOの最大の特徴なのですが、PDOは他のAPI(mysql関数・mysqli)とは違い、MySQL以外のデータベースも操作することができます。具体的にはドライバを切り替えることで、MySQL以外のデータベースとも接続できます。こういった仕組みをデータベース抽象化レイヤーといいます。
それぞれのデータベースへ接続する手順を抽象化し、ドライバを切り替えるだけで、PHPとそれぞれのデータベースの間に入り、それぞれの差異を吸収してくれる便利な仕組みです。
PDOでの接続方法について
では、さっそくPDOでの接続方法について説明します。
たとえば、下記のような顧客情報を格納しているテーブルがあるとします。 フィールドは3つで、「username」「age」「email」で構成されています。 それぞれ「ユーザーの名前」「年齢」「Emailアドレス」が格納されています。
username | age | |
---|---|---|
田中 | 26 | tanaka@no-title.com |
山崎 | 34 | yamasaki@no-title.com |
佐藤 | 47 | sato@no-title.com |
そのデータベースに対して、新しいユーザーを追加する場合を考えてみましょう。 新しいユーザーの情報(username・age・email)は入力フォームからPOST送信されるとします。
細かい話は後回しにしてとりあえずプログラムだけ記述すると下記のようになります。
try { $pdo = new PDO('mysql:host=ホスト名;dbname=データベース名;charset=utf8','ユーザ名','パスワード', array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false, ); $stmt = $pdo -> prepare("INSERT INTO member (username,age,email) VALUES(:username,:age,:email)"); $stmt->bindValue(':username', $_POST['username'], PDO::PARAM_STR); $stmt->bindValue(':age', $_POST['age'], PDO::PARAM_INT) $stmt->bindValue(':email', $_POST['email'], PDO::PARAM_STR); $stmt->execute(); } catch (PDOException $e) { exit('接続失敗:'.$e->getMessage()); }
プログラムの解説
1.PDOクラスからインスタンスを生成
PDOを使用してデータベースに接続するには、 最初にPDOクラスからインスタンスを作成する必要があります。
インスタンスを作成するにはnew演算子を使用します。 new演算子を使用すると、PDOクラスのコンストラクタが呼び出され、インスタンスを生成します。具体的には下記のように記載します。
$pdo = new PDO('DSN','ユーザー名','パスワード',オプション);
引数にはDSN・ユーザー名・パスワード・オプションを指定します。
DSNとは「Data Source Name」の略で、データベースのホスト名、データベース名、文字エンコードを指定します。MySQLの場合は、下記のように記載します。
mysql:host=;dbname=;charset=
オプションは連想配列で指定します。
属性名 => 属性値という形で設定します。
オプションはコンストラクタで指定せずに、後からPDO::setAttributeメソッドで設定することもできますが、コンストラクタでしか設定できないオプションもあります。
array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false, );
詳しく見ていきましょう。 まず、属性「PDO::ATTRERRMODE」に「PDO::ERRMODEEXCEPTION」という値をセットしています。 これはエラーが発生した場合について設定しています。 「PDO::ATTRERRMODE」を「PDO::ERRMODEEXCEPTION」にすると、エラーが発生すると、PDOExceptionの例外を投げてくれるようになります。 デフォルトだと「PDO::ERRMODE_SILENT」が設定されているので、エラーが表示されても何も表示されません。
属性「PDO::ATTREMULATEPREPARES」にfalseをセットしています。 falseにすることで、プリペアドステートメントのエミュレート機能をオフにします。
逆にtrueにすると、プリペアドステートメントのエミュレート機能が動作し、動的プレースホルダとして動作するようになります。
エミュレート機能を使用するかしないかには一長一短がありますが、今回は使用しないことにしたいと思います。
詳しくは下記の記事がオススメです。
2.プリペアドステートメントを準備
では、続いてデータベースにデータを入力してみたいと思います。
まずは、PDO::prepareメソッドを利用し、SQL文を実行する準備を行い、返り値としてステートメントハンドラを受け取ります。
$stmt = $pdo -> prepare();
SQL文についてですが、固定的なSQL文ではなく、ユーザーの入力によって動的なSQL文を実行する場合は、プリペアドステートメントとプレースホルダを使用する必要があります。
プリペアドステートメントとはSQL文のテンプレートのようなものです。
SQL文とユーザーの入力などにより取得した値を区別するためにプレースホルダを利用します。
プレースホルダには2種類あり、疑問符プレースホルダと名前付きプレースホルダがあります。
実際にみてみましょう。
//疑問符プレースホルダ INSERT INTO member (username,age,email) VALUES(?,?,?) //名前付きプレースホルダ INSERT INTO member (username,age,email) VALUES(:username,:age,:email)
3.取得した値をバインドさせる
次に、プレースホルダとユーザーの入力などにより取得した値を結びつける(バインド)必要があります。
値をバインドするには、PDOStatement::bindValueメソッドを利用します。
//疑問符プレースホルダの場合 $stmt->bindValue(1, $_POST['username'], PDO::PARAM_STR); $stmt->bindValue(2, $_POST['age'], PDO::PARAM_INT) $stmt->bindValue(3, $_POST['email'], PDO::PARAM_STR); //名前付きプレースホルダの場合 $stmt->bindValue(':username', $_POST['username'], PDO::PARAM_STR); $stmt->bindValue(':age', $_POST['age'], PDO::PARAM_INT) $stmt->bindValue(':email', $_POST['email'], PDO::PARAM_STR);
PDOStatement::bindValueメソッドには引数としてパラメータIDとバインドする値、そしてデータ型を指定します。
パラメータIDは疑問符プレースホルダであれば、最初に記載した「?」が1、次に記載した「?」が2となります。 名前付きプレースフォルダの場合は、名前がパラメータIDになります。
バインドする値はユーザーの入力などにより取得した値を指定します。
最後にデータ型ですが、デフォルトでは文字列型のPDO::PARAMSTRが指定されています。 整数型の場合はPDO::PARAMINTを指定しましょう。
4.プリペアドステートメントを実行
上記で設定したプリペアドステートメントを実行するにはPDOStatement::executeメソッドを実行します。
$stmt->execute();
これで、データベースにレコードが追加されているはずです。
今回は少し長くなりましたので、続きは後日書きたいと思います。