PHPの基本知識をゼロから学ぶハンズオン学習(後編)

本PHPのページは、3部作となります。焦らず進めていきましょう。

  1. リクエスト情報
    1. 1. リクエスト情報
      1. 1-1. リクエスト情報とは
      2. 1-2. HTTP通信の確認方法
      3. 1-3. HTTP通信の構成
    2. 2. リクエスト
      1. 2-1. リクエストメソッド
      2. 2-2. リクエストヘッダー
      3. 2-3. リクエストボディ
    3. 3. レスポンス
      1. 3-1. HTTP ステータス
        1. 3-1-1. 1xx(情報レスポンス)
        2. 3-1-2. 2xx(成功)
        3. 3-1-3. 3xx(リダイレクト)
        4. 3-1-4. 4xx(クライアントエラー)
        5. 3-1-5. 5xx(サーバーエラー)
    4. 4. スーパーグローバル変数
      1. 4-1. $_GET
        1. 4-1-1. URLエンコード、デコード
      2. 4-2. $_POST
        1. 4-2-1. HTMLエスケープ(クロスサイトスクリプティング(XSS)対策)
        2. 4-2-2. 複数の値を持つ要素を扱う
      3. 4-3. $_FILES
        1. 4-3-1. ファイルアップロード
        2. 4-3-2. $_FILES の構造
        3. 4-3-3. エラーコード ($_FILES['userfile']['error'])
        4. 4-3-4. 複数ファイルのアップロード
      4. 4-4. $_SERVER
        1. 4-4-1. 基本構文
        2. 4-4-2. getallheaders() との違い
        3. 4-4-3. リクエストヘッダー
        4. 4-4-4. レスポンスヘッダー
      5. 4-5. $_ENV
        1. 4-5-1. 基本構文
      6. 4-6. $_COOKIE
        1. 4-6-1. 基本構文
        2. 4-6-2. Cookie の仕組み(流れ)
        3. 4-6-3. setcookie() の引数
        4. 4-6-4. Cookie の削除
      7. 4-7. $_SESSION
        1. 4-7-1. 基本構文
        2. 4-7-2. セッションの仕組み(流れ)
        3. 4-7-3. セッションIDの確認
        4. 4-7-4. セッションの有効期限
        5. 4-7-5. セッションを削除する
        6. 4-7-6. セッションデータの保存先
  2. データベース連携
    1. 1. データベース
      1. 1-1. データベースとは
      2. 1-2. データベースの主な特徴
      3. 1-3. データベースの種類
      4. 1-4. リレーショナルデータベース(RDB)
        1. 1-4-1. リレーショナルデータベース(RDB)とは
        2. 1-4-2. 主なリレーショナルデータベース製品
    2. 2. データベース操作を行うSQL
      1. 2-1. DDL(データ定義言語)
      2. 2-2. DML(データ操作言語)
      3. 2-3. DCL(データ制御言語)
      4. 2-4. TCL(トランザクション制御言語)
        1. 2-4-1. トランザクションとは
    3. 3. PHPからデータベースに接続
      1. 3-1. mysqliで接続する方法
      2. 3-2. PDOで接続する方法
    4. 4. 例外処理
      1. 4-1. 基本構文
      2. 4-2. 例外クラスで呼び出せるメソッド
        1. 4-2-1. getMessage()
        2. 4-2-2. getCode()
        3. 4-2-3. getFile() と getLine()
        4. 4-2-4. getTrace() と getTraceAsString()
      3. 4-3. 例外処理のポイント
    5. 5. PDO接続オプション
      1. 5-1. 接続時にオプションを指定
      2. 5-2. 接続後にオプションを指定
    6. 6. mysqlにおけるSQLクエリの発行
      1. 6-1. PDOの場合
      2. 6-2. mysqliの場合
    7. 7. 名前付きパラメータと名前なしパラメータ
      1. 7-1. 名前付きパラメータ
      2. 7-2. 名前なしパラメータ
    8. 8. 仮想テーブル(結果セットの取得)
      1. 8-1. 結果セットの取得
      2. 8-2. 仮想テーブル
      3. 8-3. 結果セットから取得する方法
        1. 8-3-1. fetch メソッド
        2. 8-3-2. fetchAll メソッド
      4. 8-3-3. フェッチモード
      5. 8-3-4. fetchColumnメソッド
      6. 8-3-5. fetchObjectメソッド
    9. 9. パラメータ値のバインド
      1. 9-1. パラメータ値のバインド
      2. 9-2. bindParamメソッド と bindValueメソッド
    10. 10. トランザクション処理

リクエスト情報

1. リクエスト情報
2. リクエスト
3. レスポンス
4. スーパーグローバル変数

1. リクエスト情報

1-1. リクエスト情報とは

クライアント(主にWebブラウザ)からサーバーへ送られてくる HTTPリクエストの内容 を指します。
HTTP(HyperText Transfer Protocol) は、WebブラウザとWebサーバーが 情報をやり取りするための通信規約(プロトコル) で、簡単に言うと、「ブラウザがお願い(リクエスト)して、サーバーが応える(レスポンス)」という仕組みを定めたルールです。

1-2. HTTP通信の確認方法

HTTP通信は、Chromeのブラウザに搭載されているデベロッパーツールで確認する事ができます。

「Network」タブを選択します。

リクエスト情報を確認したいものを選択します。
ここでは、「www.php.co.jp」とし選択すると、「Headers」タブでは「General」、「Response Headers」、「Request Headers」内を確認できます。

1-3. HTTP通信の構成

リクエスト

HTTPメソッドサーバーに対する直接の要求と取得するパス
何をどうしたいのかを指定する部分
リクエストヘッダーリクエストの構成情報、クライアント情報など
通信に関する追加情報
リクエストボディ送信されたデータ
フォームデータやJSONが入る

レスポンス

HTTP ステータスサーバーでの処理結果を表すコードとメッセージ
レスポンスヘッダーコンテンツの構成情報、サーバー情報など
レスポンスボディコンテンツ本体

2. リクエスト

2-1. リクエストメソッド

HTTPリクエストの最初の部分に書かれる 「このリクエストで何をしたいのか」を表す命令 です。
主なリクエストメソッドには、以下のものがあります。

