PHP PDO(PHP Data Objects)でデータベースに接続する
前回はphpMyAdminを利用してデータベース、テーブルの作成を解説しました。
今回は、作成したデータベースにPDO(PHP Data Objects)で接続する方法を解説します。
この記事の著者 ->S.E; です。
普段は、システム開発に必要なヒアリング、システムの要件定義、設計からプログラマとしてWebサイトやWebアプリケーションの開発、WordPressでのブログの執筆やサーバー運用・管理を行っています。
このページは「未経験の為のプログラミング講座 ゼロから始めるPHPプログラミング〜初級から実践編までを網羅〜」としてPHPの基本的な部分を【初級編】【中級編】【上級編】に分けて解説しています。最終的には簡単なフォームやシステム開発をフルスクラッチで行うことを目的としています。また、参考になる書籍なども紹介しています。
PDO(PHP Data Objects)とは?
PDOとはPHPに標準で搭載されているデータベースに接続するためのクラスです。PHPの標準で搭載されているためPDOを利用時にインストールの作業などは必要ありません。
mysql関数はPHP7で廃止
PHP4やPHP5で利用されていたmysql関数はPHP7では完全に廃止されたため利用できません。
代替えの関数としてmysqli関数がありますが、クラスで利用でき情報も多いPDOをお勧めします。
mysqlとmysqliの違いについては「PHP5からPHP7へのバージョンアップ-mysql関数」を参照してください。
PDO(PHP Data Objects)の利用方法
まずはPDOを利用してデータベースに接続するコードを紹介します。
変数$dsnの接続するデータベースの種別、データベース名、ホスト名、文字コードを指定します。$user、$passにはそれぞれデータベースに設定したユーザー名とパスワードを設定し、PDOクラスをインスタンスすればデータベースに接続を行います。
接続時にエラーが発生した場合は$e->getMessage()でエラーを吐き出します。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php $dsn = 'mysql:dbname=test_db; host=localhost; charset=utf8'; $user = 'root'; $pass = 'root'; try{ $PDO = new PDO( $dsn, $user, $pass ); echo '接続成功'; } catch( PDOException $e ){ echo '接続エラー'.$e->getMessage(); } ?> |
エラー例
dsnなどの内容が間違っている場合は下記のようなエラーが表示されます。
データベース名が間違っている場合
SQLSTATE[HY000] [1049] Unknown database ‘test_db01’
ユーザー名もしくはパスワードが間違っている場合
SQLSTATE[HY000] [1045] Access denied for user ‘root1’@’localhost’ (using password: YES)
ホスト名が間違っている場合
SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known
データベースに接続しテーブルを操作
データベースへの接続に成功したらテーブルに情報を登録(insert)、更新(update)、削除(delete)、取得(select)を行います。
データの操作を行うにあたり、SQL文に不正な文字列や間違った記述などを行った際、エラーを出力するため、$PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);の一文を追記します。
定数(オプション名) | 設定値 | 内容 |
---|---|---|
PDO::ATTR_ERRMODE | – | エラーの通知方法 (デフォルトはPDO::ERRMODE_SILENT) |
– | PDO::ERRMODE_SILENT | エラーを出力しない |
– | PDO::ERRMODE_WARNING | 警告を発生 |
– | PDO::ERRMODE_EXCEPTION | 例外を発生 |
1 2 3 4 5 6 7 8 9 10 11 12 | <?php $dsn = 'mysql:dbname=test_db; host=localhost; charset=utf8'; $user = 'root'; $pass = 'root'; try{ $PDO = new PDO( $dsn, $user, $pass ); $PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch( PDOException $e ){ echo '接続エラー'.$e->getMessage(); } ?> |
データの登録(insert)
それではtest_tableに情報を登録します。
データベースに接続後、情報を登録するためのINSERTを利用します。
$queryにSQLを記述します。SQL文内の「:test_name」や「:test_age」はプレースホルダで後のbindValue()で指定の位置に任意のデータを送信するための記述です。
SQL文を記述した後、prepare()にSQL文を送り$stmtにセットします。その後、bindValue()でプレースホルダを指定し任意の情報を送ります。bindValue()内にのある「PDO::PARAM_STR」「PDO::PARAM_INT」は登録する情報が文字列なのか数値なのかを指定しています。
定数 | 内容 |
---|---|
PDO::PARAM_STR | 文字列型 |
PDO::PARAM_INT | 整数型 |
PDO::PARAM_BOOL | 真偽型 |
PDO::PARAM_NULL | null型 |
PDO::PARAM_LOB | ラージオブジェクト型(バイナリ) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <?php $dsn = 'mysql:dbname=test_db; host=localhost; charset=utf8'; $user = 'root'; $pass = 'root'; try{ $PDO = new PDO( $dsn, $user, $pass ); $PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch( PDOException $e ){ echo '接続エラー'.$e->getMessage(); } try{ $query = 'INSERT INTO test_table ( test_name, test_age, test_gender, test_tel, test_create )VALUES( :test_name, :test_age, :test_gender, :test_tel, now() )'; $stmt = $PDO->prepare( $query ); $stmt->bindValue( ':test_name', '山田 太郎', PDO::PARAM_STR ); $stmt->bindValue( ':test_age', 25, PDO::PARAM_INT ); $stmt->bindValue( ':test_gender', 1, PDO::PARAM_INT ); $stmt->bindValue( ':test_tel', '080-1111-2222', PDO::PARAM_STR ); $stmt->execute(); echo '登録しました。'; } catch( PDOException $e ){ echo $e->getMessage(); exit(); } ?> |
SQLインジェクション対策
送信するデータに不正な文字列などがあった場合、bindValue()を通すことによりエスケープすることができます。エスケープすることにより「SQLインジェクション」を防ぐことができます。
データの更新(update)
登録したデータを更新する場合はUPDATEを利用します。
SQL文がUPDATEとなる以外はほぼINSERT時と同じ内容です。
注意点は、どの情報を更新するかのWHERE句です。WHERE句を設定しないと全ての情報を指定の内容で上書き更新してしまいます。更新する場合はWHERE句でプライマリキー「test_id」を指定してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <?php $dsn = 'mysql:dbname=test_db; host=localhost; charset=utf8'; $user = 'root'; $pass = 'root'; try{ $PDO = new PDO( $dsn, $user, $pass ); $PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch( PDOException $e ){ echo '接続エラー'.$e->getMessage(); } try{ $query = 'UPDATE test_table SET test_name = :test_name, test_age = :test_age, test_gender = :test_gender, test_tel = :test_tel WHERE test_id = :test_id'; $stmt = $PDO->prepare( $query ); $stmt->bindValue( ':test_name', '山田 次郎', PDO::PARAM_STR ); $stmt->bindValue( ':test_age', 28, PDO::PARAM_INT ); $stmt->bindValue( ':test_gender', 1, PDO::PARAM_INT ); $stmt->bindValue( ':test_tel', '080-6666-2222', PDO::PARAM_STR ); $stmt->bindValue( ':test_id', 1, PDO::PARAM_INT ); $stmt->execute(); echo '更新しました。'; } catch( PDOException $e ){ echo $e->getMessage(); exit(); } ?> |
データの削除(delete)
データベースに登録した情報を完全に削除したい場合はDELETEを利用します。
DELETE利用時も必ずWHERE句を利用して削除する情報を指定しましょう。WHERE句の記述がないと指定のテーブルの情報が全て削除されてしまいます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <?php $dsn = 'mysql:dbname=test_db; host=localhost; charset=utf8'; $user = 'root'; $pass = 'root'; try{ $PDO = new PDO( $dsn, $user, $pass ); $PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch( PDOException $e ){ echo '接続エラー'.$e->getMessage(); } try{ $query = 'DELETE FROM test_table WHERE test_id = :test_id'; $stmt = $PDO->prepare( $query ); $stmt->bindValue( ':test_id', 1, PDO::PARAM_INT ); $stmt->execute(); echo '削除しました。'; } catch( PDOException $e ){ echo $e->getMessage(); exit(); } ?> |
データ削除の方法
今回データベースには「test_delete_key」を用意しています。このカラムは通常時は「0」、削除時は「1」ということにすることで、データを完全に削除するのではなく一時的に非表示にする方法もあります。
この場合は「DELETE」ではなく「UPDATE」を利用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <?php $dsn = 'mysql:dbname=test_db; host=localhost; charset=utf8'; $user = 'root'; $pass = 'root'; try{ $PDO = new PDO( $dsn, $user, $pass ); $PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch( PDOException $e ){ echo '接続エラー'.$e->getMessage(); } try{ $query = 'UPDATE test_table SET test_delete_key = 1 WHERE test_id = :test_id'; $stmt = $PDO->prepare( $query ); $stmt->bindValue( ':test_id', 1, PDO::PARAM_INT ); $stmt->execute(); echo '削除しました。'; } catch( PDOException $e ){ echo $e->getMessage(); exit(); } ?> |
このように、フラグを利用し一時的に見えないようにすることで、万が一間違って削除してしまった場合でもデータを復元することができます。
データの取得(select)
データの登録ができたので、登録したデータを呼び出してみましょう。
データの取得にはSELECTを利用します。
fetch(PDO::FETCH_ASSOC)でデータベース内の情報を取得し、$rowsに格納しています。
定数 | データ取得の形式 | 取得例 |
---|---|---|
PDO::FETCH_ASSOC | 連想配列 | $row[‘test_id’] |
PDO::FETCH_NUM | 配列 | $row[0] |
PDO::FETCH_OBJ | オブジェクト | $row->test_id |
PDO::FETCH_COLUMN | スカラー値 | $row |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <?php $dsn = 'mysql:dbname=test_db; host=localhost; charset=utf8'; $user = 'root'; $pass = 'root'; try{ $PDO = new PDO( $dsn, $user, $pass ); $PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch( PDOException $e ){ echo '接続エラー'.$e->getMessage(); } try{ $query = 'SELECT * FROM test_table'; $stmt = $PDO->prepare( $query ); $stmt->execute(); $row = $stmt->fetch(PDO::FETCH_ASSOC); print_r($row); } catch( PDOException $e ){ echo $e->getMessage(); exit(); } ?> // 結果 Array ( [test_id] => 1 [test_name] => 山田 太郎 [test_age] => 25 [test_gender] => 1 [test_tel] => 080-1111-2222 [test_create] => 2020-09-23 04:05:41 [test_update] => 2020-09-23 04:05:41 [test_delete_key] => 0 ) |
データベース内に複数の情報がある場合はwhileを利用することで全てを出力することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | <?php $dsn = 'mysql:dbname=test_db; host=localhost; charset=utf8'; $user = 'root'; $pass = 'root'; try{ $PDO = new PDO( $dsn, $user, $pass ); $PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch( PDOException $e ){ echo '接続エラー'.$e->getMessage(); } try{ $query = 'SELECT * FROM test_table'; $stmt = $PDO->prepare( $query ); $stmt->execute(); while( $row = $stmt->fetch(PDO::FETCH_ASSOC) ){ print_r($row); } } catch( PDOException $e ){ echo $e->getMessage(); exit(); } ?> // 結果 Array ( [test_id] => 1 [test_name] => 山田 太郎 [test_age] => 25 [test_gender] => 1 [test_tel] => 080-1111-2222 [test_create] => 2020-09-23 04:05:41 [test_update] => 2020-09-23 04:05:41 [test_delete_key] => 0 ) Array ( [test_id] => 2 [test_name] => 佐藤 花子 [test_age] => 19 [test_gender] => 2 [test_tel] => 090-8888-3333 [test_create] => 2020-09-23 04:34:55 [test_update] => 2020-09-23 04:34:55 [test_delete_key] => 0 ) |
「DELETE」と「UPDATE」での削除方法を紹介しましたが、「test_delete_key」を利用してで0田を一時的に非表示にしている場合は「SELECT」時に「test_delete_key=1」のものは呼び出さないようにする必要があります。その場合は、WHERE句で「test_delete_key != 1」もしくは「test_delete_key != 0」と記述することで、削除フラグ(test_delete_key)が「1」のものを除いて情報を取得することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <?php $dsn = 'mysql:dbname=test_db; host=localhost; charset=utf8'; $user = 'root'; $pass = 'root'; try{ $PDO = new PDO( $dsn, $user, $pass ); $PDO->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch( PDOException $e ){ echo '接続エラー'.$e->getMessage(); } try{ $query = 'SELECT * FROM test_table WHERE test_delete_key != 1 '; $stmt = $PDO->prepare( $query ); $stmt->execute(); while( $row = $stmt->fetch(PDO::FETCH_ASSOC) ){ print_r($row); } } catch( PDOException $e ){ echo $e->getMessage(); exit(); } ?> |
データベースを利用してみて
データベースの読み書きについて解説しましたが、慣れるまでは難しいかと思いますがSQL文さえわかればあとは定形文のようなものなので簡単に利用できます。
S.E->お勧め記事;
- PHPフレームワーク「Laravel」ルーティング Route::get()
- XSERVERにSSHを利用してLaravel環境を構築する
- macOS Monterey にアップデート後、composerやhomebrewでenv: php: No such file or directoryが出る
- PHPフレームワーク「Laravel」ディレクティブ-繰り返し処理(ループ処理)-
- PHPフレームワーク「Laravel」MVCとコントローラを利用する
- PHP フレームワーク Laravel ディレクティブ – ループ変数 $loop –
- PHPフレームワーク「Laravel」ディレクティブ-分岐処理(条件分岐)-
- PHPフレームワーク「Laravel」PHPテンプレートを利用する
- PHPフレームワーク「Laravel」Bladeテンプレートを利用する