23

Windows 7、Apache 2、PHP 5、MySQL 5 を使用していますが、すべて同じマシン上にあります。興味深い問題が見つかりました。次のコードがあります。

    $sql = "select * from user1";
    $conn = mysql_connect("localhost", "root", "xxxxxxxx");
    mysql_select_db("test1");
    mysql_query("set names utf8");
    $result = mysql_query($sql, $conn);
    while ($row = mysql_fetch_assoc($result)){
        foreach ($row as $key => $value){
            echo $key." => ".$value." || ";
        }
        echo "<br/>";
    }
    mysql_free_result($result);
    mysql_close($conn);

上記のコードの実行時間は 1 秒を超えています。

127.0.0.1の代わりに使用するとlocalhost、実行時間は約 10 ms です。

インターネットで根本的な理由を見つけようとしましたが、これが結果です。

最近、開発を XP から Windows 7 に移行したところ、開発した Web ページの読み込みに 5 秒かかっていました。もちろん、これは受け入れられないので、問題を追跡する必要がありました。最終的に、問題のある関数/メソッド pdo::construct を突き止めました。また、mysql_connect が接続を確立するのに約 1 秒かかっていることもわかりました。少しグーグルで調べたところ、php には IPv6 に関する問題があり、IPv6 を無効にするか、接続時に IP アドレス 127.0.0.1 に切り替えることで問題を解決できるという説明が見つかりました。

PHP での IPv6 の問題は何なのだろうか、もっと深く理解したいだけです。ありがとう。

4

2 に答える 2

29

PHP が localhost への接続を開こうとしています。お使いのコンピュータは IPv6 経由でネットワークに接続されているため、最初に「localhost」の IPv6 バージョンが試行されます。これは ::1 の IP アドレスです。

http://en.wikipedia.org/wiki/IPv6_address#Special_addresses

::1/128 — ループバック アドレスはユニキャスト localhost アドレスです。ホスト内のアプリケーションがこのアドレスにパケットを送信すると、IPv6 スタックはこれらのパケットを同じ仮想インターフェイス (IPv4 の 127.0.0.0/8 に対応) にループバックします。

MySQL サーバーはそのアドレスをリッスンしていないようです。代わりに、IPv4 アドレスにのみバインドされているため、PHP が接続を開くことができないと、フォールバックし、IPv4 aka 127.0.0.1 経由で localhost を開こうとします。

個人的には、IP アドレスを使用するか、Windows のホスト ファイルまたは Mac に相当するものを使用して「偽の」ドメイン名を定義し、MySQL に接続するときに IP アドレスに解決されるドメイン名を使用することを好みます。いずれにせよ、IPv4 アドレスと IPv6 アドレスのどちらが使用されるかを正確に知ることができます。

MySQL と Apache はどちらも IPv6 をサポートしていますが、IPv6 アドレスを明示的に使用するように指示する必要があります。MySQL については、http: //dev.mysql.com/doc/refman/5.5/en/ipv6-server-config.htmlを参照してください。

Apache 構成については、http: //httpd.apache.org/docs/2.2/bind.htmlを参照してください。

Apache は複数の IP アドレスをサポートしているため、マシンのネットワーク カードに IPv4 と IPv6 の両方のアドレスがある場合は、両方を同時に使用できます。MySQL は 1 つのアドレスのみをサポートします。

于 2012-07-26T10:21:51.973 に答える
11

PHPはWindows7/8/10で「localhost」に接続しようとしています。::1ですが、MySQLはIPv6ソケットをリッスンしていません。いくつかの修正を適用できます:

1)ホストファイル(C:/ windows / system32 / drivers / etc / host)でlocalhostを127.0.0.1に設定します

2)PHPでは、MySQLサーバーがlocalhostから127.0.0.1に変更されます

3)my.iniで、次を追加または編集します。bind-address = ::

アドレスが::の場合、サーバーはすべてのサーバーホストのIPv4およびIPv6インターフェイスでTCP/IP接続を受け入れます。このアドレスを使用して、すべてのサーバーインターフェイスでIPv4接続とIPv6接続の両方を許可します。

MySQL>=5.5.3を使用している場合の推奨オプション

于 2012-12-28T20:12:43.817 に答える