1

gm convert基本的に、GraphicsMagick 1.3.12 から exec() を介して呼び出して画像のサイズを変更する小さな PHP クラスを作成しました。ライブ サイトのユーザーが問題を報告しており、私の開発ボックスでもいくつかの問題を再現できました。

関連するコードは次のようになります。

<?php

define('GM_PATH', 'C:\\Archivos de programa\\GraphicsMagick-1.3.12-Q16\\gm.exe');

[...]

private function resize($width, $height, $do_not_upscale=TRUE){
    $source = escapeshellarg($this->source_file);
    $target = escapeshellarg($this->target_file);
    $command = escapeshellarg(GM_PATH) . ' convert ';
    $parameters = array();

    $parameters[] = $source;
    $parameters[] = sprintf('-resize "%dx%d%s"', round($width), round($height), $do_not_upscale ? '>' : '');
    $parameters[] = '+profile "*"';
    $parameters[] = $target;

    $execute = $command . ' ' . implode(' ', $parameters) . ' 2>&1';

    exec($execute, $output, $return);
    if( $return==0 ){
        return $this->target_file;
    }else{
        throw new Exception('Image resizing failed: return code ' . $return . ': ' . implode(PHP_EOL, $output));
    }
}

ライブ サイトは PHP/5.2.9-2 で実行され、開発サイトは PHP/5.3.0 で実行されます。どちらのボックスも、Windows Server 2003、Apache/2.2、および GraphicsMagick 1.3.112 Q16 を実行します。

ライブ サイトで return code の例外が発生します1cmd.exe開発サイトでは、タスクを強制終了するまで 0% の CPU を使用して、プロセスが永久にアイドル状態のままになる様子をランダムに確認できます。

これが外部ツールであることを考えると、次に何をすべきかについてのアイデアが尽きてしまいました。この問題のトラブルシューティング方法を教えてください。

更新 #1

関係のないコードの小さなバグを修正し、考えられるすべてのステップ (gm.exeのアクティビティを含む-debug All) ごとにファイルにログインしていますが、どこにも行きません。PHP は exec() 呼び出しに到達し、 gm.exe何もせずに永久に実行され続けます。

アップデート #2

正確なコマンドが 2 つの方法で実行されています。ログ ファイルへのエコーはこれを示します:

"C:\Archivos de programa\GraphicsMagick-1.3.12-Q16\gm.exe" convert  -debug All "\\SHARE\Project\tmp\mini_4d13465d4bc4b.jpg" -resize "1024x1024>" +profile "*" "\\SHARE\Project\tmp\mini_4d13465dafddd.jpg" 2>>"//SHARE/Project/Miniatura-01.log"

Process Explorerで表示されるプロセス プロパティでは、コマンド ラインは次のようになります。

cmd.exe /c ""C:\Archivos de programa\GraphicsMagick-1.3.12-Q16\gm.exe" convert  -debug All "\\SHARE\Project\tmp\mini_4d13465d4bc4b.jpg" -resize "1024x1024>" +profile "*" "\\SHARE\Project\tmp\mini_4d13465dafddd.jpg" 2>>"//SHARE/Project/Miniatura-01.log""

両方のコマンドを手動で実行できますが、式全体を二重引用符で囲まない限り、2 つ目のコマンドは (コマンド プロンプトからではなく) Start->Run からのみ実行されます。

いずれにせよ、サイズ変更された画像を常に取得し、gm によって生成されたデバッグ ログが正常に見えるため、コマンドが期待どおりに実行されることはかなり確信しています。最後の行は、停止するときと停止しないとき、常に次のようになります。

13:53:52 0:03 3.016u 2344 module.c/UnloadModule/2180/Configure: 「JPEG」モジュールをアンロード中 ...

完了時にプロセスが終了するのを妨げる何かがあるのではないかと思います:ウイルススキャナー、シェル拡張など...

全体が、修正する努力に見合う価値がなくなり始めています。ImageMagick またはプレーンな PHP 関数イメージに切り替えることを検討します。

アップデート #3

面白い... ImageMagick に切り替えましたが、まったく同じ問題が発生しています。そして、いつでも再現できます。ブラウザのタブを 2 つ開くだけです。

PHP からコマンドを実行する方法を忘れてしまったことは明らかです。純粋な PHP コードで画像のサイズを変更しようと思います。

4

2 に答える 2

0

同僚のおかげで解決策を見つけました:

http://es2.php.net/manual/en/function.exec.php#99781

Windows-Apache-PHP サーバーでは、exec コマンドを同時に複数回使用すると問題が発生します。スクリプト (exec コマンドを使用) が同じユーザーによって同時に複数回読み込まれると、サーバーがフリーズします。私の場合、exec コマンドを使用する PHP スクリプトがイメージ タグのソースとして使用されました。1 つの HTML に複数の画像があるため、サーバーが停止しました。この問題は、ここ (http://bugs.php.net/bug.php?id=44942) で解決策とともに説明されています - exec コマンドの前にセッションを停止し、その後に再度開始してください。

<?php

session_write_close();
exec($cmd);
session_start();

?>
于 2010-12-23T18:03:36.900 に答える
0

実行されている正確なコマンドを印刷しましたか? (そして、その印刷された文字列に明らかなエラーがないかチェックしましたか?)

その正確なコマンドをコマンドラインから直接 (つまり、PHP とは別に) 実行しようとしましたか? そのコンテキストで機能しますか、それともロックアップしますか?

個別に実行したときにまったく同じコマンドが機能する場合は、PHP を使用して外部コマンドを呼び出す方法に問題がある可能性があります。

うまくいかない場合は、GM に指定したコマンド ライン パラメータにエラーがあるか、GM 自体にバグが見つかった可能性があります。

いずれにせよ、これはエラーが発生している場所をより適切に処理するのに役立ちます。

もう 1 つ提案したいのは、GM フォルダーをシステム パスに追加することです。これにより、パス全体gmではなく、単独でコマンドを呼び出すことができます。define

ところで、PHP には GraphicsMagik 拡張機能があることをご存知ですか? これは、 を使用して呼び出す必要がないことを意味しますexec。PECL からインストールする必要がありますが、その価値はあるかもしれません... http://devzone.zend.com/article/10531を参照してください

于 2010-12-23T13:40:56.667 に答える