PHPによるプログラミング(2.データベース)に関する世界観です。
PDOをnewする時のコンストラクタ引数には、「データソース名」「ユーザー名(任意)」「パスワード(任意)」「接続オプション(任意)」を指定する。
$dbh = new PDO('mysql:dbname=bbs_db;host=localhost', $db_user, $db_password);
PDOの主な関数は以下。
関数 | 説明 |
---|---|
PDO::query() | SQL文を即時に実行して結果を返す。 |
PDO::prepare() | execute()で実行されるSQL文の準備。 |
PDO::setAttribute() | データベースハンドルの属性を設定する。 PDO::ATTR_ERRMODEはエラーレポートの設定で、 PDO::ERRMODE_EXCEPTIONは例外を投げる。 PDO::ATTR_EMULATE_PREPARESは、 プリペアドステートメントのエミュレーションの有効・無効。 詳しくはPHP: PDO::setAttribute - Manualを参照。 |
PDOStatement::bindValue() | SQL文のプレースホルダに値を入れる。 |
PDOStatement::execute() | プリペアドステートメント(SQL文)の実行。 |
PDOStatement::fetchAll() | 全ての要素を含む配列を返す。 |
(【モダンなPHP】PHPでPDOを使ってMySQLに接続する方法! | CodeCampus、PDOを使ったPHPでのデータベース基本操作 - Qiitaを参考に執筆しました。)
データベースサーバーとやり取りするプログラムが、「いちばんやさしいPHPの教本 人気講師が教える実践Webプログラミング (「いちばんやさしい教本」シリーズ)」にあります。
基本的に以下のように接続すれば良い。
$dbh = new PDO('mysql:dbname=bbs_db;host=localhost;charset=utf8', $db_user, $db_password); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sql = "SELECT * FROM bbs"; $stmt = $dbh->query($sql); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($data as $row) { /*HTML表示などの処理*/ }
(以上は「いちばんやさしいPHPの教本 人気講師が教える実践Webプログラミング (「いちばんやさしい教本」シリーズ)」より編集して部分的に引用。)
foreach文「foreach ($data as $row) {}」の中で、ひとつひとつのデータ(行の中の列の項目)には
$row['username']
や
$row['comment']
のようにアクセスする。
セキュリティ対策のために
htmlspecialchars($row['username'], ENT_QUOTES, 'UTF-8')
とするのが望ましい。
たとえば、
echo "<table id=\"bbs\">\n"; foreach ($data as $row) { echo "<tr>"; echo "<td>"; echo htmlspecialchars($row['username'], ENT_QUOTES, 'UTF-8'); echo "</td>"; echo "<td>"; echo htmlspecialchars($row['comment'], ENT_QUOTES, 'UTF-8'); echo "</td>"; echo "</tr>\n"; } echo "</table>\n";
などとする。
(以上は「いちばんやさしいPHPの教本 人気講師が教える実践Webプログラミング (「いちばんやさしい教本」シリーズ)」より編集して部分的に引用。)
2024.11.10編集
以下はプレースホルダの例。
以下の?のところに変数の値が入る。
$sql = "SELECT * FROM bbs WHERE uid = ?"
これに対して、PHPでは
bindValue(?の出てくる番号, ?に入れる変数, 型)
として、?に値を設定する。たとえば、
$stmt = $dbh->prepare($sql); $stmt->bindValue(1, $user_id, PDO::PARAM_INT); $stmt->execute();のようにする(1が1番目の?に対応し、$user_idを当てはめる)。
(以上は「いちばんやさしいPHPの教本 人気講師が教える実践Webプログラミング (「いちばんやさしい教本」シリーズ)」を参考に執筆しました。)
プレースホルダはprepare()の時にbindValue()ではなくbindParam()を使うことで名前を付けて変換することもできる。プレースホルダ名には:idのように「:」をつけて表現する。
$stmt = $dbh->prepare('INSERT INTO bbs(uid, comment) VALUES(:uid, :comment)'; $stmt->bindParam(':uid', $user_id); $stmt->bindParam(':comment', $_POST['comment']); $stmt->execute();
などとする。
(以上は3ステップでしっかり学ぶ MySQL入門 (今すぐ使えるかんたんプラス)より編集して部分的に引用。)
SELECT文だけではなく、INSERT、UPDATE、DELETEなどの命令文(CRUD操作)も同様にプリペアドステートメントにSQL文を代入して実行できる。
SELECTの場合:
$sql = "SELECT * FROM bbs"; $stmt = $dbh->query($sql); $data = $stmt->fetchAll(PDO::FETCH_ASSOC);
INSERTの場合:
$sql = "INSERT INTO bbs (name,email,text) VALUES (?, ?, ?)"; $stmt = $dbh->prepare($sql); $stmt->bindValue(1, $name, PDO::PARAM_STR); $stmt->bindValue(2, $email, PDO::PARAM_STR); $stmt->bindValue(3, $text, PDO::PARAM_STR); $stmt->execute();
UPDATEの場合:
$sql = "UPDATE bbs SET text = ?, name = ? WHERE id = ?"; $stmt = $dbh->prepare($sql); $stmt->bindValue(1, $text, PDO::PARAM_STR); $stmt->bindValue(2, $name, PDO::PARAM_STR); $stmt->bindValue(3, $id, PDO::PARAM_INT); $stmt->execute();
DELETEの場合:
$sql = "DELETE FROM bbs WHERE id = ?"; $stmt = $dbh->prepare($sql); $stmt->bindValue(1, $id, PDO::PARAM_INT); $stmt->execute();
PDOオブジェクトの詳しい使い方については以下が参考になる。
以下の書籍が参考になります。
また、MySQLしかデータベースサーバーを使わないのであれば、mysql_connect()やmysql_query()などのようなmysql_*系の関数を使うこともできます。
以下はPHPとMySQLの連携について。
MySQLも参照のこと。
PHPからデータベースを操作できるPDOクラスですが、実際には上から下へと流れるように書くのではなく、DbManagerのような専門のクラスを仲介することが多いです。
DbManagerという名前のクラスにおいて、new PDO()したオブジェクトをメンバとして保持するようにし、このオブジェクトに対して外部からさまざまなメソッドを実行し、その中でSQL文をクエリ実行するようにします。
もし、ページごとにPDOを操作していると、ひとつのページで一回しかデータベース処理することができず、複雑なことができません。
DbManagerのような専門のクラスを用意することで、さまざまな場所からさまざまなタイミングで、データベースを処理することができます。
(詳しくはパーフェクトPHP (PERFECT SERIES 3)を参照してください。)
2023.05.15
実際のところ、掲示板やブログエンジンを作るのは簡単です。
単に、PHPやNode.jsなどを使って、HTMLの中でSQLのデータを表示・編集あるいは投稿・更新すればいいだけだからです。
必要なのは、HTMLのテンプレート(各ページに共通のHTMLの雛形)を書いて、SQLデータベースからデータを取得して表示するといったように、HTMLとSQLを変換する技術を使いこなすことだけです。
なので、ブログサービスやSNSなどのネットサービスは、比較的簡単に作れます。
ただし、開発の難しさと、運営のコストや利益を上げるのはまた別の問題です。X(旧ツイッター)のようなSNSや掲示板を作っても、利益を上げることが難しく、また運営にもコストがかかります。
なので、企業が簡単にSNSや掲示板を開発・運用することはなかなかできません。無料で公開して世界中でユーザーを集めることがまず至難の業であり、ユーザーがたくさんいても利益が生まれません。膨大なユーザー数を誇るXのイーロン・マスクですら利益を上げるために苦労しています。
XなどのSNSではユーザーのヘイトスピーチや差別発言によるアカウントの凍結も必要で、そのために膨大な運用と管理のコストがかかり、どんなにユーザーがいても赤字になってしまいます。2ちゃんねるはそのような運用・管理をきちんとしていないため、元管理者のひろゆき氏は裁判で膨大な賠償金を支払うように判決が下っています。ただし、安易にアカウントを凍結するとその人間がネット上で言論の活動をする権利を奪ってしまうことになり、「言論の自由」という権利上の問題になります。
2024.11.10