IIS上の PHPでクライアントのOS・ブラウザを判定しようとして 苦労したのでその顛末を・・・
動作環境
- OS Windows7
- IIS 7.5
- PHP 5.4
ASP.Netでは、HttpRequestオブジェクトの UserAgentおよびBrowserプロパティを参照することで クライアントのOS・ブラウザを判定できます。
PHPのマニュアルによると、get_browser関数を使うとPHPでも同様の処理ができそうです。
ここを参照し、http://browscap.org/ から 最新のphp_browscap.ini を ダウンロードし、php.ini の browscap 指定を変更したのですが、マニュアルにあったサンプル
$browser = get_browser(null, true);
print_r($browser);
?>
を実行すると
の嵐!!!!
WEBをいろいろググッていると エラーメッセージは違っているものの ここに 『php5.3以降でparse_ini_fileの挙動が変わったため UserAgentの判定条件にて、”[~]“で囲まれた部分のなかにセミコロン”;”が含まれると この セミコロン以降コメントとみなされ 書式エラー(syntax error)となってしまう。』 とあった。そこで スクリプトを作って セミコロンの前に “” を挿入することに
<?php
$browsecap = file("c:\php54\ext\php_browscap.ini");
$stack = array();
foreach( $browsecap as $row ) {
$rownew = "";
if ( $row[ 0 ] == '[' ){
array_push($stack, str_replace( ';', '\;', $row ));
}
else {
array_push($stack, $row );
}
}
file_put_contents('c:\php54\ext\php_browscap_cnv.ini', $stack );
?>
ところが 結果は 同じ
『Windowsサーバでは動かない』 と書いてあるので ダメ元と思いながら Programing Magic に載っている get_browser関数と同じ働きをする関数を実装して セミコロン対策を施したiniファイルを使ってみると 幸運にも 正常!!!!
クライアントのOS・ブラウザが取得できました。
ちなみにWindowsServer2012R2 IIS8.5 に載せたPHPでも正常に動くことが確認できました。
完成したプログラムは
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>browscapサンプル</title>
</head>
<body>
<?php
echo 'Browser Info: '.$_SERVER['HTTP_USER_AGENT']."<br /><br />";
$arr = get_browser_info(null ,"C:\php54\ext\php_browscap_cnv.ini");
foreach($arr as $key => $row){
print $key.'=>'.$row."<br />";
}
?>
<?php
function get_browser_info($user_agent = null, $ini_path = null){
//引数が省略された場合のデフォルト値を設定
if($user_agent === null)
$user_agent = $_SERVER['HTTP_USER_AGENT'];
if($ini_path === null)
$ini_path = ini_get('browscap');
//iniファイルからデータを取得
$browser_info_list = parse_ini_file($ini_path, true);
//マッチするパターンを探す
foreach($browser_info_list as $pattern => $browser_info){
if(fnmatch($pattern, $user_agent, FNM_CASEFOLD))
$match_pattern_list[] = $pattern;
}
//もっともマッチするパターンを選択
$best_score = PHP_INT_MAX;
foreach($match_pattern_list as $pattern){
$score = levenshtein($user_agent, $pattern);
if($best_score > $score){
$best_score = $score;
$best_pattern = $pattern;
}
}
//情報を取得
$result = array();
$regex = preg_replace(array("/./","/*/","/?/"), array(".",".*","."), $best_pattern);
$result['browser_name_regex'] = strtolower("^{$regex}$");
$result['browser_name_pattern'] = $best_pattern;
$result += $browser_info_list[$best_pattern];
//親を辿って、親の情報を取得
$parent = @$result['Parent'];
while($parent){
$result += (array)$browser_info_list[$parent];
$parent = @$browser_info_list[$parent]['Parent'];
}
//キーを全て小文字に変換
$r = array();
foreach($result as $key => $value){
$r[strtolower($key)] = $value;
}
return $r;
}
?>
</body>
</html>
実行結果は下記の通り
Browser Info: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36 browser_name_regex=>^mozilla/5.0 (.*windows nt 6.1.*) applewebkit/.* (khtml, like gecko).*chrome/36..*safari/.*$ browser_name_pattern=>Mozilla/5.0 (*Windows NT 6.1*) AppleWebKit/* (KHTML, like Gecko)*Chrome/36.*Safari/* parent=>Chrome 36.0 platform=>Win7 platform_version=>6.1 comment=>Chrome 36.0 browser=>Chrome version=>36.0 majorver=>36 win32=>1 frames=>1 iframes=>1 tables=>1 cookies=>1 javascript=>1 javaapplets=>1 cssversion=>3 minorver=>0 alpha=> beta=> win16=> win64=> backgroundsounds=> vbscript=> activexcontrols=> ismobiledevice=> istablet=> issyndicationreader=> crawler=> aolversion=>0