概要
みなさんこんにちはcandleです。今回はちょっと問題が起きてshell_execがうまくいかないときのトラブルシューティングをまとめます。
私はMAMPをバージョンアップする前は、phpのshell_execからunixのconvertコマンドを使う事ができたのですが、バージョンアップ後、急に使えなくなりました。
どうやって、そこから解決まで持っていったのかまとめます。
今回は、imagemagickのconvertコマンドを使うという前提で話を進めていきます。
前提
なし
サンプルファイルと画像を用意する
まずは、shell_execをするphpファイルを作ります。私は「do_shell_exec.php」というファイルを適当なプロジェクトに作成します。
私はalltestプロジェクトに置きました。
do_shell_exec.phpの中身は下の様にします。
<?php $command="convert -geometry 50% ./apple.jpg ./50p.jpg"; $result=shell_exec($command); echo $result; echo "end"; ?>
画像を用意します。
下の写真を「do_shell_exec.php」があるフォルダに置いてください。
do_shell_execを実行する
MAMPを起動して、今作成したphpフィアルのところにいきます。
私の場合は下のURL になります。
http://localhost:8888/alltest/do_shell_exec.php
もしも、shell_execでconvertが作動すれば、画像のサイズが半分になった50p.jpgというファイルが生成されます。
画面をみると、phpのスクリプトは最後まで実行されています。
しかし、このphpスクリプトが置かれたフォルダ(私の場合はalltestフォルダ)には50p.jpgというファイルが生成されていません。
これはつまり、shell_execは動いているが、unixコマンドがうまく実行されてい無い事を表しています。
unixコマンドにエラーを吐かせる
現在、このサンプルソースは下の様に、unixの実行結果を$resultにおさめています。
$result=shell_exec($command); echo $result;
もしも、unixコマンドでエラーがでれば、確認できるというわけです。エラーを出す為に、do_shell_exec.phpを変更しましょう。
<?php $command="convert -geometry 50% ./apple.jpg ./50p.jpg 2>&1"; $result=shell_exec($command); echo $result; echo "</br>"; echo "end"; ?>
unixコマンドの最後に「2>&1」というが加えられました。これでエラーがみれます。
ブラウザをリロードすると下のようなエラーがでました。
「sh:convert: command not found」
このエラーはconvertコマンドが見当たらないようという意味です。convertのコマンドがある場所を探して指定しましょう。
ターミナルでconvertのある場所を探します。下のコマンドを打ちましょう。
which convert
私のはmacportsでImagemagickを入れているのでopt以下にありますね。brewで入れている人はusr以下にあると思います。
ということで、今調べたパスを用いて、ソースコードを編集します。下のPATHはmacportsでimagemagickを入れた時のconvertコマンドのパスです。ちゃんと自分の調べたものを入れてください。
<?php $command="export PATH='/opt/local/bin/'; convert -geometry 50% ./apple.jpg ./50p.jpg 2>&1"; $result=shell_exec($command); echo $result; echo "</br>"; echo "end"; ?>
では、これでブラウザをリロードしてみましょう。
今度は別のエラーがでました。これもMAMPのバージョンや使っているunixコマンドによって違うのですが、だいたいはdylibのエラーだと思われます。
例えば、下のようなエラーや
「dyld: Library not loaded: /opt/local/lib/libfreetype.6.dylib Referenced from: /opt/local/bin/convert Reason: Incompatible library version: convert requires version 18.0.0 or later, but libfreetype.6.dylib provides version 16.0.0 」
下のようなエラーがでるかもしれません。
「dyld: Symbol not found: __cg_jpeg_resync_to_restart Referenced from: /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ImageIO.framework/Versions/A/Resources/libTIFF.dylib Expected in: /Applications/MAMP/Library/lib/libJPEG.dylib in /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/ImageIO.framework/Versions/A/Resources/libTIFF.dylib 」
envvarsを編集する
これらのエラーを出さない為に、MAMPのenvvarsを編集します。私はこのファイルでdylibがどのように影響しているか詳しく知らないのですが、もしも、不具合が生じたい場合は戻しておくと良いでしょう。
下のパスに移動します。
/Applications/MAMP/Library/bin/
この中に「envvars」というファイルがあります。これを適当なエディタで開きます。
下の1文をコメントアウトします。
DYLD_LIBRAY_PATH=”/Applications/MAMP/Library/lib:$DYLD_LIBRARY_PATH”
MAMPの古いバージョンでは下の場所をコメントアウトします。
最新版ではif文になっています。その中の同じ文章をコメントアウトしましょう。
これで修正は終わりです。
サーバを再起動しましょう。
ブラウザをリロードすると、今度はエラーメッセージがでてきません。
フォルダをみると、無事convertコマンドが実行されて、画像が生成されています。
まとめ
今回は、convertメソッドをみてきましたが、他のコマンドでも同じだと思います。まずはエラーを出力して、どのような問題が起きているか把握して、対処しましょう。