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