リクエストメソッド概要
GETデータを取得するためのリクエスト
URLにパラメータを付けて送信(例: /search.php?q=php
送信内容は クエリ文字列 に含まれる
ブラウザのアドレスバーに表示される
ブックマーク可能
POSTデータをサーバーに送るためのリクエスト
フォーム送信やAPIでよく使う
送信内容は リクエストボディ に含まれる(URLに見えない)
ファイルアップロードやログインなどに利用
PUT既存データを「更新」するために使われる
REST API などで利用される(ブラウザからは直接送信しにくい)
DELETEデータを「削除」するためのリクエスト
REST APIで利用される

GET /index.php HTTP/1.1
  • GET = メソッド
  • /index.php = リクエスト対象のパス(URI)
  • HTTP/1.1 = プロトコルのバージョン

2-2. リクエストヘッダー

リクエストの構成情報、クライアント情報など通信に関する追加情報です。

Host: example.com
User-Agent: Mozilla/5.0
Accept-Language: ja
Cookie: session=abc123

2-3. リクエストボディ

データを送る部分(主に POST, PUT, PATCH などで利用)で、フォームデータやJSONが入ります。

username=test&password=1234

3. レスポンス

3-1. HTTP ステータス

リクエストがどう処理されたかを表します。
HTTPで利用される主なHTTPステータスは、以下のとおりです。

100情報
200成功
300リダイレクト
400クライアントエラー
500サーバーエラー

HTTP/1.1 200 OK
  • 200 OK → 成功
3-1-1. 1xx(情報レスポンス)

リクエストはまだ継続中であり、最終的なレスポンスではないことを示します。
主にクライアントとサーバーの やり取りの途中 に使われます。
主に 大きなデータ送信(ファイルアップロードなど) の前に利用されます。

3-1-2. 2xx(成功)

リクエストが正常に処理されたことを表します。

200正常終了
201サーバー側にリソースが新規作成された
202受付完了(未処理)
203情報は返すけれど、オリジナルのサーバーが保証したものではない
204成功したが返す内容がない
3-1-3. 3xx(リダイレクト)

別の場所へ移動したことを知らせます。

301リソースが恒久的に移転
302リソースが一時的に移動
303リソースが別の場所に存在する
POSTの後でGETにリダイレクト
304リソースが変更されていない
キャッシュを使ってOK(変更なし)
3-1-4. 4xx(クライアントエラー)

リクエストに問題があるときです。

400不正なリクエスト
401HTTP認証を要求
認証が必要(ログイン必須)
403アクセス拒否(権限なし)
404ページが存在しない
405許可されていないメソッド
(例: GETしかないのにPOST送信)
407HTTPメソッドが不許可
408リクエストタイムアウト
3-1-5. 5xx(サーバーエラー)

サーバー側で問題が発生。

500サーバー内部エラー(PHPエラーなど)
501応答に必要な機能が未実装
502ゲートウェイやプロキシの不具合
503HTTPサーバーが利用不可
(メンテナンス中など)
504ゲートウェイやプロキシのタイムアウト

4. スーパーグローバル変数

PHPではリクエスト情報の取得/操作するためにスーパーグローバル変数という、あらかじめ用意されている連想配列の変数があります。
このスーパーグローバル変数は、主に「HTTPリクエスト情報」や「サーバー情報」を格納されており、スクリプト側ではこれを参照するだけで必要な情報を取得できます。
どのスコープ(関数内・クラス内など)からでも 必ずアクセス可能です。
スーパーグローバル変数は、主に以下のものがあります。

スーパーグローバル変数概要
$_GETGETリクエストで送られたデータを格納
URLクエリ文字列が入る
$_POSTPOSTリクエストで送られたデータを格納
フォーム送信やJSON送信など
$_FILESファイルアップロード情報
アップロード時のファイル名・一時保存場所・エラー情報など
$_SERVERサーバーや実行環境に関する情報
リクエストヘッダー、またはサーバー固有の変数情報
リクエストメソッドやクライアントのIPなども取れる
$_ENV環境変数を格納
$_COOKIEクライアントが送ってきたクッキーの値
$_SESSIONサーバー側で保持するセッション変数
ログイン状態などを保持するのに使う
$_REQUEST$_GET, $_POST, $_COOKIE をまとめたもの

以下の理由から原則として利用は推奨されていません
・同名のキーがあった場合に、片方のキーが上書きされてしまう
・どこから受け取ったデータなのか曖昧になりやすい

4-1. $_GET

URLのクエリ文字列(?以降の部分) から送られてきたデータを受け取るスーパーグローバル変数で、主に検索フォームやリンクで利用されます。
送信できるデータ量は URLの長さに制限 があります。(ブラウザやサーバー依存)

例文
例えば、次のような URL があったとします。

http://example.com/test.php?name=Taro&age=20

HTMLフォーム

<form method="get" action="test.php">
  名前: <input type="text" name="name"><br>
  年齢: <input type="text" name="age"><br>
  <input type="submit" value="送信">
</form>

$_GET['キー名'] で値を取得できます。

<?php
echo $_GET['name']; // Taro
echo $_GET['age'];  // 20
?>
4-1-1. URLエンコード、デコード

URLの中で そのままでは使えない文字(日本語や記号など)を、特別な形式に変換する仕組みです。

例文
クエリ文字列に使える形式に変換(スペースは + に変換)。

echo urlencode("太郎 東京"); 
// %E5%A4%AA%E9%83%8E+%E6%9D%B1%E4%BA%AC

urlencode() でエンコードしたものを戻します。

echo urldecode("%E5%A4%AA%E9%83%8E"); 
// 太郎

4-2. $_POST

クライアント(ブラウザなど)が HTTPリクエストメソッド POST で送信したデータを格納する 連想配列で、代表的に フォーム送信データ を受け取るときに利用されます。
例文

フォーム(form.html)

<form action="receive.php" method="post">
  <input type="text" name="username">
  <input type="password" name="password">
  <input type="submit" value="送信">
</form>

PHP側(receive.php)

<?php
echo "ユーザー名: " . $_POST['username'] . "<br>";
echo "パスワード: " . $_POST['password'];

任意の値を送信すると以下のように表示されます。

ユーザー名: Taro
パスワード: 1234
4-2-1. HTMLエスケープ(クロスサイトスクリプティング(XSS)対策)

ユーザーからの入力データをそのままHTMLに埋め込むと危険なので、特別な記号を「安全な文字列」に変換する処理 を行う必要があります。


もしユーザー入力をそのまま出力したら…

<?php
echo $_POST['name'];

ユーザーが次のように入力すると:

<script>alert('XSS');</script>

ブラウザはこれを JavaScriptコード として実行してしまいます。
デフォルトでは以下の文字が変換されます。

文字変換後
&&amp;
<&lt;
>&gt;
"&quot;
'(オプション指定時)&#039;

HTMLエスケープを実装するには、PHPでは主に htmlspecialchars() を使います。
HTMLの特殊文字を「エスケープ(無害化)」して、ブラウザがタグとして解釈しないようにする関数です。
入力データを画面に出力するとき に必ず使用しましょう。

htmlspecialchars(string $string, int $flags, string $encoding, bool $double_encode)

引数

$stringエスケープ対象の文字列
$flagsエスケープの種類

以下は一部です。
ENT_QUOTES : シングルクォート ' も変換(推奨)
ENT_NOQUOTES : ダブルクォート ", シングルクォート ' は変換しない
ENT_HTML5 : HTML5 形式で変換
$encoding使用する文字エンコーディング
$double_encodeHTMLエンティティを二重にエスケープするか

例文

<?php
$input = '<script>alert("XSS!");</script>';

echo htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
?>

出力

&lt;script&gt;alert(&quot;XSS!&quot;);&lt;/script&gt;

ブラウザに表示されるのはただの文字列になり、スクリプトは実行されません

4-2-2. 複数の値を持つ要素を扱う

複数の値を持つ要素を取得するには、name属性を[ ]を付与し配列にする必要があります。
例文
name="fruits[]" のように [] をつけると、配列として複数の値を受け取れる

<form method="post">
  <label><input type="checkbox" name="fruits[]" value="apple"> りんご</label>
  <label><input type="checkbox" name="fruits[]" value="banana"> バナナ</label>
  <label><input type="checkbox" name="fruits[]" value="orange"> みかん</label>
  <input type="submit" value="送信">
</form>
<?php
if (!empty($_POST['fruits'])) {
    foreach ($_POST['fruits'] as $fruit) {
        echo htmlspecialchars($fruit, ENT_QUOTES, 'UTF-8') . "<br>";
    }
}
?>

選択結果(例)

apple
orange

4-3. $_FILES

HTMLフォームからファイルをアップロードする際に使用するスーパーグローバル変数です。
アップロードされたファイルに関する情報(ファイル名・サイズ・一時保存場所・エラー情報など)が格納されます。

4-3-1. ファイルアップロード

HTMLフォーム側
まず、ファイルをアップロードするためのHTMLフォームを用意します。
ここでのポイントは enctype="multipart/form-data" を指定することです。

<form action="upload.php" method="post" enctype="multipart/form-data">
  <input type="file" name="userfile">
  <input type="submit" value="アップロード">
</form>
  • action:送信先のPHPファイル(ここでは upload.php
  • method="post":POSTメソッドで送信
  • enctype="multipart/form-data":ファイルを送信するために必須

PHP側 (upload.php)

<?php
// エラーチェック
if ($_FILES['userfile']['error'] === UPLOAD_ERR_OK) {

    // 一時ファイルの場所
    $tmp_name = $_FILES['userfile']['tmp_name'];

    // アップロードされたファイル名
    $name = $_FILES['userfile']['name'];

    // 保存先ディレクトリを指定(存在していることが前提)
    $upload_dir = "uploads/";

    // ファイルを指定の場所へ移動
    if (move_uploaded_file($tmp_name, $upload_dir . $name)) {
        echo "ファイル「{$name}」をアップロードしました。";
    } else {
        echo "ファイルの保存に失敗しました。";
    }

} else {
    echo "アップロードエラーが発生しました。";
}
?>

まとめ

構文・関数説明
$_FILES['userfile']アップロードされたファイル情報を格納する配列
$_FILES['userfile']['name']元のファイル名
$_FILES['userfile']['tmp_name']一時保存されたファイルのパス
$_FILES['userfile']['error']アップロードエラーの有無
move_uploaded_file(一時パス, 保存先)ファイルを指定フォルダへ移動させる関数
4-3-2. $_FILES の構造

$_FILES は連想配列で、次のキーを持っています

キー名内容
name元のファイル名
typeMIMEタイプ(例: image/jpeg
tmp_name一時的に保存されたファイルのパス
errorエラーコード(0なら成功)
sizeファイルサイズ(バイト単位)
4-3-3. エラーコード ($_FILES['userfile']['error'])
定数名意味
UPLOAD_ERR_OK0成功
UPLOAD_ERR_INI_SIZE1php.ini の upload_max_filesize を超えた
UPLOAD_ERR_FORM_SIZE2フォームの MAX_FILE_SIZE を超えた
UPLOAD_ERR_PARTIAL3一部しかアップロードされなかった
UPLOAD_ERR_NO_FILE4ファイルが選択されていない
UPLOAD_ERR_NO_TMP_DIR6一時フォルダが存在しない
UPLOAD_ERR_CANT_WRITE7ディスク書き込みエラー
UPLOAD_ERR_EXTENSION8PHP拡張でアップロードが停止された
4-3-4. 複数ファイルのアップロード

複数ファイルをアップロード する場合は、HTML側で <input>multiple 属性を付けて、さらに name 属性を配列形式 (name="userfile[]") にするのがポイントです。

例文
HTMLフォーム側

<form action="upload.php" method="post" enctype="multipart/form-data">
  <input type="file" name="userfile[]" multiple>
  <input type="submit" value="アップロード">
</form>
  • multiple … 複数ファイルを一度に選択できるようにする属性。
  • name="userfile[]"[] を付けることで、送信時に複数ファイルが配列として扱われます。

PHP側 (upload.php)

<?php
$upload_dir = "uploads/";

// フォルダが存在しなければ作成
if (!is_dir($upload_dir)) {
    mkdir($upload_dir, 0777, true);
}

foreach ($_FILES['userfile']['tmp_name'] as $key => $tmp_name) {

    $name = $_FILES['userfile']['name'][$key];
    $error = $_FILES['userfile']['error'][$key];

    if ($error === UPLOAD_ERR_OK) {
        $destination = $upload_dir . basename($name);
        if (move_uploaded_file($tmp_name, $destination)) {
            echo "ファイル「{$name}」をアップロードしました。<br>";
        } else {
            echo "ファイル「{$name}」の保存に失敗しました。<br>";
        }
    } else {
        echo "ファイル「{$name}」のアップロードに失敗しました。(エラーコード: {$error})<br>";
    }
}
?>

複数ファイルの場合の$_FILES 配列の構造

複数ファイルをアップロードすると、$_FILES は次のような 多次元配列 になります。

$_FILES = [
  "userfile" => [
    "name" => ["a.jpg", "b.png"],
    "type" => ["image/jpeg", "image/png"],
    "tmp_name" => ["/tmp/phpYzdqkD", "/tmp/phpuA9sdf"],
    "error" => [0, 0],
    "size" => [12345, 67890]
  ]
];

そのため、foreach$key を使って各ファイルにアクセスします。

4-4. $_SERVER

サーバーやクライアント(ブラウザ)に関する情報を取得できる スーパーグローバル変数 で、リクエストのヘッダー情報 などが入っており、HTTP通信の中身を確認したり、処理を分岐させたりする際に使います。

ヘッダー情報概要
一般ヘッダー要求 / 応答時双方で利用
エンティティヘッダーコンテンツに関する情報
リクエストヘッダークライアント(ブラウザなど)がサーバーに送る情報
レスポンスヘッダーサーバーがクライアントに返す情報
4-4-1. 基本構文

基本構文

<?php
echo $_SERVER['キー名'];
?>

$_SERVER は連想配列になっていて、キー名によって取得できる情報が異なります。

よく使われる $_SERVER のキー一覧は以下のとおりです。

キー名内容
$_SERVER['PHP_SELF']実行中のスクリプトのパス/index.php
$_SERVER['SERVER_NAME']サーバー名(ドメイン)example.com
$_SERVER['HTTP_HOST']リクエストヘッダの Hostexample.com
$_SERVER['REQUEST_METHOD']HTTPメソッドGET / POST / PUT など
$_SERVER['REQUEST_URI']リクエストされたURI/test/page.php?x=1
$_SERVER['QUERY_STRING']クエリ文字列x=1&y=2
$_SERVER['HTTP_USER_AGENT']ブラウザやOSの情報Mozilla/5.0 ...
$_SERVER['HTTP_REFERER']直前のページ(リファラ)https://google.com/
$_SERVER['REMOTE_ADDR']クライアントのIPアドレス192.168.1.10
$_SERVER['SERVER_ADDR']サーバーのIPアドレス192.168.1.5
$_SERVER['SCRIPT_FILENAME']実行中スクリプトの絶対パス/var/www/html/index.php
$_SERVER['HTTPS']HTTPS接続なら 'on'on or 未定義
$_SERVER['SERVER_PORT']サーバーのポート番号80 / 443

例文

<?php
echo "アクセスしたURL: http://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . "<br>";
echo "使用中のブラウザ: " . $_SERVER['HTTP_USER_AGENT'] . "<br>";
echo "あなたのIPアドレス: " . $_SERVER['REMOTE_ADDR'] . "<br>";
echo "通信方式: " . $_SERVER['REQUEST_METHOD'] . "<br>";
?>

結果(例)

アクセスしたURL: http://example.com/test.php
使用中のブラウザ: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
あなたのIPアドレス: 192.168.0.15
通信方式: GET
4-4-2. getallheaders() との違い

getallheaders() は、HTTPヘッダーだけを取得する関数です。
$_SERVER はヘッダーに加えてサーバーや環境情報も含みます。

$headers = getallheaders();
print_r($headers);

例文

Array
(
  [Host] => example.com
  [User-Agent] => Mozilla/5.0 ...
  [Accept] => text/html
)
4-4-3. リクエストヘッダー

クライアント(ブラウザなど)がサーバーに送る情報です。
「どんな内容を欲しいのか」「どんな環境からアクセスしているのか」を伝えます。

主なリクエストヘッダー一覧

ヘッダー名内容
Host接続先ホスト名(ドメイン)example.com
User-AgentブラウザやOSの情報Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept受け取れるデータ形式(MIMEタイプ)text/html,application/json
Accept-Language使用言語ja,en-US;q=0.9
Accept-Encoding圧縮形式gzip, deflate, br
Referer前のページのURL(リンク元)https://google.com/
Cookieクライアント側のCookie情報session_id=abc123; theme=dark
Authorization認証情報(APIトークンなど)Bearer xxxxxxxx
Content-Type送信データの形式(POST時など)application/jsonmultipart/form-data
Content-Length送信データのバイト数356
Originリクエスト元のオリジン(CORS制御で使用)https://myapp.com
Connection接続の継続指定keep-alive / close
4-4-4. レスポンスヘッダー

サーバーがクライアントに返す情報です。
「どんな形式のデータを返したか」「キャッシュできるか」などを伝えます。

主なレスポンスヘッダー一覧

ヘッダー名内容
Content-Type返すデータの形式text/html; charset=UTF-8
Content-Lengthボディ部分の長さ4521
Dateレスポンス生成日時Sun, 12 Oct 2025 03:12:00 GMT
Server使用中のサーバーソフトApache/2.4.57 (Unix)
Set-CookieサーバーからクライアントにCookieを送るsession_id=abc123; HttpOnly
Cache-Controlキャッシュの制御no-cache, no-store
Expiresキャッシュ有効期限Wed, 21 Oct 2025 07:28:00 GMT
Locationリダイレクト先のURLhttps://example.com/login
Access-Control-Allow-OriginCORS許可設定* or https://myapp.com
Content-Disposition添付ファイルの指定attachment; filename="report.pdf"

4-5. $_ENV

サーバー側に設定されている環境変数を取得するためのスーパーグローバル変数です。
環境変数とは、コンピューター上にあらかじめ定義されたパラメータのことで、プログラムを実行する際に参照するパスやオプション値などを設定します。例えば、環境変数PATHは、コマンドラインなどでプログラムを呼び出す場合に既定で検索するフォルダを表します。

4-5-1. 基本構文

基本構文

<?php
echo $_ENV['変数名'];
?>

よく使われる環境変数の例

変数名内容
PATH実行ファイルを探すディレクトリのリスト/usr/local/bin:/usr/bin:/bin
HOMEユーザーのホームディレクトリ/home/www-data
USER実行中ユーザー名www-data
LANGロケール設定ja_JP.UTF-8
APP_ENVアプリケーションの環境(Laravelなど)local, production
APP_DEBUGデバッグモード(true/false)true
DB_HOSTデータベースホスト名127.0.0.1
DB_PASSWORDDBパスワードsecret

例文
システムの環境変数を表示する

<?php
print_r($_ENV);
?>

出力例

Array
(
    [PATH] => /usr/local/bin:/usr/bin:/bin
    [HOME] => /home/www-data
    [USER] => www-data
    [LANG] => ja_JP.UTF-8
)

4-6. $_COOKIE

$_COOKIE は PHP のスーパーグローバル変数のひとつで、ブラウザに保存されたクッキー情報を取得・操作する ために使います。

4-6-1. 基本構文

基本構文

<?php
echo $_COOKIE['キー名'];
?>

ブラウザがサーバーにアクセスするとき、保存済みのクッキーが自動的に送信されます。
その内容は $_COOKIE に格納されます。

4-6-2. Cookie の仕組み(流れ)

サーバーが Cookie をセットする

setcookie("user", "moka", time() + 3600); // 有効期限1時間

ブラウザが Cookie を保存する

  • ユーザーのPCのブラウザ内に保存されます。
  • ドメインごとに管理されます。

次回アクセス時にブラウザが送信

  • 同じドメインに再アクセスすると、CookieがHTTPヘッダーでサーバーに送られ、
    PHPの $_COOKIE に自動的に反映されます。

例文
Cookie のセットと取得

<?php
// Cookieを設定
setcookie("username", "moka", time() + 3600, "/"); // "/" は全ページで有効

// ページ再読み込み後に取得可能
if (isset($_COOKIE['username'])) {
    echo "ようこそ、" . $_COOKIE['username'] . "さん!";
} else {
    echo "Cookieは設定されていません。";
}
?>

出力例:

ようこそ、mokaさん!
4-6-3. setcookie() の引数

setcookie() は PHP で クライアント(ブラウザ)に Cookie を送信するための関数 です。
「ユーザーを識別する」「ログイン状態を保持する」「サイト設定(テーマなど)を保存する」などに使われます。

基本構文

setcookie(
    string $name,        // クッキー名
    string $value = "",  // 値
    int $expires = 0,    // 有効期限(UNIXタイムスタンプ)
    string $path = "",   // 有効なパス
    string $domain = "", // 有効なドメイン
    bool $secure = false,// HTTPS通信のみ送信するか
    bool $httponly = false // JavaScriptからアクセスできないようにするか
);

例文

setcookie("username", "moka");

この場合、有効期限は「ブラウザを閉じるまで」。(=セッションクッキー)
次回ページ読み込み時には:

echo $_COOKIE['username']; // moka
4-6-4. Cookie の削除

有効期限を「過去の時刻」に設定すると削除されます。

例文

setcookie("username", "", time() - 3600);

または

unset($_COOKIE['username']);

※ただし、unset() はサーバー側の一時的な削除で、ブラウザからは消えません

4-7. $_SESSION

$_SESSION は PHP でユーザーごとの状態(ログイン情報など)をサーバー側に安全に保持するための仕組みです。
Cookieよりもセキュアで、ユーザーごとにデータを一時的に保存できるのが特徴です。

Cookieデータをクライアント(ブラウザ)側に保存する
Sessionデータをサーバー側に保存する

セッションとクッキーの違い(比較表)

比較項目セッション ($_SESSION)クッキー ($_COOKIE)
保存場所サーバークライアント(ブラウザ)
容量制限大きめ(サーバー依存)約4KBまで
セキュリティ高い(情報はサーバー側)低い(改ざん可能)
有効期限通常ブラウザを閉じるまで任意で設定可能
用途ログイン、カート、状態保持などユーザー設定や追跡情報

Sessionを使うと、例えばこんなことができます。

  • ログイン状態を維持
  • 買い物カート情報を保持
  • フォームの入力値を一時的に保存
4-7-1. 基本構文

基本構文

<?php
session_start(); // セッションを開始
$_SESSION['キー名'] = 値; // セッション変数を保存
?>

例文1

<?php
session_start(); // セッション開始

$_SESSION['username'] = 'moka';
echo $_SESSION['username']; // moka
?>

これで、$_SESSION['username'] の値は同じブラウザ内で他のページでも使えます。

例文2
ページをまたいでデータ共有
page1.php

<?php
session_start();
$_SESSION['user'] = 'moka';
echo "ユーザーを登録しました!";

page2.php

<?php
session_start();
echo "こんにちは、" . $_SESSION['user'] . "さん!";

出力:

こんにちは、mokaさん!
4-7-2. セッションの仕組み(流れ)

session_start() を呼ぶと、サーバーが「セッションID」を発行。

② そのIDがCookie(PHPSESSID)としてブラウザに送られる。

③ 次のリクエスト時に、そのIDをもとにサーバーが該当データを復元。

つまり、実際のデータはサーバー上に保存され、クライアント側には「セッションID」だけ保存される。

4-7-3. セッションIDの確認

セッションIDの確認は以下のように行います。

session_start();
echo session_id(); // 現在のセッションIDを表示
4-7-4. セッションの有効期限

デフォルトでは ブラウザを閉じるまでであり、変更する場合は php.ini またはコードで設定できます。

ini_set('session.gc_maxlifetime', 3600); // 1時間
session_start();
4-7-5. セッションを削除する

セッションを削除するには、以下のように行います。

セッション変数をすべて削除

session_unset();

セッション自体を破棄

session_destroy();
4-7-6. セッションデータの保存先

PHPはデフォルトで、セッション情報をサーバー上の一時ディレクトリに保存します。
確認するには:

echo session_save_path();

出力例:

/var/lib/php/sessions

データベース連携

1. データベース
2. データベース操作を行うSQL
3. PHPからデータベースに接続
4. 例外処理
5. PDO接続オプション
6. mysqlにおけるSQLクエリの発行
7. 名前付きパラメータと名前なしパラメータ
8. 仮想テーブル(結果セットの取得)
9. パラメータ値のバインド
10. トランザクション処理

1. データベース

1-1. データベースとは

データベース とは、大量のデータを効率的に保存・検索・更新・削除できるように整理されたデータの集まりのことです。
簡単に言うと、**データをしまっておく「倉庫」**のようなものです。
ただし、単なる倉庫ではなく、「探しやすく・取り出しやすく・整った形で保管」されるのがポイントです。
以下のこのような表(テーブル)形式でデータを整理しておくのが代表的なデータベースの形です。

ID名前年齢住所
1田中太郎30東京
2鈴木花子25大阪
3佐藤健28福岡

1-2. データベースの主な特徴

  1. 大量のデータを扱える
    数百万件以上のデータでも、高速に検索や処理が可能です。
  2. 複数人で同時利用ができる
    システム全体で共有でき、同時に読み書きしても整合性を保ちます。
  3. 安全性が高い
    権限管理やバックアップ機能があり、重要なデータを守ります。
  4. 整合性(データの正しさ)を保証
    データの矛盾を防ぐルール(整合性制約)が設けられます。

1-3. データベースの種類

データベースには、以下のような種類があります。

種類代表例特徴
リレーショナルデータベース(RDB)MySQL, PostgreSQL, Oracle, SQLiteデータを表形式で管理(もっとも一般的)
NoSQLデータベースMongoDB, Redis, Cassandra柔軟な構造、ビッグデータやリアルタイム処理に強い
クラウドデータベースAWS RDS, Google Cloud SQLクラウド上で管理・スケールしやすい

ここでは、リレーショナルデータベース(RDB)に絞って解説していきます。

1-4. リレーショナルデータベース(RDB)

1-4-1. リレーショナルデータベース(RDB)とは

リレーショナルデータベース(Relational DataBase:RDB) とは、データを**「表(テーブル)」の形で管理するデータベース**のことです。
そして、その表同士を「関係(リレーション)」でつなげて扱えるのが特徴です。

RDBでは、データを「表(テーブル)」に分けて保存します。
各テーブルは「行(レコード)」と「列(カラム)」から構成されています。

id名前年齢都市
1田中太郎30東京
2鈴木花子25大阪
3佐藤健28福岡

このように、1件のデータが1行で表されます。

1-4-2. 主なリレーショナルデータベース製品

主なリレーショナルデータベース製品は以下があります。

製品名特徴
MySQL無料・Webシステムで人気(WordPressなど)
PostgreSQL高機能でオープンソース、企業システム向け
Oracle Database商用で強力、銀行や大企業で多い
SQLite軽量でスマホアプリや小規模開発に最適
Microsoft SQL ServerWindows環境で使われることが多い

2. データベース操作を行うSQL

SQLはデータを管理するソフトウェアであるデータベースを操作および制御するための言語です。膨大なデータをデータベースで一元管理し、さまざまなシステムからデータベース内のデータを用いることで、業務を効率よく行うことができます。

SQLは多くの命令を用いてデータベースを扱います。命令は大きく3つに分類されます。

DDLデータ定義言語
DMLデータ操作言語
DCLデータ制御言語

2-1. DDL(データ定義言語)

DDL(Data Definition Language) とは、データベースの構造(設計)を定義・変更するためのSQL文のことです。
つまり、「データを入れる入れ物(テーブルやデータベース)」を作ったり、その形を変更・削除するために使います。

DDLで使う主な命令(SQL)

コマンド意味
CREATE新しく作るテーブルやデータベースを作成
ALTER構造を変更カラムを追加・削除・型変更
DROP削除テーブルやデータベースを削除
TRUNCATE中身を全削除テーブルのデータだけを一括削除(構造は残る)

2-2. DML(データ操作言語)

DML(Data Manipulation Language) とは、データベースの中にあるデータを操作するためのSQL文のことです。
つまり、データを「登録・更新・削除・検索」する命令をまとめたものです。

主なDMLのコマンド

コマンド目的内容
SELECT検索データを取り出す
INSERT追加新しいデータを登録する
UPDATE更新既存のデータを変更する
DELETE削除データを消す

2-3. DCL(データ制御言語)

DCL(Data Control Language) とは、データベースのアクセス権限やセキュリティを制御するためのSQL文です。
つまり、「誰が」「どのデータベースやテーブルに」「何をできるか」を設定します。

主なDCLコマンド

コマンド意味説明
GRANT権限を与えるユーザーに操作権限を付与
REVOKE権限を取り消す付与した権限を削除

2-4. TCL(トランザクション制御言語)

TCL(Transaction Control Language) とは、データベースの操作を確定させたり取り消したりするためのSQL文のことです。
つまり、DMLで行った操作(INSERT・UPDATE・DELETEなど)を**「本当に反映するか」「なかったことにするか」**を制御します。

主なTCLコマンド

コマンド意味説明
COMMIT確定トランザクションの内容をデータベースに反映
ROLLBACK取り消しトランザクションの内容をすべて取り消す
SAVEPOINT保存点トランザクション内で途中の状態を記録
ROLLBACK TO SAVEPOINT保存点まで戻す一部だけ取り消す
2-4-1. トランザクションとは

トランザクションは、データベースに対する一連の操作のまとまりです。

  • すべて成功すれば「確定」
  • 途中で失敗したら「元に戻す」

例えると:

  • 銀行で振込する場合:
    1. A口座からお金を引き落とす
    2. B口座にお金を入れる
      → この2つがセットで成功しなければ意味がない
      → 失敗した場合は元に戻す

3. PHPからデータベースに接続

PHPでデータベース接続する方法として、主に2つあります。

方法説明
mysqliMySQL専用、手軽で標準的
PDO(PHP Data Objects)複数のDB対応、オブジェクト指向

3-1. mysqliで接続する方法

mysqliで接続する構文は以下のとおりです。

new mysqli($host, $user, $password, $dbname);

$host:サーバー名
$user:ユーザー名
$password:パスワード
$dbname:データベース名

例文1
DB接続

<?php
$host = "localhost";      // サーバー名
$user = "root";           // ユーザー名
$password = "password";   // パスワード
$dbname = "testdb";       // データベース名

// 接続
$conn = new mysqli($host, $user, $password, $dbname);

// 接続確認
if ($conn->connect_error) {
    die("接続失敗: " . $conn->connect_error);
}
echo "接続成功!";

// 接続終了
$conn->close();
?>
  • new mysqli(...) で接続オブジェクトを作成
  • $conn->connect_error で接続エラーを確認
  • $conn->close() で接続を閉じる

例文2
SELECT文実行

$sql = "SELECT id, name, age FROM users";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        echo "ID: ".$row["id"]." 名前: ".$row["name"]." 年齢: ".$row["age"]."<br>";
    }
} else {
    echo "データなし";
}
  • $conn->query($sql) でSQLを実行
  • fetch_assoc() で1行ずつ連想配列として取得

3-2. PDOで接続する方法

PDOは 複数のDBに対応 しており、オブジェクト指向で扱えるので、より拡張性があります。
PDOで接続する構文は以下のとおりです。

new PDO($dsn, $user, $password);

$dsn:サーバー名, データベース名, 文字コード
$user:ユーザー名
$password:

例文1
DB接続

<?php
$host = "localhost";      // サーバー名
$user = "root";           // ユーザー名
$password = "password";   // パスワード
$dbname = "testdb";       // データベース名

// 接続
$conn = new mysqli($host, $user, $password, $dbname);

// 接続確認
if ($conn->connect_error) {
    die("接続失敗: " . $conn->connect_error);
}
echo "接続成功!";

// 接続終了
$conn->close();
?>
  • new mysqli(...) で接続オブジェクトを作成
  • $conn->connect_error で接続エラーを確認
  • $conn->close() で接続を閉じる

例文2
SELECT文実行

$sql = "SELECT id, name, age FROM users";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        echo "ID: ".$row["id"]." 名前: ".$row["name"]." 年齢: ".$row["age"]."<br>";
    }
} else {
    echo "データなし";
}
  • $conn->query($sql) でSQLを実行
  • fetch_assoc() で1行ずつ連想配列として取得

