
本PHPのページは、3部作となります。焦らず進めていきましょう。
リクエスト情報
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 | 不正なリクエスト |
| 401 | HTTP認証を要求 認証が必要(ログイン必須) |
| 403 | アクセス拒否(権限なし) |
| 404 | ページが存在しない |
| 405 | 許可されていないメソッド (例: GETしかないのにPOST送信) |
| 407 | HTTPメソッドが不許可 |
| 408 | リクエストタイムアウト |
3-1-5. 5xx(サーバーエラー)
サーバー側で問題が発生。
| 500 | サーバー内部エラー(PHPエラーなど) |
| 501 | 応答に必要な機能が未実装 |
| 502 | ゲートウェイやプロキシの不具合 |
| 503 | HTTPサーバーが利用不可 (メンテナンス中など) |
| 504 | ゲートウェイやプロキシのタイムアウト |
4. スーパーグローバル変数
PHPではリクエスト情報の取得/操作するためにスーパーグローバル変数という、あらかじめ用意されている連想配列の変数があります。
このスーパーグローバル変数は、主に「HTTPリクエスト情報」や「サーバー情報」を格納されており、スクリプト側ではこれを参照するだけで必要な情報を取得できます。
どのスコープ(関数内・クラス内など)からでも 必ずアクセス可能です。
スーパーグローバル変数は、主に以下のものがあります。
| スーパーグローバル変数 | 概要 |
|---|---|
| $_GET | GETリクエストで送られたデータを格納URLクエリ文字列が入る |
| $_POST | POSTリクエストで送られたデータを格納フォーム送信や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コード として実行してしまいます。
デフォルトでは以下の文字が変換されます。
| 文字 | 変換後 |
|---|---|
& | & |
< | < |
> | > |
" | " |
'(オプション指定時) | ' |
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_encode | HTMLエンティティを二重にエスケープするか |
例文
<?php
$input = '<script>alert("XSS!");</script>';
echo htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
?>
出力
<script>alert("XSS!");</script>
ブラウザに表示されるのはただの文字列になり、スクリプトは実行されません。
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 | 元のファイル名 |
type | MIMEタイプ(例: image/jpeg) |
tmp_name | 一時的に保存されたファイルのパス |
error | エラーコード(0なら成功) |
size | ファイルサイズ(バイト単位) |
4-3-3. エラーコード ($_FILES['userfile']['error'])
| 定数名 | 値 | 意味 |
|---|---|---|
UPLOAD_ERR_OK | 0 | 成功 |
UPLOAD_ERR_INI_SIZE | 1 | php.ini の upload_max_filesize を超えた |
UPLOAD_ERR_FORM_SIZE | 2 | フォームの MAX_FILE_SIZE を超えた |
UPLOAD_ERR_PARTIAL | 3 | 一部しかアップロードされなかった |
UPLOAD_ERR_NO_FILE | 4 | ファイルが選択されていない |
UPLOAD_ERR_NO_TMP_DIR | 6 | 一時フォルダが存在しない |
UPLOAD_ERR_CANT_WRITE | 7 | ディスク書き込みエラー |
UPLOAD_ERR_EXTENSION | 8 | PHP拡張でアップロードが停止された |
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'] | リクエストヘッダの Host 値 | example.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/json、multipart/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 | リダイレクト先のURL | https://example.com/login |
| Access-Control-Allow-Origin | CORS許可設定 | * 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_PASSWORD | DBパスワード | 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-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 Server | Windows環境で使われることが多い |
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. トランザクションとは
トランザクションは、データベースに対する一連の操作のまとまりです。
- すべて成功すれば「確定」
- 途中で失敗したら「元に戻す」
例えると:
- 銀行で振込する場合:
- A口座からお金を引き落とす
- B口座にお金を入れる
→ この2つがセットで成功しなければ意味がない
→ 失敗した場合は元に戻す
3. PHPからデータベースに接続
PHPでデータベース接続する方法として、主に2つあります。
| 方法 | 説明 |
|---|---|
| mysqli | MySQL専用、手軽で標準的 |
| 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 = '東京';
以下のような表(結果セット)が返ります。
| id | name | age |
|---|---|---|
| 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_PAIR | 1列目をキー、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();
}
?>
