1

仲間の Drupal 開発者、

私は本当に奇妙な問題を抱えています。画像を出力するメニュー項目を持つ小さなモジュールがあります。つまり、ページ、HTML、その他のものは表示されませんが、単に送信してheader('Content-Type: image/png');からPNGを出力し、終了しますexit();

しかし...そしてこれは本当に奇妙です.URLを1回しかロードしないのに、2回実行され、関数を2回通過することがあります。関数にウォッチドッグを追加してログのあとがきを調べると、関数が 2 回処理されていることがわかります... 時々。明確な理由はありませんが、意図したとおりに機能することがあります。1 回のパス、1 つの画像出力、その後は何も実行されませんが、それ以外の場合は 2 回実行されます。

データベース内の数値をインクリメントするカウンターを追加すると、ブラウザで画像を 1 回しかロードしていないにもかかわらず、この数値が 1 になったり 2 になったりすることがあります。

2 台のサーバー (1 台は Unix、1 台は Windows) でテストしましたが、同じ不規則な動作です。

ヘッダーとキャッシングに注意を払いましたが、何か問題があるようには見えません。1x1 PNG を出力すると、画像のヘッダーは次のようになります。

Date: Thu, 04 Oct 2012 09:21:51 GMT
Server: Apache/2.2.22 (Win32) PHP/5.2.17
X-Powered-By: PHP/5.2.17
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Last-Modified: Thu, 04 Oct 2012 09:21:51 +0000
Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0
Etag: "1349342511"
Content-Length: 95
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: image/png

200 OK

あちこちにウォッチドッグを追加すると、モジュールが複数回初期化されることがわかりますが、これは驚くべきことではありませんが、カスタム関数が複数回呼び出されることに本当に驚きます。最初のパスとブレークの数をカウントするセッション変数を追加するなど、あらゆる種類の魔法を試しましたが、役に立ちませんでした。関数は複数回実行されます...ほとんどの場合。

関数を常に 1 回だけ実行することが重要です。

何が起こっているか知っている人はいますか?

これが私の基本的なコードです:

function my_image_menu() {
  $items = array();
  $items['image_1x1'] = array(
    'title' => t('Create image'),
    'description' => t('Output 1x1 PNG.'),
    'page callback' => 'my_image_show',
    'access arguments' => array('access content'),
  );

  return $items;
}

function my_image_show() {
  watchdog('My Image', 'Image shown');
  if (!headers_sent()) {
    header('Content-Type: image/png');
    echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=');
    exit();
  }
}

ロードhttp://mysite/image_1x1すると、予想どおり画面に小さな 1x1 ドットが 1 つ表示されますが、ほとんどの場合 (毎回ではありませんが...)、ログに「画像が表示されました」というエントリが 2 つ表示されます。にもかかわらず、exit()私が知る限り、スクリプトを停止する必要があります。

Drupal は私にどんなブードゥー教を行っているのでしょうか?

4

3 に答える 3

0

これかもしれませんし、そうでないかもしれません!--- watchdog() と exit() の両方がログに報告されます。watchdog() は条件付きではないため、常にログに記録されます。exit() は条件付きであるため、条件が満たされた場合にのみログに記録されます。これはブードゥーを説明することができます.

ログをきれいにするには、exit() の代わりに die() を試してください。

于 2012-10-08T09:50:37.903 に答える
0

コードで画像を出力するのではなく、ヘッダーコマンドを使用してブラウザーを物理的な画像ファイルに送信することで、この問題を部分的に解決しました。

これにより、Drupal のフローが中断され、イメージが期待どおりに 1 回レンダリングされるようです。唯一の欠点は、イメージを生成することができず、物理的にそれを持たなければならないことですが、それは私が克服できる障害です.

つまり交換

  if (!headers_sent()) {
    header('Content-Type: image/png');
    echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=');
    exit();   }

  if (!headers_sent()) {
    header('location:/sites/default/files/1px.png');
  }

私の質問のコードで、 /sites/default/files/1px.png がサーバー上にあることを確認してください。

exit()これは今のところうまくいきますが、Drupal のordie()コマンドの処理であると私が推測することを止めることができるものを知りたいと思っています。

マーティン

于 2012-10-11T08:04:47.740 に答える
-1

「クリーンな」ブラウザでこれを確認してみてください。拡張機能なしでFirefox(Chromeではありません!)を試してください。追加

watchdog('My Image debug info', print_r($_SERVER, true));

この出力を分析します。

于 2012-10-08T12:55:15.330 に答える