4. 例外処理

例外処理とは、プログラムの実行中に予期せぬエラー(例外)が発生した場合に、適切に対応する仕組みです。

  • 例外が発生 → プログラムが突然止まるのを防ぐ
  • エラーに応じて処理を分けることができる

PHPでは try-catch構文 を使います。

4-1. 基本構文

基本構文

try {
    // 例外が発生する可能性のある処理
} catch (Exception $e) {
    // 例外発生時の処理
    echo "エラー発生: " . $e->getMessage();
} finally {
    // 成功・失敗に関わらず必ず実行される処理
}
  • try ブロック:例外が発生する可能性のある処理
  • catch ブロック:例外発生時の処理
  • finally ブロック:例外の有無に関わらず必ず実行(省略可能)

例文
PDOでの例外処理

<?php
$dsn = "mysql:host=localhost;dbname=testdb;charset=utf8";
$user = "root";
$password = "password";

try {
    $pdo = new PDO($dsn, $user, $password);
    // エラーを例外として扱う
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    echo "接続成功!";

    // SQL実行例
    $sql = "SELECT * FROM users";
    $stmt = $pdo->query($sql);
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        echo $row['name'] . "<br>";
    }

} catch (PDOException $e) {
    // データベース接続やSQLエラー時の処理
    echo "データベースエラー: " . $e->getMessage();
} catch (Exception $e) {
    // それ以外の例外処理
    echo "一般エラー: " . $e->getMessage();
} finally {
    // 接続終了
    $pdo = null;
}
?>
  • PDOException:PDO特有の例外
  • Exception:すべての一般例外
  • finally$pdo = null; を実行し、接続を確実に閉じる

