私はブラウザのサポートによってXHTML 1.1をapplication/xhtml + xmlまたはHTML 4.01をtext/htmlとして提供する標準準拠のウェブサイトフレームワークを構築しようとしています。現在のところ、acceptヘッダーのどこでも "application/xhtml + xml"を探し、それが存在する場合はそれを使用しますが、柔軟性がありません。text/htmlの方がスコアが高くなる可能性があります。また、他のフォーマット(WAP、SVG、XFormsなど)を追加すると、より複雑になります。だから、誰かが試してテストしたPHPコードを、サーバーから与えられた文字列配列から選択することを知っていますか?それとも、クライアントのスコアに基づいて順序付けされたリストをサポートしていますか?HTTPからコンテンツタイプを選択するには
答えて
apache's mod_negotiation moduleを利用できます。この方法では、独自のプリファレンス(コンテンツタイプ(e、g、「クライアントが非常に多くのことを好まない限り、アプリケーション/ xhtml + xmlを配信したいと思っています)を含む、モジュールが提供するすべてのネゴシエーション機能を使用できます。 ")。 基本的なソリューション:
- が内容として
<?php echo 'selected type: ', substr($_SERVER['PATH_INFO'], 1);
でファイルfoo.phpを作成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
内容として持つファイルfoo.varを作成
AddHandler type-map .var内容としてで.htaccessファイルを作成します。
。
私のFirefoxが "Accept:text/html、application/xhtml + xml、application/xml; q = 0.9,/; q = 0.8"を送信し、例の.varマップが "selected type:xhtml" 。
PATH_INFOを取り除くために、またはfoo .varをリクエストする必要がありますが、基本的な考え方は次のとおりです:mod_negotiationがリクエストをあなたのPHPスクリプトにリダイレクトして、選択されたコンテンツタイプ。
だから、誰もがそれは純粋なPHPソリューションではありませんを選択するために、PHPコードの実証済みの作品を知っているんが、私はmod_negotiationが試みられていると言うだろうし、念のため;-)
http://www.dev-archive.net/articles/xhtml.html#content-negotiationはPerlで書かれていますが、明らかにレイアウトされており、if/elseと正規表現で構成されています。 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'));
ほんの少しの改善です:関数プロトタイプを 'function getBestSupportedMimeType($ mimeTypes = null、$ acceptedTypes = FALSE)に変更してください。{if($ acceptedTypes === FALSE){$ acceptedTypes = $ _SERVER ['HTTP_ACCEPT']; } ... '。基本的にカスタム受付タイプを許可するのは、プログラムがもう少しカスタムを行う必要がある場合です。 – chacham15
PEAR :: HTTP 1.4.1が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";
}
プリント
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
編集方法を持っていますこれはあまりにも良くないかもしれません...
私のFirefoxは受け入れ を送信します:text/htmlのを、アプリケーション/ XHTML + xmlの、アプリケーション/ XMLを、Q = 0.9、/; qは= 0.8
テキスト/ htmlとアプリケーション/ XHTML + xmlのQ = 1.0を持っていますが、 PEAR :: HTTP(afaik)は、 があなたが好むものを選ぶことはできません。あなたが渡したものが$ supportとして渡されてもtext/htmlを返します。これはあなたには十分かもしれません。私の他の答えを見てください。
PHP 5コードの場合、HTTP2パッケージを使用してください:http://pear.php.net/package/HTTP2 – cweiske
をテスト、Negotiationは、コンテンツネゴシエーションを処理するための純粋なPHP実装です。
私の問題を修正し改善した@ maciej-Łebkowskiと@ chacham15ソリューションをマージしました。 $desiredTypes = 'text/*'
とAccept
を渡した場合、text/html;q=1
を含む場合は、text/html
が返されます。
/**
* Parse, sort and select best Content-type, supported by a user browser.
*
* @param string|string[] $desiredTypes The filter of desired types. If &null then the all supported types will returned.
* @param string $acceptRules Supported types in the HTTP Accept header format. $_SERVER['HTTP_ACCEPT'] by default.
* @return string|string[]|null Matched by $desiredTypes type or all accepted types.
* @link Inspired by http://stackoverflow.com/a/1087498/3155344
*/
function resolveContentNegotiation($desiredTypes = null, $acceptRules = null)
{
if (!$acceptRules) {
$acceptRules = @$_SERVER['HTTP_ACCEPT'];
}
// Accept header is case insensitive, and whitespace isn't important.
$acceptRules = strtolower(str_replace(' ', '', $acceptRules));
$sortedAcceptTypes = array();
foreach (explode(',', $acceptRules) as $acceptRule) {
$q = 1; // the default accept quality (rating).
// Check if there is a different quality.
if (strpos($acceptRule, ';q=') !== false) {
// Divide "type;q=X" into two parts: "type" and "X"
list($acceptRule, $q) = explode(';q=', $acceptRule, 2);
}
$sortedAcceptTypes[$acceptRule] = $q;
}
// WARNING: zero quality is means, that type isn't supported! Thus remove them.
$sortedAcceptTypes = array_filter($sortedAcceptTypes);
arsort($sortedAcceptTypes, SORT_NUMERIC);
// If no parameter was passed, just return parsed data.
if (!$desiredTypes) {
return $sortedAcceptTypes;
}
$desiredTypes = array_map('strtolower', (array) $desiredTypes);
// Let's check our supported types.
foreach (array_keys($sortedAcceptTypes) as $type) {
foreach ($desiredTypes as $desired) {
if (fnmatch($desired, $type)) {
return $type;
}
}
}
// No matched type.
return null;
}
クライアントのAcceptヘッダーからq = 0を除外してはなりません。これは、クライアントがそのタイプを受け入れないことを意味します。 'Accept-Language:en、en-US; q = 0'は、アメリカ人でない限り英語を受け入れることを意味します。 –
PEAR's HTTP2 libraryAccept
ヘッダのすべての種類を解析サポートしています。それはcomposerとPEARを介してインストール可能です。
例は、documentationまたはmy blog postで見つけることができます。
クライアントは、応答でmime-typeのリストを受け入れることができます。一方、応答の順序はクライアント側にとって非常に重要です。 PHP Pear HTTP2は、言語、文字セット、およびMIMEタイプを処理するのに最適です。ここで
$http = new HTTP2();
$supportedTypes = array(
'text/html',
'application/json'
);
$type = $http->negotiateMimeType($supportedTypes, false);
if ($type === false) {
header('HTTP/1.1 406 Not Acceptable');
echo "You don't want any of the content types I have to offer\n";
} else {
echo 'I\'d give you data of type: ' . $type . "\n";
}
良いチュートリアルです:https://cweiske.de/tagebuch/php-http-negotiation.htm
- 1. AngularJSでコンテンツタイプを選択する方法
- 2. ServiceStack APIをHTTPからHTTPSに選択的に移動するには
- 3. Sharepoint外部コンテンツタイプ認証モード - 何を選択しますか?
- 4. JPA(選択)から選択
- 5. Oracle:タイトルから選択OK、ビューから選択する.0行
- 6. 選択値から選択した値を選択します。
- 7. データベースからドメイン列を選択すると、データベースから行を選択する
- 8. 選択欄から項目を選択
- 9. http://harvesthq.github.com/chosen/、選択したデータを取得するには?
- 10. ajaxレスポンスのコンテンツタイプを動的に選択するにはどうすればよいですか?
- 11. PHPの選択から選択した値を取得するには?
- 12. Mysqlは選択から行を選択します
- 13. SelectFieldはドロップダウンから選択を選択します
- 14. mysqlから条件を選択してフィールドを選択する
- 15. ブートストラップからオプションを選択解除する - ドロップダウンコンポーネントを選択
- 16. Ruby HTTP投稿要求 - コンテンツタイプ?
- 17. httpリクエストのzipファイルのコンテンツタイプ
- 18. 選択メニューから特定の行を選択する - PHP/Mysql
- 19. カルーセル - 選択からカルーセルアイテムとオープンモーダルを選択する方法
- 20. ajaxから選択ボックスで値を選択する方法
- 21. リスト内の選択から値を選択する - イオン
- 22. 選択したデータセットから範囲を選択解除する
- 23. 選択から複数の段落を選択する方法
- 24. angularjsモデルから選択されないオプションを選択する
- 25. CXF WebClientがHTTPコンテンツタイプをオーバーライドします
- 26. 選択メニューからHTTP GETリクエストを変更する変更 - 更新パラメータ
- 27. リストから項目を選択するときにラジオボタンを選択します
- 28. 別の選択ドロップダウンからの選択に従って、選択ドロップダウンからオプションを削除するにはどうすればいいですか?
- 29. すでに選択されている選択肢を他の選択肢から削除する
- 30. マトリックスから選択インデックスの基本列を選択する方法は?
それは準拠しており、「正しいことを行う」の基準を試してみて、あることを、すべての良いですが、私はあなたが実際にから任意の利益を得ることがあれば、それは考慮瞬間を費やす価値があると思いますこのすべて。例えば。 text/htmlがうまくいけばapplication/xhtml + xmlを提供する理由はあまりありません。 –