質問: stream_context_create($opts); echo file_get_contents('http://www.example.com', false, $context); ?> ``` 上記のようにコンテキストを指定しても * file_get_contents(): Invalid IP Address : [自環境のIPv6] というエラーが出てしまいます。 以下状況です。 * 当該のIPv6は17個すべてDNS逆引きが可能な状態で設定は正しいものと思います。 * IPv6、17個すべて試しましたがエラーが出ます(省略表記・フル表記どちらも)。 * 別途追加したIPv4ではコンテキスト指定(IP切り替え)に成功しています。 * 接続先のサイトはIPv6に対応しています。 どのようにしたらPHPからIPv6にて外部に出ることができますでしょうか? IP(IPv6にて)を切り替えてデータが取得できるのであれば方法はfile_get_contentsにこだわりはありません。 よろしくおねがいします。 追記 コメントにて確認頂いた件について情報を追加 * 1.ping6は成功しています。( ipv6.google.com等のサイトで成功) * 2.ip6tablesの設定は以下です。 :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p ipv6-icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m state --state NEW -m udp -p udp --dport 546 -d [ 自環境のIPv6の帯域] -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT -A INPUT -j REJECT --reject-with icmp6-adm-prohibited -A FORWARD -j REJECT --reject-with icmp6-adm-prohibited COMMIT * 3.ip6tablesを無効にしても出現するエラーに変化はありませんでした。 * 4.`php -i | grep -i ipv6`の試行結果については以下のようになりました。 $ php -i | grep -i ipv6 IPv6 Support => enabled IPv6 => Yes * 5.PHPプログラムのbindtoの部分を`'bindto' => '[0]:0'` (osに任せる)にしてみる。 エラーは出なくなりますが、別途所有するサーバに以下のようなスクリプトを用意し接続してみると、取得できるのはインターフェスeth0に紐付いたVPSレンタル時に授与されるデフォルトのIPv4でした。 ``` '[::1]:0'の試行結果は以下のようになりました。 以下のようなエラーとなりました。 file_get_contents(): Invalid IP Address: ::1 上記5.で使用した別サーバのスクリプトにて取得できたIPはデフォルトのIPv4でした。 * 7.IPアドレスとして適切な形式になってるかの確認(全角文字の有無、省略表記の誤謬) 再度確認しましたが、全角文字等の不適当な文字は入っていませんでした。 ::が:になっていないかについては、所有するIPv6にて0000で連続する領域が無いため記述はありません。 また、所有するIPv6にて「0090」のような「0」を省略できる箇所は複数ありますので、再度省略に間違いがないかを確認しました。また0を省略しないフル表記でも再度試行してみましたが、エラーは依然として出ています。 * 一応の解決? 結論から申しますと、コメントにて示唆いただいた「IPv6の直指定によるfile_get_contents」にて、IPv6コンテキスト切り替えが可能であることがわかりました。 IPv6の直指定であれば、エラーは出ず、なおかつ接続元のIPはIPv6になります。ドメイン指定でなぜエラーが出てしまうのかの疑問はありますが、現状では示唆していただいた方法で目的に叶うので一旦解決とさせていただきたいと思います。 たくさんの助言をいただきありがとう御座います。
回答: ソースコードを見ると"Invalid IP Address"になるのは文字列がIPアドレスとして適切な形式になっていない場合なので、その点を確認してください。 ・全角文字を紛れ込ませていないか ・0を省略する`::`が`:`になっていないか など もう一つ、接続先がIPv4の場合、IPv6アドレスを表記していてもIPv4として解釈しようとしてやはり"Invalid IP Address"になります。 ``` $ host www.google.com www.google.com has address 173.194.126.209 www.google.com has address 173.194.126.212 www.google.com has address 173.194.126.208 www.google.com has address 173.194.126.210 www.google.com has address 173.194.126.211 www.google.com has IPv6 address 2404:6800:4004:808::1010 file_get_contents('http://www.google.com', false, $context); // => no warning $ host www.yahoo.co.jp www.yahoo.co.jp is an alias for www.g.yahoo.co.jp. www.g.yahoo.co.jp has address 182.22.72.251 www.g.yahoo.co.jp has address 183.79.197.250 www.g.yahoo.co.jp has address 183.79.198.79 www.g.yahoo.co.jp has address 183.79.227.90 file_get_contents('http://www.yahoo.co.jp', false, $context); // => PHP Warning: file_get_contents(): Invalid IP Address: (snip) ```