4-2. 例外クラスで呼び出せるメソッド

PHPの 例外クラス(Exception クラス) は、発生した例外の情報を取得するための便利なメソッドが用意されています。
ここでは代表的なものをまとめます。

メソッド説明
getMessage()例外のメッセージ文字列を取得
getCode()例外コードを取得(数値や任意の値)
getFile()例外が発生したファイル名を取得
getLine()例外が発生した行番号を取得
getTrace()例外発生時のスタックトレース(配列)を取得
getTraceAsString()スタックトレースを文字列で取得
4-2-1. getMessage()

getMessage()の実装方法は以下のような感じです。

try {
    throw new Exception("エラーが発生しました", 100);
} catch (Exception $e) {
    echo $e->getMessage();  // エラーが発生しました
}
4-2-2. getCode()

getCode()の実装方法は以下のような感じです。

try {
    throw new Exception("エラー発生", 404);
} catch (Exception $e) {
    echo $e->getCode();  // 404
}
4-2-3. getFile() と getLine()

getFile() と getLine()の実装方法は以下のような感じです。

try {
    throw new Exception("テストエラー");
} catch (Exception $e) {
    echo "File: " . $e->getFile(); // 例外が発生したファイル
    echo " Line: " . $e->getLine(); // 行番号
}
4-2-4. getTrace() と getTraceAsString()

