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

Drupal 7 Drupal 7菜单项在一个会话中调用两次,drupal-7,Drupal 7,Drupal开发人员同事 我有一个很奇怪的问题。我有一个小模块,它有一个菜单项,输出一个图像——换句话说,它不显示任何页面、任何HTML或任何其他内容,只发送一个标题('Content-Type:image/png')然后输出PNG并使用exit()退出 但是。。。这真的很奇怪。。。有时它运行两次,并通过两次函数,即使我只加载URL一次。如果我在函数中添加一个看门狗并检查日志的后记,我可以看到函数已经处理了两次。。。有时候。没有明显的原因,它偶尔会像预期的那样工作——一个过程,一个图像输出,然后

Drupal开发人员同事

我有一个很奇怪的问题。我有一个小模块,它有一个菜单项,输出一个图像——换句话说,它不显示任何页面、任何HTML或任何其他内容,只发送一个
标题('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点,但大多数时候(但不是每次…)我在日志中看到两个“图像显示”条目!尽管有
退出()

德鲁帕尔会对我做什么?

也许是这个,也许不是!--watchdog()和exit()都向日志报告。您的watchdog()不在条件中-因此它将始终记录。您的exit()处于条件中,因此只有在满足条件时才会记录。这可以解释伏都教


尝试die()而不是exit(),以获得更干净的日志。

可能是您应该尝试在“clean”浏览器上检查这一点。试试Firefox(而不是Chrome!),不带任何扩展。 加


并分析此输出。

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

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

换言之,取代

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

在我问题中的代码中,确保/sites/default/files/1px.png位于服务器上

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


马丁

迈克尔,谢谢你的评论和建议。我尝试过die(),但结果是一样的,根据PHP文档,它们都是一样的:“die-等价于exit”。关于条件:如果我看到了图片(我看到了),脚本应该退出——当然,通过可能设置的“退出处理程序”。马丁尼:这不是答案
  if (!headers_sent()) {
    header('Content-Type: image/png');
    echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=');
    exit();   }
  if (!headers_sent()) {
    header('location:/sites/default/files/1px.png');
  }