PHP

PHP8.2 と MySQL8.0 の接続エラー対策とサンプルコード

ⓘ本ページはプロモーションが含まれています

スポンサードリンク

はじめに

PHP 8.2 では mysql_* 系関数は完全に削除され、代わりに mysqliPDO (pdo_mysql) が推奨されています。両者はそれぞれ以下の特徴があります。

項目 mysqli PDO
API 形態 手続き型とオブジェクト指向の両方が利用可 完全にオブジェクト指向
DB 抽象化 MySQL 固有 複数データベースに対応(MySQL、PostgreSQL 等)
例外処理 mysqli_report() で例外化可能 デフォルトで例外 (PDOException) をスロー

本稿では 安全性可搬性保守性 の観点から、両方の接続方法を示しつつ、実務で頻出するエラーとその対策を体系的に解説します。


mysqli と PDO の基本的な接続コード

1. mysqli(オブジェクト指向)

ポイント

  • real_connect の第5引数でポートを明示的に指定することで、Docker やカスタムポート環境でのミスを防げます。
  • mysqli_report() を有効にすると、エラーが例外として捕捉できるため、if ($mysqli->connect_errno) の分岐を書き換える必要はありません。

2. PDO(MySQL 用 DSN)

重要な修正点

  • charset=utf8mb4文字化け防止正しいバイト列での比較 を保証しますが、直接的に SQL インジェクションを防ぐわけではありません。インジェクション対策は必ず プリペアドステートメント$stmt->prepare())や パラメータバインディング で実装してください。

よくある接続エラーと対策

エラーコード 主な原因 確認すべきポイント
SQLSTATE[HY000] [2002] Connection refused MySQL が起動していない、ポートが閉じている、ホスト名が誤っている netstat -tlnp/Docker のポートマッピング、my.cnfbind-address
SQLSTATE[HY000] [1045] Access denied for user … ユーザー名・パスワード不一致、ホスト制限、認証プラグインのミスマッチ SELECT User, Host, plugin FROM mysql.user;caching_sha2_password vs mysql_native_password
SQLSTATE[HY000] [2006] MySQL server has gone away 接続タイムアウト、max_allowed_packet 超過、サーバ再起動 wait_timeoutmax_allowed_packet の設定値確認

対処フロー

  1. エラーメッセージを取得 → 例外オブジェクトのコード・メッセージをログに残す。
  2. カテゴリ判定(ネットワーク / 認証 / サーバ設定)で原因領域を絞る。
  3. 該当項目の設定を確認し、必要に応じて修正する。

環境別に注意すべき設定ミス

1. ローカル開発環境(MAMP / XAMPP 等)

誤り例 正しい対策
MySQL のデフォルトポートが 3306 と想定し、接続コードをそのまま使用する。 my.cnf で実際の port を確認し、PHP 側でも同じ番号に合わせる(例: XAMPP は 3307)。
.env に設定したパスワードと PHP のハードコーディングが食い違う。 環境変数を統一的に管理し、getenv() または vlucas/phpdotenv で読み込む。

2. Docker コンテナ

誤設定 正しい設定
docker run -p 3306:3306 mysql のみ実行し、コンテナ内部の MySQL が 127.0.0.1 にバインドしている。 my.cnfbind-address = 0.0.0.0 を追加し、外部からの接続を許可する。
アプリ側 .env が空文字列になっているが、コンテナは環境変数でパスワードを設定している。 Docker Compose の environment: と PHP 側の .env を同一に保ち、docker compose exec php env で確認する。

3. クラウド(AWS RDS / Aurora 等)

誤り 修正策
セキュリティグループでポート 3306 が閉じている、または DB インスタンスが「Publicly Accessible」になっていない。 SG のインバウンドに自分の IP/VPC CIDR を追加し、必要ならプライベートサブネットからのアクセスを許可する。
認証プラグインが caching_sha2_password だが、古いドライバーで接続できない。 PDO の場合は PHP 8.2 が対応済み。どうしても旧バージョンを使うなら ALTER USER … IDENTIFIED WITH mysql_native_password BY 'pwd'; で変更する。

トラブルシューティングの実践手順

1. PHP 拡張モジュールの有無確認

  • phpinfo() の出力でも同様に mysqlipdo_mysql が表示されているかチェック。
  • 拡張が無効の場合は php.iniextension=mysqliextension=pdo_mysql を追加し、Web サーバを再起動。

