読者です 読者をやめる 読者になる 読者になる

超PHPerになろう

Enjoy PHP Programming

User-Agent文字列を解釈するには [woothee/woothee]

User-Agent/UA文字列はブラウザなどのユーザーエージェントが自己申告する識別子のことです。この値は歴史的経緯から複雑怪奇で、付け焼刃の実装では正確な判定が困難です。

Project Wootheeプログラミング言語に依存しないUA文字列パーサーを開発するプロジェクトです。言語を横断してテストを共有して居り、同じバージョンを利用すれば、どの言語実装を利用しても同じ結果が得られることが保障されます。

公式サイト Woothee: User-Agent parser/classifier for multi languages by woothee
概要 Cross-language UserAgent classifier library, PHP implementation
パッケージ名 woothee/woothee - Packagist
作者 tagomoris (TAGOMORI "moris" Satoshi)
yuya-takeyama (Yuya Takeyama)
ライセンス Apache License, Version 2.0
バージョン v1.2.0 (2015-08-14)

インストール

Composerでインストール可能です。

composer.phar require woothee/woothee

UA文字列とは

以前、勉強会で発表するために作成したスライドを紹介します。

www.slideshare.net

ブラウザ業界は常に渾沌として居り、現在はMozilla Firefoxを除く多くのブラウザは「WebKitだ」と名乗ります^1

# Chrome 
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2560.0 Safari/537.36
# Mozilla Firefox
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:42.0) Gecko/20100101 Firefox/42.0
# Safari
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/601.2.7 (KHTML, like Gecko) Version/9.0.1 Safari/601.2.7
# Microsoft Edge
Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586
# Opera(OPR)
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36 OPR/33.0.1990.58

これらの変化する情勢について自前で解釈するのは不毛なので、WootheeのようなUAパーサーを利用することは有効です。

UAを分岐する目的

とは言っても現在の多くのブラウザの挙動は標準化されて居り、サーバーサイドのレベルでブラウザの種類そのものを判定することが必要な処理は、ほとんどありません。

実用例を挙げるならば、次のような用途があります。

  • UAスマートフォンかどうかを判定し、モバイル向けサイトにリダイレクトする
  • セキュリティを目的に、著しく古いブラウザ(IE8以下など)での利用を抑制する
  • TwitterFacebookクローラーなどに、TwitterカードOGPを出力する
  • OSごとに異なるファイルをダウンロードさせる

それ以外の目的で不用意に判定を追加すると、将来登場する新しい環境で意図しない挙動をするおそれがあるので、本当に必要な処理かどうか検討してください。

また、GooglebotなどのUAに対して通常のブラウザと著しく異なるレスポンスを返した場合、検索結果に想定できない悪影響がある場合があります。単にGooglebotからのアクセスを拒否することは問題ありませんが、その場合はrobots.txtを利用することを推奨します。詳細はGooglebot - Search Console ヘルプを参照ください。

UAの取得方法

標準のPHPでは、以下のような方法でUser-Agent文字列を取得できます。

<?php
$UA = isset($_SERVER['HTTP_ USER_AGENT']) ? $_SERVER['HTTP_ USER_AGENT'] : '';

$woothee = new \Woothee\Classifier;
$result = $woothee->parse($UA);

ただし、Webフレームワークを利用する場合はテスタビリティを確保するため、フレームワーク推奨の方法で取得しましょう。

以下はLaravelのファサードを利用した記法です。

<?php
$UA = Request::server('HTTP_USER_AGENT');

$woothee = new \Woothee\Classifier;
$result = $woothee->parse($UA);

解析結果

本稿執筆時点でのWoothee 1.2.0では、以下のような出力が得られます。

<?php
$woothee = new \Woothee\Classifier;

# Twitterのクローラー
$woothee->parse("Twitterbot/1.0");
# => [
#     "name" => "twitter",
#     "category" => "crawler",
#     "os" => "UNKNOWN",
#     "version" => "UNKNOWN",
#     "vendor" => "UNKNOWN",
#     "os_version" => "UNKNOWN",
# ]

$woothee->parse("facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)");
# => [
#     "name" => "facebook",
#     "category" => "crawler",
#     "os" => "UNKNOWN",
#     "version" => "UNKNOWN",
#     "vendor" => "UNKNOWN",
#     "os_version" => "UNKNOWN",
# ]

$woothee->parse("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2560.0 Safari/537.36");
# => [
#     "name" => "Chrome",
#     "vendor" => "Google",
#     "version" => "48.0.2560.0",
#     "category" => "pc",
#     "os" => "Mac OSX",
#     "os_version" => "10.10.5",
# ]

$woothee->parse("Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586");
# => [
#     "name" => "Edge",
#     "vendor" => "Microsoft",
#     "version" => "13.10586",
#     "category" => "pc",
#     "os" => "Windows 10",
#     "os_version" => "NT 10.0",
# ]

$woothee->parse('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)');
# => [
#     "name" => "Internet Explorer",
#     "vendor" => "Microsoft",
#     "version" => "6.0",
#     "category" => "pc",
#     "os" => "Windows XP",
#     "os_version" => "NT 5.1",
# ]

$woothee->parse("Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; Media Center PC 4.0; SLCC1; .NET CLR 3.0.04320)");
# => [
#     "name" => "Internet Explorer",
#     "vendor" => "Microsoft",
#     "version" => "8.0",
#     "category" => "pc",
#     "os" => "Windows UNKNOWN Ver",
#     "os_version" => "NT 5.2",
# ]