2012年2月26日日曜日

Zend Framework + WURFLでPC、携帯、スマホのUA判定


いつまで経ってもUA判定面倒だぜ。。

って、やっぱりみんな思ってる。
WURFL(Wireless Universal Resource FiLe)というモバイル判定を行うデータベースが整備されています。

ZendのUserAgent判定にWURFLを組み込む方法。

参考)
http://framework.zend.com/manual/ja/zend.http.user-agent.html
http://framework.zend.com/manual/en/zend.http.user-agent-features-wurfl.html


0. 環境

PHP 5.3.10
Zend 1.11.10
wurfl-php-1.3.1


1. WURFLのダウンロードと配置

WURFL PHPをダウンロード。
http://sourceforge.net/projects/wurfl/files/
http://sourceforge.net/projects/wurfl/files/WURFL%20PHP/

任意のディレクトリに展開してOKだけど、Zendのドキュメントに書いてある通り、application/libraryに展開します。

library
 └wurfl-php-1.3.1
  ├docs
  ├examples
  ├tests
  ├tools
  ├WURFL
  ├COPYING
  └README


2. キャッシュディレクトリの設定

WURFLデータベースのストレージとしてFile、Memcache、Memory、Mysqlの4つが使えるっぽいです。

以下、簡単そうなFileストレージを採用します。
WURFLのXMLファイルをリクエスト毎にパースしていたら大変なのでFileストレージは最初のアクセス時にキャッシュを作っておきます。

/wurfl-php-1.3.1/WURFL/Storage/File.php
を見てみると、デフォルトのキャッシュパスが/var/tmpになっています。

これをZendのドキュメントに倣って
APPLICATION_ROOT/data/wurfl/cache
とします。

mkdir -p data/wurfl/cache
chmod -R o+rwX data/wurfl/cache


3. データファイルコピー

wurfl-php-1.3.1/tests/resources/
配下のWURFLデータベースを先ほど作ったdataディレクトリにコピーします。

cp library/wurfl-php-1.3.1/tests/resources/wurfl-2.0.27.zip data/wurfl/
cp library/wurfl-php-1.3.1/tests/resources/web_browsers_patch.xml data/wurfl/


4. 設定

Zend先生は
application/config/wurfl-config.php
を作って、
application.ini
からwurfl-config.phpをロードしなさい、と言われていますが、キャッシュディレクトリの設定が上手くいきません。

参考)
<?php
$resourcesDir            = dirname(__FILE__) . '/../../data/wurfl/';
 
// $wurfl['main-file']      = $resourcesDir  . 'wurfl-latest.zip';
$wurfl['main-file']      = $resourcesDir  . 'wurfl-2.0.27.zip';
$wurfl['patches']        = array($resourcesDir . 'web_browsers_patch.xml');
 
$persistence['provider'] = 'file';
$persistence['dir']      = $resourcesDir . '/cache/';
 
$cache['provider']       = null;
 
$configuration['wurfl']       = $wurfl;
$configuration['persistence'] = $persistence;
$configuration['cache']       = $cache;

この辺りのドキュメントのwurflapi.wurfl_config_array.*パラメタをwurfl-config.phpで設定しておきなさい、ということのようですが、
wurflapi.wurfl_config_array.persistence.dir
が効かないっぽいですし、
wurflapi.wurfl_config_array.cache.*
なんてドキュメントには無い。

よく分かんないですが、wurfl-config.phpを作らずにapplication.iniから設定します。

; application/configs/application.ini
; WURFL API
;
resources.useragent.wurflapi.wurfl_lib_dir = APPLICATION_PATH "/../library/wurfl-php-1.3.1/WURFL/"
resources.useragent.wurflapi.wurfl_api_version = "1.1"
resources.useragent.wurflapi.wurfl_config_array.wurfl.main-file = APPLICATION_PATH "/../data/wurfl/wurfl-2.0.27.zip"
resources.useragent.wurflapi.wurfl_config_array.wurfl.patches = APPLICATION_PATH "/../data/wurfl/web_browsers_patch.xml"
resources.useragent.wurflapi.wurfl_config_array.persistence.provider = "file"
resources.useragent.wurflapi.wurfl_config_array.persistence.dir.dir = APPLICATION_PATH "/../data/wurfl/cache"

; resources.useragent.wurflapi.wurfl_config_array.persistence.dir = FOO
; キャッシュディレクトリは恐らくこう↑設定するのが正しいのだと思いますが、これだと動作しません。
; /wurfl-php-1.3.1/WURFL/Storage/File.phpのコンストラクタにdirパラメタが渡ってきません。
; こう↓すれば渡ってきます。
; resources.useragent.wurflapi.wurfl_config_array.persistence.dir.dir = FOO
; Zendの不具合??仕様??。


5. トラブルシュート1

これで設定はお終いでパスが正しく設定されていれば動作する、とのことですが、上手く行きません。

キャッシュディレクトリとして作成した
data/wurfl/cache
がWritableじゃないよ、と言われます。

chmod -R o+rwX data/wurfl/cache
してるのにな、と/wurfl-php-1.3.1/WURFL/Storage/File.phpを見てみると、

if(!is_writeable(dirname($this->root))){
    throw new WURFL_Storage_Exception("The file cache directory is not writeable: ".$this->root);
}

となっており、一つ上のdata/wurflディレクトリがWritableでないとエラーが出ます。

if(!is_writeable($this-&gt;root)){
に修正しても良さそうに見えますが、data/wurflのパーミッションを777にして対応しました。


6. トラブルシュート2

Fatal error: Class 'XMLReader' not found

となった場合は

$ yum install php-xml
$ service httpd restart
# それでもダメならコンパイルオプションの問題かも。


7. 実行

適当なコントローラで

$bootstrap = $this->getInvokeArg('bootstrap');
$userAgent = $bootstrap->getResource('useragent');
$device = $userAgent->getDevice();
var_dump($device);

してみると色々取れてて面白い。

// モバイル、PC、タブレット判定
$device->getFeature('is_mobile');
$device->getFeature('is_desktop');
$device->getFeature('is_tablet');
// モバイル、スマホ判定
$device->getFeature('device_os')
// SSLサポート
$device->httpsSupport();
// 最大画像サイズ(?)
$device->getMaxImageWidth();
$device->getMaxImageHeight();
// 画面解像度(?)
$device->getPhysicalScreenWidth();
// Flashサポート
$device->hasFlashSupport()
// audioサポート
if ($userAgent->hasFeature('mp3') && $userAgent->getFeature('mp3')) {
    // embed HTML5 audio tag...
}


8. 付録

エミュレータを使ったスマホ判定実験結果一覧。

端末名 OS device_os device_os_token brand_name
DC GALAXY NEXUS(SC-04D) Android 4.0 Android Android 4.0.1 Android
SB iPad iOS5 iPhone OS iPhone OS Apple
SB iPhone4 iOS5 iPhone OS iPhone OS Apple
DC HT1100 Windows Mobile 6 Windows Mobile OS Windows CE Generic
DC BlackBerry Bold 9700 BlackBerry OS5.0 RIM OS NULL RIM
DC NM850iG Symbian OS 8.0 NULL NULL DoCoMo

Symbianだけガラケー判定しそうだけど、基本的にはdevice_osの有り無しで見てしまっていいんではないだろうか。。

0 件のコメント:

コメントを投稿