getTrace() と getTraceAsString()の実装方法は以下のような感じです。

function a() {
    b();
}

function b() {
    throw new Exception("トレース例外");
}

try {
    a();
} catch (Exception $e) {
    print_r($e->getTrace());           // 配列形式のスタックトレース
    echo $e->getTraceAsString();       // 文字列形式のスタックトレース
}

ログ出力やデバッグにメソッドを使って詳細情報を取得します。開発中は getMessage()getTraceAsString() を使い、本番ではユーザー向けに安全なメッセージに置き換えましょう。

4-3. 例外処理のポイント

① 必ずtry-catchで囲む
→ データベース接続や外部API呼び出しなど、失敗する可能性のある処理は必須

② finallyでリソース解放
→ 接続終了やファイルクローズなどを確実に行う

③ 特定の例外から順にcatch
→ 具体的な例外から一般例外の順で書く

④ ユーザー向けには詳細を出さない
$e->getMessage() は開発時のみ、公開用では安全なメッセージに置き換える

5. PDO接続オプション

PHPでPDOを使ってデータベースに接続する場合、接続オプションsetAttribute メソッド を使うと動作やエラー処理を細かく制御できます。

  • エラーの扱い方
  • フェッチモード(取得方法)
  • トランザクションの挙動

5-1. 接続時にオプションを指定

