为什么打印某个字符串导致代码执行两次?

时间:2015-09-29 19:51:44

标签: php

我通过从php视图文件加载动态生成的html来创建电子邮件,但是当包含以下html时,代码似乎执行了两次。
    <table background="#000">
(我甚至不确定background="#000"属性是否有效,但在此上下文中并不重要)

以下是演示此问题的简化示例。

$body = '<table background="#000">';

print $body;

$handle = fopen('error.log', 'a');
fwrite($handle, '########################'.date('Y-m-d H:i:s')."########################\n".$body."\n\n");
fclose($handle);

这将在日志文件中生成2行文本(它应该只生成1) (我使用a作为fopen的第二个参数,以便附加第二个写入。在重新加载页面之前,必须手动删除error.log文件。)

如果print $body;被注释掉或删除,则日志文件只写入1行。

如果我将#000更改为任何非十六进制值(例如红色),或将table更改为其他任何值(例如div),或者我将background属性更改为任何内容否则日志文件只写入1行。

我在运行PHP 5.6.12和5.5.9以及Apache 2.4.7和2.4.16的两台不同服务器上试过这个。

1 个答案:

答案 0 :(得分:4)

TL; DR:浏览器将background="#000"视为背景图片属性,使用#000的相对网址作为图片来源,导致网页加载两次

当浏览器向PHP文件发出请求时,它会收到以下内容:

<table background="#000">

浏览器尝试通过清理它来解析格式错误的HTML文档,将其转换为:

<html>
  <head></head>
  <body>
    <table background="#000"></table>
  </body>
</html>

没有什么令人兴奋或意外的。但有趣的是background标记中的table属性。如果您在Chrome的devtools中检查该页面并查看表格的样式,您会注意到该表格已应用以下CSS(如果该页面位于http://example.com/index.html

background-image: url('http://example.com/index.html#000');

事实证明,背景属性曾经在table标签上(在其他几个标签中)有效,但此后已经制作obsolete in the HTML5 spec

  

tabletheadtbodytfoottrtdth元素具有background属性设置为非空值,新值预计将相对于元素解析,如果成功,则用户代理应将该属性视为表示元素的表示提示&& 39; s& #39;背景图像&#39;绝对URL的属性。

HTML5 Spec, Section 10.3.9 (Tables)

正在发生的事情是#000被视为相对URL,因此浏览器向完全相同的URL发出第二个请求(通过网络发送的URL不包含哈希字符串)。 / p>