如何在PHP中从HTTPAccepHeader中选择内容类型?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (54)

我试图建立一个符合标准的网站框架,它根据浏览器支持将XHTML 1.1作为application / xhtml + xml或HTML 4.01作为文本/ html提供。目前它只是在accept头文件的任何位置寻找“application / xhtml + xml”,如果它存在,就会使用它,但这并不灵活 - text / html可能会有更高的分数。另外,当添加其他格式(WAP,SVG,XForms等)时,它将变得更加复杂。那么,有没有人知道一段经过验证和测试的PHP代码可以从服务器给出的字符串数组中选择一个最好的客户端支持的还是基于客户端得分的有序列表?

提问于
用户回答回答于

你可以利用Apache的mod_negotiation模块。通过这种方式,你可以使用模块提供的全面的协商功能,包括你对内容类型的自己的偏好(例如,“我真的想提供application / xhtml + xml,除非客户非常喜欢别的东西”)。 。基本解决方案

  • 创建一个.htaccess文件AddHandler type-map .var 作为内容
  • 创建一个文件foo.varURI:foo URI:foo.php / html 内容类型:text / html; 适量= 0.7 URI:foo.php / xhtml 内容类型:application / xhtml + xml; 适量= 0.8 作为内容
  • 创建一个文件foo.php<?PHP echo'selected type:',substr($ _ SERVER ['PATH_INFO'],1); 作为内容。
  • 请求http://localhost/whatever/foo.var

为此,你需要启用mod_negotiation,并且不会为$ _SERVER ['PATH_INFO']禁用AddHandler和AcceptPathInfo的相应AllowOverride权限。 用我的Firefox发送“Accept:text / html,application / xhtml + xml,application / xml; q = 0.9,/ ; q = 0.8”,结果是“selected type:xhtml”。 你可以使用其他“调整”来摆脱PATH_INFO或需要foo .var,但基本概念是:让mod_negotiation将请求重定向到你的php脚本,以便脚本可以“读取”所选内容 -类型。

用户回答回答于
function getBestSupportedMimeType($mimeTypes = null) {
    // Values will be stored in this array
    $AcceptTypes = Array ();

    // Accept header is case insensitive, and whitespace isn’t important
    $accept = strtolower(str_replace(' ', '', $_SERVER['HTTP_ACCEPT']));
    // divide it into parts in the place of a ","
    $accept = explode(',', $accept);
    foreach ($accept as $a) {
        // the default quality is 1.
        $q = 1;
        // check if there is a different quality
        if (strpos($a, ';q=')) {
            // divide "mime/type;q=X" into two parts: "mime/type" i "X"
            list($a, $q) = explode(';q=', $a);
        }
        // mime-type $a is accepted with the quality $q
        // WARNING: $q == 0 means, that mime-type isn’t supported!
        $AcceptTypes[$a] = $q;
    }
    arsort($AcceptTypes);

    // if no parameter was passed, just return parsed data
    if (!$mimeTypes) return $AcceptTypes;

    $mimeTypes = array_map('strtolower', (array)$mimeTypes);

    // let’s check our supported types:
    foreach ($AcceptTypes as $mime => $q) {
       if ($q && in_array($mime, $mimeTypes)) return $mime;
    }
    // no mime-type found
    return null;
}

示例用法:

$mime = getBestSupportedMimeType(Array ('application/xhtml+xml', 'text/html'));

扫码关注云+社区

领取腾讯云代金券