Drupal 7菜单项在一个会话中调用两次

时间:2012-10-08 09:34:30

标签: drupal-7

Drupal开发者,

我有一个非常奇怪的问题。我有一个小模块,有一个菜单项,输出一个图像 - 换句话说,它不显示任何页面,任何HTML或其他任何东西,但只是发送header('Content-Type: image/png');,然后输出PNG并退出与exit();

但是......这真的很奇怪......有时它会运行两次,并且即使我只加载一次URL也要经过两次。如果我在函数中添加一个看门狗并检查日志后记,我可以看到该函数已被处理两次......有时候。由于没有明显的原因,它偶尔会按预期工作 - 一次通过,一次图像输出,然后没有,但在其他时候它会运行两次。

如果我添加一个增加数据库中数字的计数器,这个数字有时会增加1,有时会增加2,尽管我只在浏览器中加载了一次图像。

我在两台服务器上测试过它(一台Unix,一台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

如果我在这里和那里添加看门狗,我可以看到该模块初始化不止一次,这并不奇怪,但我真的很惊讶我的自定义函数不止一次被调用 - 而且有时只是。我已经尝试了各种各样的魔法,比如添加一个会话变量来计算第一个之后的传递次数和中断次数,但无济于事。该功能在大多数情况下运行不止一次。

对于函数的目的而言,它始终只运行一次至关重要。

有人知道发生了什么吗?

这是我的基本代码:

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点,但大部分时间(但不是每次......)我在日志中得到两个“图像显示”条目!尽管有exit(),但据我所知,它应该暂停脚本。

Drupal可能会对我做什么伏都教?

3 个答案:

答案 0 :(得分:0)

也许这个或许不是! --- watchdog()和exit()都会向日志报告。您的看门狗()不在条件中 - 因此它将始终记录。你的exit()是有条件的,所以只有在满足条件时才会记录。这可以解释巫毒。

尝试使用die()而不是exit()来获得更清晰的日志。

答案 1 :(得分:0)

我通过不在代码中输出图像,而是使用header命令将浏览器发送到物理图像文件,部分解决了这个问题。

这似乎打破了Drupal中的任何流程并按预期呈现图像一次。唯一的缺点是,我不能只生成任何图像,但必须有物理,但这是我可以克服的障碍。

换句话说,替换

  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在服务器上。

这对我现在有用,但我仍然很高兴知道什么可以阻止Drupal处理exit()die()命令。

马丁

答案 2 :(得分:-1)

可能你应该尝试在“干净”的浏览器上查看这个。尝试不使用任何扩展程序的Firefox(不是Chrome!)。 添加

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

并分析此输出。