PHP başlık Accept HTTP içerik türünü seçmek için nasıl

5 Cevap php

Text / html tarayıcı desteği bağlı olarak application / xhtml + xml veya HTML 4.01 gibi XHTML 1.1 gören bir standart uyumlu web sitesi çerçeve oluşturmak için çalışıyorum. Şu anda sadece her yerde kabul başlığında "application / xhtml + xml" arar, ve o var, ama bu esnek değilse o kullanır - text / html yüksek bir puan olabilir. Diğer formatlar (WAP, SVG, XForms vb) eklenir Ayrıca, daha karmaşık hale gelecektir. Yani, herkes, sunucu tarafından verilen bir dize diziden seçmek için PHP kodu bir denenmiş ve test edilmiş parça biliyor ya en iyi müşteri skoruna göre istemci veya sıralı bir listesi tarafından desteklenen bir?

5 Cevap

You can leverage apache's mod_negotiation module. This way you can use the full range of negotiation capabilities the module offers, including your own preferences for the content type (e,g, "I really want to deliver application/xhtml+xml, unless the client very much prefers something else"). basic solution:

  • AddHandler type-map .var
    içerikleri gibi olan bir. htaccess dosyası oluşturmak
  • create a file foo.var with
    URI: foo
    URI: foo.php/html Content-type: text/html; qs=0.7
    URI: foo.php/xhtml Content-type: application/xhtml+xml; qs=0.8
    as contents
  • create a file foo.php with
    <?php
    echo 'selected type: ', substr($_SERVER['PATH_INFO'], 1);
    as contents.
  • istek http://localhost/whatever/foo.var

For this to work you need mod_negotiation enabled, the appropriate AllowOverride privileges for AddHandler and AcceptPathInfo not being disabled for $_SERVER['PATH_INFO'].
With my Firefox sending "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8" and the example .var map the result is "selected type: xhtml".
You can use other "tweaks" to get rid of PATH_INFO or the need to request foo.var, but the basic concept is: let mod_negotiation redirect the request to your php script in a way that the script can "read" the selected content-type.

So, does anyone know of a tried and tested piece of PHP code to select
Bu saf php çözüm değil ama ben mod_negotiation denenmiş ve test edilmiş söyleyebilirim ;-)

Benim kütüphaneden küçük parçası:

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;
}

örnek kullanım:

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

Armut :: HTTP 1.4.1 bir yöntemi vardır string negotiateMimeType( array $supported, string $default)

<?php
require 'HTTP.php';

foreach(
  array(
    'text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5',
    'text/*;q=0.3, text/html;q=0.8, application/xhtml+xml;q=0.7, */*;q=0.2',
    'text/*;q=0.3, text/html;q=0.7, */*;q=0.8',
    'text/*, application/xhtml+xml',
    'text/html, application/xhtml+xml'
  ) as $testheader) {  
  $_SERVER['HTTP_ACCEPT'] = $testheader;

  $http = new HTTP;
  echo $testheader, ' -> ',
    $http->negotiateMimeType( array('application/xhtml+xml', 'text/html'), 'application/xhtml+xml'),
    "\n";
}

prints

text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, /;q=0.5 -> application/xhtml+xml
text/*;q=0.3, text/html;q=0.8, application/xhtml+xml;q=0.7, */*;q=0.2 -> text/html
text/*;q=0.3, text/html;q=0.7, */*;q=0.8 -> application/xhtml+xml
text/*, application/xhtml+xml -> application/xhtml+xml
text/html, application/xhtml+xml -> text/html

edit: this might not be so good after all...
My firefox sends Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
text/html and application/xhtml+xml have q=1.0 but PEAR::HTTP (afaik) doesn't let you chose which one you prefer, it returns text/html no matter what you pass as $supported. This may or may not be sufficient for you. see my other answer(s).

Sadece kayıt için, Negotiation içerik müzakere ile başa çıkmak için saf bir PHP uygulamasıdır.

http://www.dev-archive.net/articles/xhtml.html#content-negotiation Perl ile yazılmış, ama açıkça ortaya koydu ve sadece bazı if / else ve regex oluşur. PHP için taşıma Önemsiz olmalıdır.