章 53. 使用 PHP本节汇集了你在写 PHP 脚本时可能碰到的大多数普通错误。
PHP 提供很多“预定义变量”,例如超全局变量 $_POST。可以遍历 $_POST 变量,因为它是一个和所有通过 POST 方法传递数据相联系的数组。例如,可以用 foreach 简单地遍历它,检查 empty() 值,以及将它们输出。
函数 addslashes() 能够实现这种操作。请参阅函数 mysql_escape_string()。另外,还可以用函数 stripslashes() 来去掉反斜线。
PHP 函数 stripslashes() 能够从 string 中去掉所有的反斜线。这些反斜线出现最有可能的原因是 PHP 设置项 magic_quotes_gpc 被开启。
在 PHP 中,一段代码的结束标记要么是“?>”要么是“?>\n”(\n 表示换行)。因此在上面的例子中,输出的句子将显示在同一行中,因为 PHP 忽略了代码结束标记后面的换行。这意味着如果要输出一个换行符,需要在每段 PHP 代码的结束标记后面多加一个换行。 PHP 为什么这么做呢?因为在格式化正常的 HTML 时,这样通常会更容易。假如输出了换行而你不需要这个换行时,就不得不用一个非常长的行来达到这样的效果,或者让产生的 HTML 页面的源文件的格式很难读。 6. 我得到消息“Warning: Cannot send session cookie - headers already sent...”或者“Cannot add header information - headers already sent...”。 函数 header(),setcookie() 和 session 函数需要在输出流中添加头信息。但是头信息只能在其它任何输出内容之前发送。在使用这些函数前不能有任何(如 HTML)的输出。函数 headers_sent() 能够检查脚本是否已经发送了头信息。请参阅输出控制函数。 如果以 Apache 的模块方式运行 PHP,那么函数 getallheaders() 可以做这件事。因此下面的代码可以显示所有的请求报头:
请参阅函数 apache_lookup_uri()、apache_response_headers() 和 fsockopen()。 IIS 的安全模型这里有毛病。这是所有 IIS 下运行的 CGI 程序所共有的问题。一个解决办法是建立一个纯 HTML 文件(不经过 PHP 解析)作为要进入认证目录的登录页面,然后用 META 标记来重定向到 PHP 页面,或者用一个连接到 PHP 页面。然后 PHP 就可以正确识别认证信息了。如果是用 ISAPI 模块,那没有这个问题。其它 NT 下的 web 服务器不受此影响。更多信息见 http://support.microsoft.com/kb/q160422/及 HTTP 认证一章。 必须要做些修改。打开 Internet 信息服务,找到你的 PHP 文件并打开属性页,选择文件安全性标签,点击匿名访问和身份验证控制的“编辑”按钮。 解决此问题有两个方法,一是不要选中匿名访问并且选中集成 Windows 身份验证,二是选中匿名访问并编辑匿名访问使用的帐户,改成一个有权限的。 Netscape 在关于 HTML 标记(例如 table)上比 IE 更严格。用一个 HTML 验证器,例如 validator.w3.org 来验证你的 HTML 输出可能会有帮助。例如漏了 </table> 可能会导致这样的结果。 同样,IE 和 Lynx 都忽略了 HTML 流中的任何 NULs(\0),Netscape 就不。最好的检查方法是编译 PHP 的命令行模式版本(也称为 CGI 版本)并从命令行运行你的脚本。在 *nix 中,用管道传递到 od -c 并查看任何 \0 字符。如果在 Windows 下你需要能够查看二进制文件格式的编辑器或程序。当 Netscape 碰到 NUL 时就不会输出之后该行的任何内容而 IE 和 Lynx 都会。 要能够在 PHP 代码中直接嵌入 <?xml,需要将 PHP 设置项 short_open_tags 设置为 0 以关闭短标记格式。无法通过函数 ini_set() 来更改这项设置。不管 short_open_tags 是开或者关,都可以用类似于 <?php echo '<?xml'; ?> 的方法达到目的。该项设置的默认值为开。 最简单的方法是让 PHP 代码也能使用 ASP 标记。这可以让你用 ASP 风格的 <% 和 %> 代码定界符。一些流行的 HTML 编辑器在处理此格式上更加智能化一些(目前如此)。要使用 ASP 风格的标记,需要在 php.ini 中打开 asp_tags,或者用相应的 Apache 配置选项。 请阅读手册中的预定义变量一章,该部分的文档已经包含了一部分可以用于你的脚本的预定义变量的列表。可用变量的完整列表(及更多信息)可以通过调用 phpinfo() 函数来查阅。请务必阅读手册中来自 PHP 之外的变量一节,这部分文档阐述了外部变量的概念,例如来自 HTML 表单、Cookie 和 URL 的变量。
首先非常重要的一点是 PHP 设置项 register_globals 同样会对服务器端和环境变量产生影响。当 register_globals = off (从 PHP 4.2.0 开始其默认值为 off),变量 $DOCUMENT_ROOT 将不会存在,而只有 $_SERVER['DOCUMENT_ROOT']。如果 register_globals = on 则变量 $DOCUMENT_ROOT 和 $GLOBALS['DOCUMENT_ROOT'] 将同时存在。 如果确认 register_globals = on 但不知道为什么 $DOCUMENT_ROOT 在函数内部不可用,这是因为它和其它的变量一样需要在函数中执行 global $DOCUMENT_ROOT。请参阅手册中的变量范围一节。建议在 register_globals = off 的情况下进行编码。
| ||||||||