[PHP] file_get_contentsやfopenでhttpsにアクセスしたらエラーが出る症状を回避する方法

2019年3月26日

PHP テクノロジー プログラミング

WEB公開サーバーがhttpsでないとブラウザが「保護されていない通信」というメッセージを表示するようになっています。 GoogleChromeブラウザが2018年7月にアップグレード対応した仕様ですが、httpsで通信を暗号化しないと、もはやデータ送信を安心して行えないというユーザーの事を考えてくれる優しい仕様なのですが、サーバー管理者はたまったもんじゃないですよね。 そしてSSLもTLSに代わり、バージョンも1.2や1.3という風にアップグレードされていきます。 sslは今では使われていないオワコンなので、技術者にうかつに「sslセットして」とか言うと「sslは使わないですよ」という風な不毛なやり取りをしている現場もあるとか無いとか・・・ そんな、httpsの現状の中、いつものようにPHPで便利ツールを作っていたところ、file_get_contentをhttpsサイトに対して行った時に、「failed to open stream」という思わぬエラーが出てうまくアクセスできなかったのでその対応方法を備忘録しておきます。

どんなエラー

金融庁から企業の有価証券報告書や色々な企業のアップロードしている書類(pdf)をダウンロードするスクリプトを書いていた時に表示されたエラーでした。 $data = file_get_contents("https://disclosure.edinet-fsa.go.jp/E01EW/BLMainController.jsp?uji.verb=W00Z1010initialize&uji.bean=ek.bean.EKW00Z1010Bean&TID=W00Z1010&PID=W1E63011&SESSIONKEY=1553119833925&lgKbn=2&pkbn=0&skbn=1&dskb=&askb=&dflg=0&iflg=0&preId=1&mul=toyota&fls=on&cal=1&era=H&yer=&mon=&pfs=4&row=100&idx=0&str=&kbn=1&flg=&syoruiKanriNo=S100F5P4"); file_put_contents("data.pdf" , $data); これは、トヨタ社の四半期報告書のPDFファイルですが、実行すると、"failed to open stream: file_get_contents..."というエラーが表示されます。

解決方法

もちろん、サーバー環境によっては、エラーが出ずに正常に動作する環境もあるようですが、このエラーの原因は、データ取得をしようとするリクエストサーバー側に、https証明書の中間証明書がインストールされていない事が原因のようです。 中間証明書は本来PCやブラウザに搭載されていて、sslやtlsなどの証明書をデコードする際の証明機関との繋ぎをする役割の証明書なのですが、詳しく知りたい方は以下のURLでを読んでください。 https://milestone-of-se.nesuke.com/sv-advanced/digicert/digital-certification-summary/ このエラーの解決方法として、サーバーに中間証明書をインストールすればいいという方法が書かれているサイトも多い中、そもそもそうした証明書を無効にしてデータ暗号化なんかしなくてもいいから、データ取得だけできればいいという方向けに簡単なやり方があります。 $options = stream_context_create(array('ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false ))); $url = "https://disclosure.edinet-fsa.go.jp/E01EW/BLMainController.jsp?uji.verb=W00Z1010initialize&uji.bean=ek.bean.EKW00Z1010Bean&TID=W00Z1010&PID=W1E63011&SESSIONKEY=1553119833925&lgKbn=2&pkbn=0&skbn=1&dskb=&askb=&dflg=0&iflg=0&preId=1&mul=toyota&fls=on&cal=1&era=H&yer=&mon=&pfs=4&row=100&idx=0&str=&kbn=1&flg=&syoruiKanriNo=S100F5P4"; $data = file_get_contents($url , false , $options); file_put_contents("data.pdf" , $data); これでエラーが出ること無く、正常にデータ取得を行なうことができました。 お試しあれ・・・ それにしても、"stream_context_create"命令で指定するオプションが"ssl"ってオワコン名称のままって、「せめて"tls"って書けるようにしてあげて・・・」と考えるのは僕だけでしょうか?

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。