PHP

PHPでMySQL接続をmysqliとPDOへ移行する方法とエラー対策

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

お得なお知らせ

スポンサードリンク
AI時代のキャリア構築

プログラミング学習、今日から動き出す

「何から始めるか」で止まっている人こそ、無料説明会や本で自分に合うルートを30分で確定できます。

Enjoy Tech!|月額制でWeb系に強い▶ (Kindle本)ITエンジニアの転職学|後悔しないキャリア戦略▶

▶ AIコーディング環境なら  実践Claude Code入門(Amazon)が実務で即使える入門書です。Amazonベストセラーにも選ばれていますよ。


スポンサードリンク

PHP で MySQL に接続する際の最新情報と移行ポイント

PHP7 以降、mysql_* 系関数は 完全に削除 されました。現在は標準拡張として提供されている mysqliPDO_MySQL を利用します。本稿では、両者の概要・選択基準・実装例に加えて、公式ドキュメントへの参照php.ini の設定ポイント、エラーハンドリングのベストプラクティスをまとめます。

この記事は PHP 8.2 を前提に作成していますが、PHP 7.4 以上でも同様に適用できます。


1️⃣ mysql_* 系関数の廃止経緯(公式情報)

項目 内容 参考
非推奨化 (Deprecated) PHP 5.5 で mysql_connect() 等が 非推奨 とされました。 https://www.php.net/manual/ja/migration71.deprecated.php
完全削除 (Removed) PHP 7.0 で関数自体が削除され、コードは致命的エラーになります。 https://www.php.net/manual/ja/migration70.removed-functions.php

mysql_* が提供できなかった主な機能は プレースホルダー未対応例外ベースのエラーハンドリングが不可utf8mb4 への完全対応が難しい ことです。これらを補完する形で mysqliPDO が推奨されています。


2️⃣ mysqli と PDO の比較表

項目 mysqli PDO
対応 DB MySQL 系専用 40 種類以上(MySQL, PostgreSQL, SQLite, SQL Server …)
プリペアドステートメント サポート (オブジェクト/手続き型) 完全サポート、名前付きプレースホルダーあり
エラーモード mysqli_report() で例外化可能。デフォルトは戻り値チェック。 デフォルトで 例外 (PDOException) が投げられる (ERRMODE_EXCEPTION)
トランザクション制御 $mysqli->begin_transaction(), commit(), rollback() $pdo->beginTransaction(), commit(), rollBack()
永続接続 (persistent) p: プレフィックスで有効化可能。 PDO::ATTR_PERSISTENT => true で有効化
学習コスト MySQL に特化しているため低め。 複数 DB を扱う場合は学習が必要。
推奨シーン 小〜中規模の MySQL 専用アプリ、既存コードのリファクタリング マルチDB 対応、フレームワーク共通基盤、大規模プロジェクト

結論
- MySQL のみで完結するシンプルな案件mysqli が手軽。
- 将来的に他 DB へ拡張したい、または フレームワーク/ライブラリと統一的に使うPDO を選択。


3️⃣ 実装例 ― エラーハンドリングを含む接続コード

3.1 mysqli(オブジェクト指向)

ポイント
- mysqli_report() により 例外 (mysqli_sql_exception) がスローされ、if ($mysqli->connect_errno) のような戻り値チェックが不要になります。
- set_charset('utf8mb4')MySQL 側の文字セット設定であり、PHP の default_charset とは別です。


3.2 PDO(例外モード)

ポイント
- DSN の charset=utf8mb4MySQL 接続時の文字セットで、PHP の出力エンコーディングには影響しません。
- ATTR_EMULATE_PREPARES => false にすると MySQL のネイティブプリペアドステートメントが利用でき、パフォーマンスとセキュリティが向上します。


4️⃣ php.ini の重要設定(公式マニュアル参照)

