最近、ユーザーのオペレーティングシステム情報を取得する http://thismachine.info/ のようなサイトについて考え始めました。私はPHPでそれを行う方法を見つけることができなかったので、それを理解しようと思っていました。
ブラウザに関する多くの情報を提供するuser-agent
をリストしていることに気付きました。彼らはそれから、または他の何かからオペレーティングシステム情報を取得しますか?ユーザーのオペレーティングシステムを取得するために使用できるAPIはありますか?
ブラウザとIPがどのように取得されたかはわかりますが、オペレーティングシステムの部分はわかりませんでした。
以下のコードは、誰かが使用しているオペレーティングシステムを http://thismachine.info/ で表示する方法を、それ自体で説明できます。
それは、たとえば、windows nt 5.1
を自分のコアオペレーティングシステムモデルのスニッフィングします。
次に、Windows NT 5.1/iをWindows XPにオペレーティングシステムとして渡します。
使用:配列から'/windows nt 5.1/i' => 'Windows XP',
。
当て推量、または近似と言うことができますが、それでもかなり強引です。
SOに関する回答から借用 https://stackoverflow.com/a/15497878/
<?php
$user_agent = $_SERVER['HTTP_USER_AGENT'];
function getOS() {
global $user_agent;
$os_platform = "Unknown OS Platform";
$os_array = array(
'/windows nt 10/i' => 'Windows 10',
'/windows nt 6.3/i' => 'Windows 8.1',
'/windows nt 6.2/i' => 'Windows 8',
'/windows nt 6.1/i' => 'Windows 7',
'/windows nt 6.0/i' => 'Windows Vista',
'/windows nt 5.2/i' => 'Windows Server 2003/XP x64',
'/windows nt 5.1/i' => 'Windows XP',
'/windows xp/i' => 'Windows XP',
'/windows nt 5.0/i' => 'Windows 2000',
'/windows me/i' => 'Windows ME',
'/win98/i' => 'Windows 98',
'/win95/i' => 'Windows 95',
'/win16/i' => 'Windows 3.11',
'/Macintosh|mac os x/i' => 'Mac OS X',
'/mac_powerpc/i' => 'Mac OS 9',
'/linux/i' => 'Linux',
'/ubuntu/i' => 'Ubuntu',
'/iphone/i' => 'iPhone',
'/iPod/i' => 'iPod',
'/ipad/i' => 'iPad',
'/Android/i' => 'Android',
'/blackberry/i' => 'BlackBerry',
'/webos/i' => 'Mobile'
);
foreach ($os_array as $regex => $value)
if (preg_match($regex, $user_agent))
$os_platform = $value;
return $os_platform;
}
function getBrowser() {
global $user_agent;
$browser = "Unknown Browser";
$browser_array = array(
'/msie/i' => 'Internet Explorer',
'/firefox/i' => 'Firefox',
'/safari/i' => 'Safari',
'/chrome/i' => 'Chrome',
'/Edge/i' => 'Edge',
'/opera/i' => 'Opera',
'/netscape/i' => 'Netscape',
'/maxthon/i' => 'Maxthon',
'/konqueror/i' => 'Konqueror',
'/mobile/i' => 'Handheld Browser'
);
foreach ($browser_array as $regex => $value)
if (preg_match($regex, $user_agent))
$browser = $value;
return $browser;
}
$user_os = getOS();
$user_browser = getBrowser();
$device_details = "<strong>Browser: </strong>".$user_browser."<br /><strong>Operating System: </strong>".$user_os."";
print_r($device_details);
echo("<br /><br /><br />".$_SERVER['HTTP_USER_AGENT']."");
?>
脚注:(Jan。19/14)2014年1月18日に YJSoft で/msie|trident/i
を追加する 推奨編集 がありました= SOの新しいメンバー。
次のようなコメント:
コメント:msie11のuaにはmsieが含まれていないため(代わりにトライデントが含まれています)
私はこれを少し調査し、トライデント文字列を説明するいくつかのリンクを見つけました。
編集は 却下 (自分ではなく他の編集者による)でしたが、上記のリンクを読んで適切な判断を下す価値があります。
SUSEの検出について質問された質問に従って、次のURLでこのコードを見つけました。
追加コード:
/* return Operating System */
function operating_system_detection(){
if ( isset( $_SERVER ) ) {
$agent = $_SERVER['HTTP_USER_AGENT'];
}
else {
global $HTTP_SERVER_VARS;
if ( isset( $HTTP_SERVER_VARS ) ) {
$agent = $HTTP_SERVER_VARS['HTTP_USER_AGENT'];
}
else {
global $HTTP_USER_AGENT;
$agent = $HTTP_USER_AGENT;
}
}
$ros[] = array('Windows XP', 'Windows XP');
$ros[] = array('Windows NT 5.1|Windows NT5.1)', 'Windows XP');
$ros[] = array('Windows 2000', 'Windows 2000');
$ros[] = array('Windows NT 5.0', 'Windows 2000');
$ros[] = array('Windows NT 4.0|WinNT4.0', 'Windows NT');
$ros[] = array('Windows NT 5.2', 'Windows Server 2003');
$ros[] = array('Windows NT 6.0', 'Windows Vista');
$ros[] = array('Windows NT 7.0', 'Windows 7');
$ros[] = array('Windows CE', 'Windows CE');
$ros[] = array('(media center pc).([0-9]{1,2}\.[0-9]{1,2})', 'Windows Media Center');
$ros[] = array('(win)([0-9]{1,2}\.[0-9x]{1,2})', 'Windows');
$ros[] = array('(win)([0-9]{2})', 'Windows');
$ros[] = array('(windows)([0-9x]{2})', 'Windows');
// Doesn't seem like these are necessary...not totally sure though..
//$ros[] = array('(winnt)([0-9]{1,2}\.[0-9]{1,2}){0,1}', 'Windows NT');
//$ros[] = array('(windows nt)(([0-9]{1,2}\.[0-9]{1,2}){0,1})', 'Windows NT'); // fix by bg
$ros[] = array('Windows ME', 'Windows ME');
$ros[] = array('Win 9x 4.90', 'Windows ME');
$ros[] = array('Windows 98|Win98', 'Windows 98');
$ros[] = array('Windows 95', 'Windows 95');
$ros[] = array('(windows)([0-9]{1,2}\.[0-9]{1,2})', 'Windows');
$ros[] = array('win32', 'Windows');
$ros[] = array('(Java)([0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2})', 'Java');
$ros[] = array('(Solaris)([0-9]{1,2}\.[0-9x]{1,2}){0,1}', 'Solaris');
$ros[] = array('dos x86', 'DOS');
$ros[] = array('unix', 'Unix');
$ros[] = array('Mac OS X', 'Mac OS X');
$ros[] = array('Mac_PowerPC', 'Macintosh PowerPC');
$ros[] = array('(mac|Macintosh)', 'Mac OS');
$ros[] = array('(sunos)([0-9]{1,2}\.[0-9]{1,2}){0,1}', 'SunOS');
$ros[] = array('(beos)([0-9]{1,2}\.[0-9]{1,2}){0,1}', 'BeOS');
$ros[] = array('(risc os)([0-9]{1,2}\.[0-9]{1,2})', 'RISC OS');
$ros[] = array('os/2', 'OS/2');
$ros[] = array('freebsd', 'FreeBSD');
$ros[] = array('openbsd', 'OpenBSD');
$ros[] = array('netbsd', 'NetBSD');
$ros[] = array('irix', 'IRIX');
$ros[] = array('plan9', 'Plan9');
$ros[] = array('osf', 'OSF');
$ros[] = array('aix', 'AIX');
$ros[] = array('GNU Hurd', 'GNU Hurd');
$ros[] = array('(Fedora)', 'Linux - Fedora');
$ros[] = array('(kubuntu)', 'Linux - Kubuntu');
$ros[] = array('(ubuntu)', 'Linux - Ubuntu');
$ros[] = array('(debian)', 'Linux - Debian');
$ros[] = array('(CentOS)', 'Linux - CentOS');
$ros[] = array('(Mandriva).([0-9]{1,3}(\.[0-9]{1,3})?(\.[0-9]{1,3})?)', 'Linux - Mandriva');
$ros[] = array('(SUSE).([0-9]{1,3}(\.[0-9]{1,3})?(\.[0-9]{1,3})?)', 'Linux - SUSE');
$ros[] = array('(Dropline)', 'Linux - Slackware (Dropline GNOME)');
$ros[] = array('(ASPLinux)', 'Linux - ASPLinux');
$ros[] = array('(Red Hat)', 'Linux - Red Hat');
// Loads of Linux machines will be detected as unix.
// Actually, all of the linux machines I've checked have the 'X11' in the User Agent.
//$ros[] = array('X11', 'Unix');
$ros[] = array('(linux)', 'Linux');
$ros[] = array('(amigaos)([0-9]{1,2}\.[0-9]{1,2})', 'AmigaOS');
$ros[] = array('amiga-aweb', 'AmigaOS');
$ros[] = array('amiga', 'Amiga');
$ros[] = array('AvantGo', 'PalmOS');
//$ros[] = array('(Linux)([0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,3}(rel\.[0-9]{1,2}){0,1}-([0-9]{1,2}) i([0-9]{1})86){1}', 'Linux');
//$ros[] = array('(Linux)([0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,3}(rel\.[0-9]{1,2}){0,1} i([0-9]{1}86)){1}', 'Linux');
//$ros[] = array('(Linux)([0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,3}(rel\.[0-9]{1,2}){0,1})', 'Linux');
$ros[] = array('[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,3})', 'Linux');
$ros[] = array('(webtv)/([0-9]{1,2}\.[0-9]{1,2})', 'WebTV');
$ros[] = array('Dreamcast', 'Dreamcast OS');
$ros[] = array('GetRight', 'Windows');
$ros[] = array('go!zilla', 'Windows');
$ros[] = array('gozilla', 'Windows');
$ros[] = array('gulliver', 'Windows');
$ros[] = array('ia archiver', 'Windows');
$ros[] = array('NetPositive', 'Windows');
$ros[] = array('mass downloader', 'Windows');
$ros[] = array('Microsoft', 'Windows');
$ros[] = array('offline Explorer', 'Windows');
$ros[] = array('teleport', 'Windows');
$ros[] = array('web downloader', 'Windows');
$ros[] = array('webcapture', 'Windows');
$ros[] = array('webcollage', 'Windows');
$ros[] = array('webcopier', 'Windows');
$ros[] = array('webstripper', 'Windows');
$ros[] = array('webzip', 'Windows');
$ros[] = array('wget', 'Windows');
$ros[] = array('Java', 'Unknown');
$ros[] = array('flashget', 'Windows');
// delete next line if the script show not the right OS
//$ros[] = array('(PHP)/([0-9]{1,2}.[0-9]{1,2})', 'PHP');
$ros[] = array('MS FrontPage', 'Windows');
$ros[] = array('(msproxy)/([0-9]{1,2}.[0-9]{1,2})', 'Windows');
$ros[] = array('(msie)([0-9]{1,2}.[0-9]{1,2})', 'Windows');
$ros[] = array('libwww-Perl', 'Unix');
$ros[] = array('UP.Browser', 'Windows CE');
$ros[] = array('NetAnts', 'Windows');
$file = count ( $ros );
$os = '';
for ( $n=0 ; $n<$file ; $n++ ){
if ( preg_match('/'.$ros[$n][0].'/i' , $agent, $name)){
$os = @$ros[$n][1].' '.@$name[2];
break;
}
}
return trim ( $os );
}
編集:2015年4月12日
昨日、このQ&Aに関連し、一部の人に役立つ可能性のある質問に気付きました。に関してで:
Mozilla/5.0 (Linux; Android 4.4.2; SAMSUNG-GT-I9505 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36
別の編集、および有用であるかもしれない質問された(そして今日は11月4/16に回答/承認された)参照リンクを追加します。
StackのQ&Aをご覧ください。
Webサイトにアクセスすると、ブラウザーは多くの情報を含む要求をWebサーバーに送信します。この情報は次のようになります。
GET /questions/18070154/get-operating-system-info-with-php HTTP/1.1
Host: stackoverflow.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate,sdch
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: <cookie data removed>
Pragma: no-cache
Cache-Control: no-cache
これらの情報はすべて、リクエストの処理方法を決定するためにWebサーバーによって使用されます。優先言語および圧縮が許可されるかどうか。
PHPでは、これらの情報はすべて$_SERVER
配列に保存されます。 Webサーバーに送信しているものを確認するには、新しいPHPファイルを作成し、配列からすべてを印刷します。
<pre><?php print_r($_SERVER); ?></pre>
これにより、サーバーに送信されるすべてのものの素敵な表現が得られ、そこから目的の情報を抽出できます。 $_SERVER['HTTP_USER_AGENT']
を使用して、オペレーティングシステムとブラウザを取得します。
get_browser のphpマニュアルから次のコードを取得しました。
$browser = get_browser(null, true);
print_r($browser);
$browser
配列には、使用中の特定のオペレーティングシステムを提供するplatform
情報が含まれています。
そのページの「メモ」セクションを必ず確認してください。これは何か(thismachine.info)が使用している可能性がありますが、既に他の回答で指摘されているものがなければ。
answer by Fred-II に基づいて、getOS関数に関する見解を共有したかったため、グローバルを回避し、両方のリストをマージし、アーキテクチャを検出します(x32/x64)
/**
* @param $user_agent null
* @return string
*/
function getOS($user_agent = null)
{
if(!isset($user_agent) && isset($_SERVER['HTTP_USER_AGENT'])) {
$user_agent = $_SERVER['HTTP_USER_AGENT'];
}
// https://stackoverflow.com/questions/18070154/get-operating-system-info-with-php
$os_array = [
'windows nt 10' => 'Windows 10',
'windows nt 6.3' => 'Windows 8.1',
'windows nt 6.2' => 'Windows 8',
'windows nt 6.1|windows nt 7.0' => 'Windows 7',
'windows nt 6.0' => 'Windows Vista',
'windows nt 5.2' => 'Windows Server 2003/XP x64',
'windows nt 5.1' => 'Windows XP',
'windows xp' => 'Windows XP',
'windows nt 5.0|windows nt5.1|windows 2000' => 'Windows 2000',
'windows me' => 'Windows ME',
'windows nt 4.0|winnt4.0' => 'Windows NT',
'windows ce' => 'Windows CE',
'windows 98|win98' => 'Windows 98',
'windows 95|win95' => 'Windows 95',
'win16' => 'Windows 3.11',
'mac os x 10.1[^0-9]' => 'Mac OS X Puma',
'Macintosh|mac os x' => 'Mac OS X',
'mac_powerpc' => 'Mac OS 9',
'linux' => 'Linux',
'ubuntu' => 'Linux - Ubuntu',
'iphone' => 'iPhone',
'iPod' => 'iPod',
'ipad' => 'iPad',
'Android' => 'Android',
'blackberry' => 'BlackBerry',
'webos' => 'Mobile',
'(media center pc).([0-9]{1,2}\.[0-9]{1,2})'=>'Windows Media Center',
'(win)([0-9]{1,2}\.[0-9x]{1,2})'=>'Windows',
'(win)([0-9]{2})'=>'Windows',
'(windows)([0-9x]{2})'=>'Windows',
// Doesn't seem like these are necessary...not totally sure though..
//'(winnt)([0-9]{1,2}\.[0-9]{1,2}){0,1}'=>'Windows NT',
//'(windows nt)(([0-9]{1,2}\.[0-9]{1,2}){0,1})'=>'Windows NT', // fix by bg
'Win 9x 4.90'=>'Windows ME',
'(windows)([0-9]{1,2}\.[0-9]{1,2})'=>'Windows',
'win32'=>'Windows',
'(Java)([0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2})'=>'Java',
'(Solaris)([0-9]{1,2}\.[0-9x]{1,2}){0,1}'=>'Solaris',
'dos x86'=>'DOS',
'Mac OS X'=>'Mac OS X',
'Mac_PowerPC'=>'Macintosh PowerPC',
'(mac|Macintosh)'=>'Mac OS',
'(sunos)([0-9]{1,2}\.[0-9]{1,2}){0,1}'=>'SunOS',
'(beos)([0-9]{1,2}\.[0-9]{1,2}){0,1}'=>'BeOS',
'(risc os)([0-9]{1,2}\.[0-9]{1,2})'=>'RISC OS',
'unix'=>'Unix',
'os/2'=>'OS/2',
'freebsd'=>'FreeBSD',
'openbsd'=>'OpenBSD',
'netbsd'=>'NetBSD',
'irix'=>'IRIX',
'plan9'=>'Plan9',
'osf'=>'OSF',
'aix'=>'AIX',
'GNU Hurd'=>'GNU Hurd',
'(Fedora)'=>'Linux - Fedora',
'(kubuntu)'=>'Linux - Kubuntu',
'(ubuntu)'=>'Linux - Ubuntu',
'(debian)'=>'Linux - Debian',
'(CentOS)'=>'Linux - CentOS',
'(Mandriva).([0-9]{1,3}(\.[0-9]{1,3})?(\.[0-9]{1,3})?)'=>'Linux - Mandriva',
'(SUSE).([0-9]{1,3}(\.[0-9]{1,3})?(\.[0-9]{1,3})?)'=>'Linux - SUSE',
'(Dropline)'=>'Linux - Slackware (Dropline GNOME)',
'(ASPLinux)'=>'Linux - ASPLinux',
'(Red Hat)'=>'Linux - Red Hat',
// Loads of Linux machines will be detected as unix.
// Actually, all of the linux machines I've checked have the 'X11' in the User Agent.
//'X11'=>'Unix',
'(linux)'=>'Linux',
'(amigaos)([0-9]{1,2}\.[0-9]{1,2})'=>'AmigaOS',
'amiga-aweb'=>'AmigaOS',
'amiga'=>'Amiga',
'AvantGo'=>'PalmOS',
//'(Linux)([0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,3}(rel\.[0-9]{1,2}){0,1}-([0-9]{1,2}) i([0-9]{1})86){1}'=>'Linux',
//'(Linux)([0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,3}(rel\.[0-9]{1,2}){0,1} i([0-9]{1}86)){1}'=>'Linux',
//'(Linux)([0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,3}(rel\.[0-9]{1,2}){0,1})'=>'Linux',
'[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,3})'=>'Linux',
'(webtv)/([0-9]{1,2}\.[0-9]{1,2})'=>'WebTV',
'Dreamcast'=>'Dreamcast OS',
'GetRight'=>'Windows',
'go!zilla'=>'Windows',
'gozilla'=>'Windows',
'gulliver'=>'Windows',
'ia archiver'=>'Windows',
'NetPositive'=>'Windows',
'mass downloader'=>'Windows',
'Microsoft'=>'Windows',
'offline Explorer'=>'Windows',
'teleport'=>'Windows',
'web downloader'=>'Windows',
'webcapture'=>'Windows',
'webcollage'=>'Windows',
'webcopier'=>'Windows',
'webstripper'=>'Windows',
'webzip'=>'Windows',
'wget'=>'Windows',
'Java'=>'Unknown',
'flashget'=>'Windows',
// delete next line if the script show not the right OS
//'(PHP)/([0-9]{1,2}.[0-9]{1,2})'=>'PHP',
'MS FrontPage'=>'Windows',
'(msproxy)/([0-9]{1,2}.[0-9]{1,2})'=>'Windows',
'(msie)([0-9]{1,2}.[0-9]{1,2})'=>'Windows',
'libwww-Perl'=>'Unix',
'UP.Browser'=>'Windows CE',
'NetAnts'=>'Windows',
];
// https://github.com/ahmad-sa3d/php-useragent/blob/master/core/user_agent.php
$Arch_regex = '/\b(x86_64|x86-64|Win64|WOW64|x64|ia64|AMD64|ppc64|sparc64|IRIX64)\b/ix';
$Arch = preg_match($Arch_regex, $user_agent) ? '64' : '32';
foreach ($os_array as $regex => $value) {
if (preg_match('{\b('.$regex.')\b}i', $user_agent)) {
return $value.' x'.$Arch;
}
}
return 'Unknown';
}
これらすべての情報を取得したい場合は、次を読んでください。
http://php.net/manual/en/function.get-browser.php
サンプルコードを実行すると、その動作を確認できます。
<?php
echo $_SERVER['HTTP_USER_AGENT'] . "\n\n";
$browser = get_browser(null, true);
print_r($browser);
?>
上記の例は次のようなものを出力します:
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7) Gecko/20040803 Firefox/0.9.3
Array
(
[browser_name_regex] => ^mozilla/5\.0 (windows; .; windows nt 5\.1; .*rv:.*) gecko/.* firefox/0\.9.*$
[browser_name_pattern] => Mozilla/5.0 (Windows; ?; Windows NT 5.1; *rv:*) Gecko/* Firefox/0.9*
[parent] => Firefox 0.9
[platform] => WinXP
[browser] => Firefox
[version] => 0.9
[majorver] => 0
[minorver] => 9
[cssversion] => 2
[frames] => 1
[iframes] => 1
[tables] => 1
[cookies] => 1
[backgroundsounds] =>
[vbscript] =>
[javascript] => 1
[javaapplets] => 1
[activexcontrols] =>
[cdf] =>
[aol] =>
[beta] => 1
[win16] =>
[crawler] =>
[stripper] =>
[wap] =>
[netclr] =>
)
たとえば、一般的なブラウザのHTMLのクラスのような情報をほとんど必要としない場合は、次を使用できます。
function get_browser()
{
$browser = '';
$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
if (preg_match('~(?:msie ?|trident.+?; ?rv: ?)(\d+)~', $ua, $matches)) $browser = 'ie ie'.$matches[1];
elseif (preg_match('~(safari|chrome|firefox)~', $ua, $matches)) $browser = $matches[1];
return $browser;
}
「safari」または「firefox」または「chrome」、または「ie ie8」、「ie ie9」、「ie ie10」、「ie ie11」を返します。
この情報は$_SERVER['HTTP_USER_AGENT']
で検索できますが、その形式は自由形式であり、送信が保証されておらず、プライバシーなどの理由でユーザーが簡単に変更できます。
browsecap
ディレクティブを設定していない場合、これは警告を返します。設定されていることを確認するには、ini_get
を使用して値を取得し、設定されているかどうかを確認します。
if(ini_get("browscap")) {
$browser = get_browser(null, true);
$browser = get_browser($_SERVER['HTTP_USER_AGENT']);
}
kbaが彼の答えで説明したように、ブラウザはWebページの読み込み中にサーバーに多くの情報を送信します。ほとんどのWebサイトは、これらの ser-agent 情報を使用して、訪問者のオペレーティングシステム、ブラウザ、およびさまざまな情報を判断します。