以下のように、接続時にオプションを指定します。

$dsn = "mysql:host=localhost;dbname=testdb;charset=utf8";
$user = "root";
$password = "password";

// オプション配列を用意
$options = [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,   // エラーを例外として投げる
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // デフォルトの取得方法を連想配列に
    PDO::ATTR_EMULATE_PREPARES => false           // ネイティブのプリペアドステートメントを使用
];

$pdo = new PDO($dsn, $user, $password, $options);

5-2. 接続後にオプションを指定

接続後にオプションを指定するには、setAttribute メソッドを使用します。

$pdo->setAttribute(定数, 値);
  • 定数:設定するオプション(例:PDO::ATTR_ERRMODE
  • :オプションの値(例:PDO::ERRMODE_EXCEPTION

代表的なPDO属性

定数説明
PDO::ATTR_ERRMODEエラー時の動作PDO::ERRMODE_SILENT / PDO::ERRMODE_WARNING / PDO::ERRMODE_EXCEPTION
PDO::ATTR_DEFAULT_FETCH_MODEデフォルトの取得モードPDO::FETCH_ASSOC / PDO::FETCH_NUM / PDO::FETCH_OBJ
PDO::ATTR_EMULATE_PREPARESプリペアドステートメントをエミュレートするかtrue / false
PDO::ATTR_PERSISTENT持続的接続(再利用)true / false
PDO::ATTR_AUTOCOMMIT自動コミットの有無true / false

例文

$pdo = new PDO($dsn, $user, $password);

// エラーを例外で扱う
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// デフォルト取得方法を連想配列に
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

// ネイティブプリペアドステートメントを使用
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

※接続時にオプション配列でまとめても、setAttribute で後から設定してもOKです。

6. mysqlにおけるSQLクエリの発行

PHPで PDOやmysqli を使ってSQLを発行する場合、SQLクエリの発行を行うメソッドが用意されています。

6-1. PDOの場合

メソッド説明使いどころ
query()単純なSQL文を実行し、結果セットを返す主に SELECT の取得
exec()SQL文を実行し、影響のあった行数を返すINSERT / UPDATE / DELETE など結果の取得が不要な場合
prepare()プリペアドステートメントを準備SQLインジェクション対策に必須
execute()prepare() で準備したステートメントを実行値をバインドして実行
beginTransaction()トランザクション開始複数操作をまとめて実行
commit()トランザクション確定成功時に確定
rollBack()トランザクション取り消しエラー発生時に元に戻す

例文
INSERTを安全に実行

$sql = "INSERT INTO users (name, age, city) VALUES (:name, :age, :city)";
$stmt = $pdo->prepare($sql);
$stmt->execute([':name'=>'田中太郎', ':age'=>30, ':city'=>'東京']);

6-2. mysqliの場合

メソッド説明使いどころ
query()単純なSQL文を実行SELECT / INSERT / UPDATE / DELETE
multi_query()複数のSQLをまとめて実行複数のSQLを一度に発行
prepare()プリペアドステートメントを準備安全なINSERT/UPDATE/DELETE
bind_param()値をバインドプリペアドステートメント実行前
execute()プリペアドステートメントを実行バインドした値で実行
begin_transaction()トランザクション開始複数操作をまとめる
commit()トランザクション確定成功時に確定
rollback()トランザクション取り消しエラー時に元に戻す

例文
プリペアドステートメント

$stmt = $mysqli->prepare("INSERT INTO users (name, age, city) VALUES (?, ?, ?)");
$stmt->bind_param("sis", $name, $age, $city);
$name = '佐藤健';
$age = 28;
$city = '福岡';
$stmt->execute();

7. 名前付きパラメータと名前なしパラメータ

7-1. 名前付きパラメータ

SQL文で :param名 を使って値を置き換えることができます。これは、値は 名前で指定 するので順番は関係なく、同じ値を複数回使う場合も便利です。
例文

$sql = "INSERT INTO users (name, age, city) VALUES (:name, :age, :city)";
$stmt = $pdo->prepare($sql);

$stmt->bindParam(':name', $name);
$stmt->bindParam(':age', $age);
$stmt->bindParam(':city', $city);

$name = "鈴木花子";
$age  = 25;
$city = "大阪";

$stmt->execute();

7-2. 名前なしパラメータ

SQL文の中で ? を使って値を置き換えることができます。値は 順番通りにバインド します。
例文

$sql = "INSERT INTO users (name, age, city) VALUES (?, ?, ?)";
$stmt = $pdo->prepare($sql);

// bindParamで順番に値を設定
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $age);
$stmt->bindParam(3, $city);

$name = "田中太郎";
$age  = 30;
$city = "東京";

$stmt->execute();

8. 仮想テーブル(結果セットの取得)

8-1. 結果セットの取得

結果セットとは、SQLを実行したときに返ってくるデータの集合 のことで、典型的には SELECT文の実行結果 が該当します(行(レコード)と列(カラム)で構成される表のようなデータ)。

例えば、以下のテーブルがあります。

SELECT id, name, age FROM users WHERE city = '東京';

以下のような表(結果セット)が返ります。

idnameage
1田中太郎30
2鈴木花子25

PHPで結果セットを取得します。

$stmt = $pdo->query("SELECT id, name, age FROM users");
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    echo $row['id'] . ":" . $row['name'] . ":" . $row['age'] . "<br>";
}
  • fetch()fetchAll() で1行ずつ、またはすべてまとめて取得可能
    →これが 結果セットの取得 にあたります。

