ホームページ >バックエンド開発 >PHPチュートリアル >PHP/MySQL の localhost および 127.0.01
前の記事から引き続き、Nginx と PHP-FPM の権限セキュリティ設定の最後の段落はデータベース接続失敗の処理についてです。
以前 WordPress を設定したとき、mysql 接続に tcp を使用したいと思い、グーグルで答えを見つけました。
define('DB_HOST', '127.0.0.1');
しかし、wp-config には注意を払いませんでした。 1 つの構成:
define('DB_HOST', 'localhost');
その後、Discuz フォーラムの権限処理を行っていたときに、mysql も Unix ドメイン ソケットを使用しているため、その方法を知りたいと思いました。そのとき、localhost が設定されていることがわかり、ポートを割り当てて tcp を強制するかどうかを常に考えていました。
長い間苦労しましたが、それでも動作しませんでした。エラー レポートから PHP コードを直接見つけ、最終的に mysql_connect() 関数を見つけました。
ドキュメントを読んだ後、何も問題がなかったので、何気なく localhost を 127.0.0.1 に変更したところ、突然動作することに気づき、興奮しましたが、同時に奇妙にも感じました。
最初は、PHP が localhost に対して特別な処理を実行し、それを mysql sock パスに直接解析したためだと思いました。
今日の仕事を終えてから、この問題を振り返ります。
まだローカルに PHP-FPM chroot 分離環境を作成しています。テスト スクリプト:
root@gentoo-local /var/www/test % cat index.php<meta charset="utf-8"><?php define('DB_HOST','localhost'); //define('DB_HOST','127.0.0.1'); define('DB_USER','root'); define('DB_PWD','******'); $connect = mysql_connect(DB_HOST, DB_USER, DB_PWD) or die('数据库连接失败,错误信息:'.mysql_error()); echo $connect;?>
昨日と同じですが、localhost の場合は失敗します。localhost:3306 も失敗します。大丈夫です。
どの作品が問題なのか分かっているので、検索するとどんどん正解に近づきます。
それで私はこの答えを見つけました 警告: mysql_connect(): [2002] そのようなファイルまたはディレクトリはありません。その中に次の文があります:
その理由は、「localhost」がmysql ドライバーの特別な名前で、tcp ソケットの代わりに unix ソケットを使用して mysql に接続します。
ここでこれが言われているのは、mysql の localhost 解析の問題のためです。これは、PHP によって解析されるという以前の推測と矛盾します。
ローカルの mysql コマンド ライン クライアント テスト。通常の状況では、次の両方が OK です (-h localhost はデフォルトのメソッドであり、指定できません):
$ mysql -h localhost -u root -p # OK$ mysql -h 127.0.0.1 -u root -p # OK
localhost は / であるため、 etc/hosts で定義されているため、このブロックを一時的にコメントアウトします。当然、localhost は意味のない文字列になります。再試行してください:
$ mysql -h localhost -u root -p # OK$ mysql -h 127.0.0.1 -u root -p # OK
どちらもまだ問題ないため、原因は mysql ドライバーにあると判断できます。データベースへのアクセス ホストの解析に問題があります。
さらに、lsof を介して接続プロセスの通信を確認することもできます。
# localhostmysql 27971 tankywoo 3u unix 0xffff880078d25540 0t0 371911 type=STREAM# 127.0.0.1mysql 28249 tankywoo 3u IPv4 373797 0t0 TCP localhost:50187->localhost:mysql (ESTABLISHED)
経験によれば、ホストが非ホストの場合、localhost と 127.0.0.1 は同等です。 IP アドレス、両方とも解析操作を試行します。 MySQL は、UNIX ドメイン ソケットの方が効率的であると考えているため、デフォルトで localhost を処理します。
しかし、この種の扱いはあまりにも不明確というか曖昧なので、「穴」の性質の方が大きいような気がします。
このトピックを検索したところ、多くの人がこの問題に遭遇していることがわかりました。たとえば、上記の StackOverflow の回答には 300 近くの賛成票がありました。
:(