2. MySQL 側設定項目の点検

項目 確認コマンド例 推奨値 / 注意
bind-address grep bind-address /etc/mysql/my.cnf 0.0.0.0(外部接続許可)
skip-networking 同上 コメントアウトまたは削除
max_connections SHOW VARIABLES LIKE 'max_connections'; 必要に応じて増加
SSL 設定 SHOW VARIABLES LIKE '%ssl%'; 本番環境は必ず有効化
認証プラグイン SELECT User, Host, plugin FROM mysql.user WHERE User='app_user'; caching_sha2_password が推奨。旧バージョンが必要な場合は mysql_native_password に変更

3. ネットワーク診断

  • ping は ICMP が許可されていないと失敗するため、必ず TCP ポート の到達性を確認してください。

4. 例外処理とロギングのベストプラクティス

  • mysqli_report() と組み合わせれば、mysqli でも同様の例外化が可能です。

5. デバッグ用ユーティリティ(開発時だけ使用)

  • 本番環境にデプロイする際は必ず削除、もしくは if (APP_DEBUG) で囲んで無効化してください。

接続エラー即応チェックリスト

フェーズ 実施項目 確認ポイント
A. エラーメッセージ取得 mysqli_connect_error() / PDOException のコード・メッセージをログへ出力 SQLSTATEerrno が正しく記録されているか
B. 環境別原因特定 ローカル/Docker/クラウドでそれぞれの設定項目を点検 ポート・バインドアドレス・SG 設定が一致しているか
C. PHP 拡張確認 php -mphpinfo()mysqlipdo_mysql が有効か 拡張が無い場合は extension= 行を追加し再起動
D. MySQL 設定点検 my.cnfbind-addressskip-networking・認証プラグインを確認 外部接続が許可され、認証方式がクライアントと合致しているか
E. ネットワーク診断 nc -zv host portTest-NetConnection でポート到達性チェック ポートが開いていなければファイアウォール/Docker の EXPOSE を修正
F. デバッグ実行 上記ユーティリティ関数で接続テストを実施 エラーメッセージが出たら次の項目へ順に追う
G. ロギングと通知 Monolog などでエラーを永続化し、CI/CD パイプラインで検知できるよう設定 本番環境ではスタックトレースや機密情報が漏れないようフィルタリング

まとめと次のステップ

  1. 接続コードは例外化
  2. mysqli_report()PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION を必ず設定し、エラーハンドリングを一元化します。

  3. 文字セットは正しく指定

  4. charset=utf8mb4 は文字化け防止とバイト列比較の正確性向上に寄与しますが、SQL インジェクション対策は必ず プリペアドステートメント で実装してください。

  5. 環境ごとの設定ミスをリスト化

  6. ローカル、Docker、クラウドそれぞれの「ポート」「バインドアドレス」「アクセス権」のチェック項目をテンプレート化し、プロジェクト開始時に README に添付すると効果的です。

  7. ロギングとモニタリング

  8. Monolog でエラーログを永続化し、CI パイプラインや監視ツール(例: CloudWatch, Datadog)と連携させることで、接続失敗の早期検知が可能になります。

  9. 定期的な設定レビュー

  10. MySQL のメジャーバージョンアップや PHP バージョン更新時は、認証プラグイン・デフォルト文字セット・拡張モジュールの互換性を必ず確認してください。

今すぐできるアクション

アクション 内容
チェックリスト作成 本稿の表をコピーし、プロジェクトごとの docs/DB_CONNECTION_CHECKLIST.md として保存。
ロギング導入 composer require monolog/monolog を実行し、上記サンプルコードをベースにエラーログ設定を追加。
環境変数統一 .env.example に接続情報のキー(DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD)を列挙し、全開発者が同じ方式で取得できるようにする。
Docker 設定見直し docker-compose.yml の MySQL サービスに command: ["mysqld","--bind-address=0.0.0.0"] を追加し、外部からの接続を許可。

以上の手順とベストプラクティスを実装すれば、PHP 8.2 環境での MySQL 接続エラーは大幅に減少し、安定したサービス提供が可能になります。ぜひ本ガイドをチーム内で共有し、開発・運用フローに組み込んでください。

スポンサードリンク

-PHP
-, , , , , , ,