ワイヤード・パンチ

元・大阪人が、岡山の山奥でも生きていけることを証明するためのブログ。

phpでfile_get_contentsとcopyがエラーになるときの対処法。

WordPressで「外部画像置き換え(External image replace)」というプラグインを以前作成し、実際に使われた方からご意見をいただくことがありました。

また、その中から、使用中にエラーが出てくるので原因を調べてほしいというものもありました。

原因を調べてみた結果、まさかサーバの設定に依存するエラーが起きるとは思わず。今回はその対処法について。

広告

どんなプラグイン?

詳細は前回の記事にあるとおりですが、簡単に言うと、他のブログからwordpressに記事をインポートしたあとに使うプラグインです。

記事をインポートしても、記事内の画像が移転前のもののままなので、移転前サーバから移転後のWordpressに画像をコピーして、記事内の画像URLも一括で書き換えるというものです。

file_get_contentsのエラー。

当プラグインはエラー時に、エラーメッセージを出力するようになっているので、報告者からそのエラー時のスクリーンショットを送ってもらいました。

すると、下記のメッセージが記載されていました。

ダウンロード先の画像が見つかりませんでした。 https://xxxxx….

まずは移転前サーバからダウンロードしようとしている画像が存在するかどうか、チェックを行っています。

エラーメッセージには元画像のURLも出力されています。

そのURLに直接アクセスしてみたのですが、画像はしっかり存在していました

それなのに、画像が見つからないというエラーはおかしなものです。

そこで、phpのシステムによるエラーメッセージも一緒に出力されるようにしてみたところ、@file_get_contentsの出力結果がfalseになっていました。

これがfalseであれば、画像がないと判断しています。

@file_get_contentsで画像の有無を判断しているのですが、存在しているのになぜfalseになってしまうのでしょうか。

調べてみると、どうやらphp.iniのallow_url_fopenが有効になっていないと、@file_get_contentsが使えないようです。

ただ、php.iniはサーバ側の設定になってしまうので、プラグイン側からではどうしようもありません。

copyのエラー。

php.iniを設定させるという煩わしいこと、利用者にさせるのはどうかと…。

というわけで、@file_get_contentsでファイルの存在チェックをすることは諦めます。

そもそも存在チェックをせずとも、移転前サーバからダウンロードしてくるときに、存在するかどうかはわかります。

そこで存在していないとどのみちエラーになるので、存在チェックを省いた状態で、報告者にまたテストしてもらいました。

しかし、残念ながらまたエラーが出てしまいました。

Warning: copy(): http:// wrapper is disabled in the server configuration by allow_url_fopen=0 in /home/……

今回は、ついうっかりデバッグメッセージも残るようにしてしまったのですが、それが結果的に解決につながることになりました。

copyを使って、移転前サーバから移転後サーバに画像をダウンロードしているのですが、そこでエラーが起きました。

デバッグメッセージを見ると原因は一目瞭然で、先程と同じくallow_url_fopenが無効であるために、URL指定によるcopyが実行できなかったようです。

しかし、存在チェックと違って、copyは絶対に外せない処理です。

でも、他に対処法もなく…。

php.iniをいじるしかない。

allow_url_fopenが有効でないとどうにもならないため、今回はもう報告者の方に、利用しているサーバのphp.iniからallow_url_fopenを有効にしてもらうよう、お願いしました。

その結果、無事にプラグインが使えるようになったと報告をいただきました。

まさかサーバの設定に依存してしまうとは思いもしませんでしたが、実際に他人に使ってもらうまでは気づかないものでした。

External image replace | WordPress.org

次回のアップデート時に、このことについて注意書きを追記するようにします。

しかし、サーバ管理者でなければ触れないphp.iniに依存してしまうなんて、phpってあんまりよろしくない言語なのでは…と、ふと思ってしまいました。

でも、何事であっても全部の環境に適したコードを作るなんて、無理な話…。こうなるのは仕方のないことでしょうか。

HTMLやCSSに例えると、ChromeやFirefox対応のサイトは楽にできるけど、EdgeやSafariに合わせるのはしんどいですしね。

ただ、今回のエラーは抜きにしても、phpって実際、打ちにくいんですよね…。

いちいち括弧とかセミコロンとか必要で…。

SassやCoffeescriptやpugみたいに、余計な記号省けないんでしょうか。