8-2. 仮想テーブル

仮想テーブルとは、実際のテーブルではなく SQLの中で一時的に作られた表のことで、主に サブクエリ(副問い合わせ)ビュー(VIEW) で利用されます。
メモリ上で作られる一時的な表 で、実際のテーブルにデータをコピーするわけではない。

例文1
サブクエリで仮想テーブルを作る

SELECT v.city, AVG(v.age) AS avg_age
FROM (SELECT * FROM users WHERE age > 20) AS v
GROUP BY v.city;
  • (SELECT * FROM users WHERE age > 20)仮想テーブル
  • AS v で名前を付けて外側のSELECTで利用可能

例文2
ビューとして仮想テーブル

CREATE VIEW adult_users AS
SELECT * FROM users WHERE age >= 20;

-- VIEWを普通のテーブルのように利用
SELECT name, city FROM adult_users WHERE city = '東京';
  • adult_users仮想テーブル
  • 実際のデータは users にあるが、条件付きで簡単に再利用できる

8-3. 結果セットから取得する方法

8-3-1. fetch メソッド

SQLの SELECT文の結果セットから1行ずつ取り出すメソッドで、PDOStatementオブジェクトに対して使用します。

$row = $stmt->fetch($fetch_style);

$fetch_style には取得形式を指定します

