IIS上のPHPでクライアントのOS・ブラウザを判定する 

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 指定を変更したのですが、マニュアルにあったサンプル

echo $_SERVER[‘HTTP_USER_AGENT’] . “nn”;
$browser = get_browser(null, true);
print_r($browser);
?>

を実行すると

PHP Warning: get_browser(): Delimiter must not be alphanumeric or backslash in hogehoge

の嵐!!!!

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 );
?>

ところが 結果は 同じ

PHP Warning: get_browser(): Delimiter must not be alphanumeric or backslash in hogehoge  の嵐

『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
スポンサーリンク
Rectangle大広告
Rectangle大広告

シェアする

  • このエントリーをはてなブックマークに追加

フォローする