設定項目 推奨値 / 説明 公式ページ
default_charset UTF-8(出力エンコーディング)※ MySQL 用の文字セットは接続時に指定する https://www.php.net/manual/ja/ini.core.php#ini.default-charset
mysqli.default_socket Unix ソケットのフルパス(例: /var/run/mysqld/mysqld.sock https://www.php.net/manual/ja/mysqli.configuration.php#ini.mysqli.default-socket
pdo_mysql.default_socket 同上 https://www.php.net/manual/ja/pdo-mysql.configuration.php#ini.pdo-mysql.default-socket
mysqli.reconnect Off(自動再接続は非推奨、手動で再接続ロジックを実装) https://www.php.net/manual/ja/mysqli.configuration.php#ini.mysqli.reconnect
log_errors / error_log 本番環境は On、ログファイルは /var/log/php_errors.log など安全な場所へ https://www.php.net/manual/ja/errorfunc.configuration.php

4‑1️⃣ default_charset の誤解を防ぐ

  • default_charset = "utf8mb4" と書くと PHP が内部的に utf8mb4 を文字列エンコーディングとして扱う という意味になり、実際にはサポート外です。
  • 正しくは default_charset = "UTF-8" とし、データベース側の文字セットは接続コード(set_charset('utf8mb4') または DSN の charset=utf8mb4)で指定します。

4‑2️⃣ mysqli.reconnect の実情

PHP 8 系でも 設定項目自体は残存していますが、公式ドキュメントは「非推奨かつ期待通りに動作しないケースが多い」旨を警告しています。したがって Off にして、接続失敗時は例外捕捉で再試行ロジックを書く ことが安全です。


5️⃣ よくある MySQL 接続エラーと対処法

エラーコード 意味・シンボル 主な原因 推奨チェック項目
2002 CR_CONNECTION_ERROR(接続タイムアウト) サーバーダウン、ポートミス、ソケットパス不一致 netstat -tlnpphp.ini の default_socket を確認
1045 ER_ACCESS_DENIED_ERROR(認証失敗) ユーザー名/パスワード誤り、ホスト制限 SELECT User, Host FROM mysql.user; で権限確認
2006 CR_SERVER_GONE_ERROR(サーバ切断) アイドルタイムアウト、ネットワーク障害 mysqli_options($link, MYSQLI_OPT_CONNECT_TIMEOUT, 5); 等でタイムアウト短縮
2013 CR_SERVER_LOST(通信エラー) 大量データ転送中の切断、ファイアウォール MySQL の max_allowed_packet 拡張、クエリ分割
1049 ER_BAD_DB_ERROR(DB 不在) DB 名ミス・削除済み SHOW DATABASES; で実在確認

実務ヒント:エラーが発生したタイミング(接続直後、クエリ実行時)をログに残すと原因特定が格段に速くなります。


6️⃣ 環境別チェックリスト

6‑1️⃣ 開発環境

  • display_errors = On → デバッグ情報を画面に出力
  • log_errors = On、ログローテーション設定(例:logrotate

6‑2️⃣ 本番環境

  • display_errors = Off(情報漏洩防止)
  • log_errors = On、エラーログは 権限 600 にし、外部から直接閲覧不可にする
  • .env ファイルは .gitignore に必ず追加

6‑3️⃣ Docker / コンテナ環境での注意点

  • コンテナ間通信は TCPhost: mysql)になるため、host にコンテナ名を指定。
  • ソケット接続が必要な場合は volumes: で MySQL のソケットファイルを共有します。

7️⃣ エラーログのベストプラクティス(機密情報除去付き)

  • 例外捕捉は必ず行うmysqli_report() で例外化すれば統一感が出ます)。
  • ログには スタックトレースや機密情報を含めないようにフィルタリングする関数を作成し、全体で使い回すと保守性が向上します。

8️⃣ WordPress 等 CMS の接続エラー切り分けフロー

手順 内容
1️⃣ デバッグモード有効化 wp-config.phpdefine('WP_DEBUG', true); define('SAVEQUERIES', true); を追加
2️⃣ プラグイン無効化 wp-content/plugins のフォルダ名を一時的に変更し、全プラグインを停止
3️⃣ テーマ切替 デフォルトテーマ(例:Twenty Twenty‑Four)へ切り替え
4️⃣ DB 設定再確認 .env または wp-config.phpDB_HOST, DB_USER, DB_PASSWORD, DB_NAME が正しいか
5️⃣ エラーログ確認 /var/log/php_errors.log やサーバーの Apache/Nginx ログで「MySQLi Connect Error」や「PDOException」を検索
6️⃣ 再現テスト 同じ環境(ローカル・ステージング)で同一設定を再度実行し、エラーが再現するか確認

ポイント:プラグインが独自に mysqli_connect() を呼び出すケースは多く、設定ミスや古いライブラリが原因になることがあります。上記手順で解消しない場合は該当プラグインの開発者へ問い合わせるか、代替プラグインを検討してください。


9️⃣ .env と最小権限ユーザーによる安全な認証情報管理

9‑1️⃣ .env の雛形(Git 管理外)

9‑2️⃣ PHP 側での読み込み(vlucas/phpdotenv 推奨)

9‑3️⃣ MySQL 側の最小権限ユーザー作成例

  • 必要最低限の権限だけを付与することで、万が一認証情報が漏洩しても被害範囲を限定できます。
  • 定期的にパスワードをローテーションし、変更後は .env を更新・デプロイパイプラインで自動反映させると運用負荷が減ります。

📚 まとめ

項目 要点
廃止された mysql_* 関数 PHP 7.0 で完全削除。公式マニュアルを必ず参照。
mysqli vs PDO MySQL 専用は mysqli、複数 DB 対応や統一コードベースは PDO が最適。
接続コード 例外化 (mysqli_report() / ATTR_ERRMODE) と utf8mb4 設定を必ず行う。
php.ini の留意点 default_charset = "UTF-8"mysqli.reconnect = Off、ソケットパスは正確に設定。
エラーハンドリング 例外捕捉+機密情報マスクしたログ出力を徹底。
.env と最小権限 認証情報はコードから分離し、DB ユーザーは必要最低限の権限だけ付与。
公式ドキュメント すべての設定・関数は https://www.php.net/ 系列で確認すること。

以上を実装・運用に取り入れることで、MySQL 接続エラーの迅速な診断と安全なデータベース連携が実現できます。ぜひプロジェクトに合わせてカスタマイズし、安定した PHP アプリケーション開発に活かしてください。

スポンサードリンク

お得なお知らせ

スポンサードリンク
AI時代のキャリア構築

プログラミング学習、今日から動き出す

「何から始めるか」で止まっている人こそ、無料説明会や本で自分に合うルートを30分で確定できます。

Enjoy Tech!|月額制でWeb系に強い▶ (Kindle本)ITエンジニアの転職学|後悔しないキャリア戦略▶

▶ AIコーディング環境なら  実践Claude Code入門(Amazon)が実務で即使える入門書です。Amazonベストセラーにも選ばれていますよ。


-PHP