定数説明
PDO::FETCH_ASSOC連想配列(カラム名をキーに取得)
PDO::FETCH_NUM数値配列(カラム番号で取得)
PDO::FETCH_BOTH連想配列 + 数値配列(デフォルト)
PDO::FETCH_OBJオブジェクト(プロパティ名がカラム名)
PDO::FETCH_COLUMN指定した列だけを取得(引数で列番号指定)

例文1
連想配列で取得

$stmt = $pdo->query("SELECT id, name, age FROM users");

while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    echo $row['id'] . ":" . $row['name'] . ":" . $row['age'] . "<br>";
}
  • $row['カラム名'] で値にアクセス
  • ループで1行ずつ処理可能

例文2
オブジェクト形式で取得

$stmt = $pdo->query("SELECT id, name, age FROM users");

while ($user = $stmt->fetch(PDO::FETCH_OBJ)) {
    echo $user->id . ":" . $user->name . ":" . $user->age . "<br>";
}
  • $user->カラム名 でアクセス
  • オブジェクト指向的に扱いやすい
8-3-2. fetchAll メソッド

結果セットをまとめて取得したい場合 に使用でき、配列の配列(または配列のオブジェクト)で返えします。
例文

$stmt = $pdo->query("SELECT * FROM users");
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);

foreach ($users as $row) {
    echo $row['name'] . "<br>";
}

8-3-3. フェッチモード

SQLの結果セットをどの形式で取得するか を指定するオプションで、PDOの fetch()fetchAll() で使います。
代表的なフェッチモード

定数説明使用例
PDO::FETCH_ASSOC連想配列(カラム名をキー)$row['name']
PDO::FETCH_NUM数値配列(カラム順で取得)$row[0]
PDO::FETCH_BOTH連想配列 + 数値配列(デフォルト)$row[0] / $row['name']
PDO::FETCH_OBJオブジェクト(プロパティ名がカラム名)$row->name
PDO::FETCH_COLUMN指定した列だけを取得$row = $stmt->fetch(PDO::FETCH_COLUMN, 1)
PDO::FETCH_KEY_PAIR1列目をキー、2列目を値にした連想配列$array[$key] = $value
PDO::FETCH_CLASS指定したクラスのオブジェクトとして取得$obj->プロパティ名

8-3-4. fetchColumnメソッド

SELECT結果の特定の列(カラム)だけを取得でき、1行ずつ値を返します。
引数で取得したい列番号(0始まり)を指定可能で、単純な集計や特定カラムの取得に便利です。

$value = $stmt->fetchColumn($column_number = 0);

8-3-5. fetchObjectメソッド

SQL結果の1行をオブジェクトとして返し、カラム名が オブジェクトのプロパティ名 になります。
クラス名を指定すると、そのクラスのインスタンスとして返すことも可能で、1行ずつ取得します。

$obj = $stmt->fetchObject($class_name = "stdClass", $ctor_args = []);
  • $class_name : 作成するオブジェクトのクラス名(省略時は stdClass
  • $ctor_args : コンストラクタに渡す引数(指定クラスの場合)

9. パラメータ値のバインド

9-1. パラメータ値のバインド

パラメータ値のバインドとは、SQLに直接値を埋め込むのではなく、変数をバインドして安全にSQLを実行する方法です。
SQLインジェクション対策として非常に重要です。

例文

<?php
// PDO接続
$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8';
$user = 'root';
$password = '';
$pdo = new PDO($dsn, $user, $password);

// SQL文を準備(? はプレースホルダ)
$sql = "SELECT * FROM users WHERE id = ? AND status = ?";
$stmt = $pdo->prepare($sql);

// パラメータをバインド
$id = 5;
$status = 'active';
$stmt->bindValue(1, $id, PDO::PARAM_INT);       // 1番目の ? に $id をバインド
$stmt->bindValue(2, $status, PDO::PARAM_STR);   // 2番目の ? に $status をバインド

// 実行
$stmt->execute();

// 結果取得
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($result);
?>

9-2. bindParamメソッド と bindValueメソッド

bindParamメソッド と bindValueメソッドには以下の特徴があります。

メソッド特徴
bindValue値を直接バインド。実行時に値を固定するので安全。
bindParam変数そのものをバインド。実行時に変数の値を評価。ループで使うと便利。

例文

$stmt = $pdo->prepare("INSERT INTO users (name) VALUES (:name)");
$name = "Alice";
$stmt->bindParam(':name', $name);
$name = "Bob";
$stmt->execute(); // このとき :name は "Bob" になる

10. トランザクション処理

トランザクション処理 は、複数のSQL処理をまとめて「全て成功したら反映、どれか失敗したら全部取り消す」ために使います。
以下のメソッドが用意されています。

メソッド説明
$pdo->beginTransaction()トランザクション開始
$pdo->commit()正常終了した場合に確定
$pdo->rollBack()エラー発生時に元に戻す
$pdo->inTransaction()現在トランザクション中か確認

例文

<?php
try {
    $dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8';
    $user = 'root';
    $password = '';
    $pdo = new PDO($dsn, $user, $password);

    // トランザクション開始
    $pdo->beginTransaction();

    // SQL1
    $stmt1 = $pdo->prepare("INSERT INTO accounts (name, balance) VALUES (?, ?)");
    $stmt1->execute(['Alice', 1000]);

    // SQL2
    $stmt2 = $pdo->prepare("INSERT INTO accounts (name, balance) VALUES (?, ?)");
    $stmt2->execute(['Bob', 2000]);

    // 問題なければコミット(確定)
    $pdo->commit();
    echo "トランザクション成功";

} catch (Exception $e) {
    // エラー発生時はロールバック(取り消し)
    $pdo->rollBack();
    echo "トランザクション失敗: " . $e->getMessage();
}
?>