与符号、PHP会话和有效HTML
为什么使用PHP会话会导致生成无效的HTML和XHTML,以及如何修复它。
本文件的状态
本文档是一篇贡献给质量保证利益集团欢迎反馈、建议和更正,并应发送到公开存档的邮件列表www-qa网站.
信用
- 作者
- 大卫·多沃德
目录
背景
HTML(和XHTML,以及其他SGML和XML应用程序)某些字符具有特殊的含义,一个主要的例子是<,它指示标记的开始。此类字符不能如果希望显示,只需在文档中键入即可-否则用户代理如何区分b<a
(意思是b小于a)和b<a
(意思是b后面是a的开头锚)?
为了显示保留字符,HTML和XHTML提供了一个调用的机制性格参考文献。其语法为:
- 与号
- 引用字符的“代码”
- 分号
例如,“小于”字符表示为&它;
.
赋予“与”和特殊含义使其成为保留字符,因此它还需要由实体表示用于文档中-&;
现在,让我们坦白一下,这些规则有一些例外,尽管它们在处理由以下原因引起的问题时并不相关PHP会话。
HTML和XHTML包括CDATA块,其中HTML特殊字符不再有特殊含义。在这些区块内不再处理字符引用,因此必须键入为与号,而不是其字符引用。在HTML中,的内容<脚本>
和<样式>
元素是CDATA,而在XHTML中他们是显式标记。您可以通过放置脚本来避免此问题和样式表在单独的文件中,并使用<链接>
和<script src=“…”>
.
其他例外情况是,有时分号是可选的,有时,无需将与号编码为实体。在这些情况下,代表字符作为以分号结尾的字符引用,所以我我们不会详细讨论。
问题
PHP内置了会话处理代码,这使数据存储在服务器上,但与特定用户关联(对于,粗略地说,只需访问一次网站)。
要将数据链接到用户,网站必须将用户代理标识它的令牌。此令牌存储在饼干,但不是全部用户代理支持cookie,而且大多数cookie允许用户代理被关闭。
PHP提供了回退机制。如果发现cookie客户端不接受,它会将页面上的每个链接重写为在查询字符串中包含该标记。我相信这过去是默认启用,但测试表明,至少对于FedoraPHP 4.3.11包(该包的Fedora版本2.4),它不是。可以通过设置会话trans_sid指令。
从理论上讲,这是解决这个问题的一个很好的方法(为第三方打折代币的发行将鼠标悬停在公共计算机、书签、链接共享等上),但实施存在缺陷。
对于没有查询字符串的链接,没有问题。PHP附加?PHPSESSID公司=
后面是随机的十六进制数。对于包含PHP附加查询字符串的链接&PHPSESSID公司=
.
用作参数分隔符的与符号字符在中没有问题普通的旧URL,但是在HTML编码的URL中,它们仍然表示字符引用的开头(根据上述规定例外情况,上述示例不适用)。
大多数用户不会注意到问题,大多数用户代理很善于处理作者的错误。然而并不意味着作者应该忽视这个问题。
- 您不可能知道每个访问该页面的用户代理都会能够处理错误
- 如果标记验证器旗帜每个链接上的错误都会很难找到可能导致严重问题的错误
- 如果您计划编写XHTML和以这种方式提供标记那么流氓&安德森就会使XML解析器放弃处理代码的尝试(这是XML规范的要求)。
解决
输出字符引用
PHP用于分隔参数的字符是可配置的使用arg_分离器输出指令。这可以在方法的数量,这是PHP手册中建议的解决方案。
编辑php.ini
php.ini文件包含在计算机上安装PHP。您可以指定对的字符引用在那里使用。
arg_separator.output=“&;”
Apache指令
这个阿帕奇web服务器可以在所有常用位置设置PHP脚本。这允许不同的要基于每个站点或每个目录设置的指令(in,for例如,<location>块或.htaccess文件)。
php_value参数分隔器输出&;
每脚本基础
PHP配置指令可以按脚本设置iniset函数.将在脚本顶部设置指令的代码。
<?php ini_set('arg_separator.output','&;');?>
使用不同的参数分隔符
由于与号字符在HTML中具有特殊含义规范建议查询字符串解析器允许使用分号作为参数分隔符.PHP预配置为接受这个,这样您就可以将输出代码更改为使用分号而不是使用相同的技术使用与符号。
编辑php.ini
arg_separator.output=“;”
Apache指令
php_value参数分隔器输出;
每脚本基础
<?php ini_set('arg_separator.output',';');?>
禁用非cookie用户的会话
从安全角度来看,此选项具有许多优点视图,因为它减少了会话令牌泄漏到第三方的可能性各方。作为副作用,它将使您的会话代码对禁用、阻止或不支持cookie的访问者(此具有可访问性含义)。
编辑php.ini
session.use_trans_sid=0
Apache指令
php_value会话.use_trans_sid 0
每脚本基础
此指令可能无法在每个脚本上设置基础取决于您使用的PHP版本。如果是的话可以设置它,然后语法如下:
<?php ini_set('session.use_trans_sid','0');?>