• ベストアンサー

携帯サイトでのユーザエージェントの振り分けについて

現在ドコモの携帯サイトを作成中です。 そこで以下の様に機種によってページを振り分ける予定です。 1.FOMAとmovaでまず振り分ける 2.movaの中でも505以上とそれ以下で振り分ける これらの処理をする際、ユーザエージェントを取って分岐する方法しか考えられないのですが、機種はどんどん新しいのが出ますし、その都度ソースを書き換えるのも…と思ってしまいます。 プログラミング自体自身がないので、どういう方法で振り分けるのかが最善なのか分かりません。 皆さんはどのように効率よく振り分けされているのでしょうか? よろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • leaz024
  • ベストアンサー率75% (398/526)
回答No.3

> 現在phpで開発初心者で、記入されているソースの意味がいまいちわかりません ん?ここはPerlのカテゴリなんですが・・・ 今回はPerlで、ということなのかな? 一応、解説はしますが、Perlは全く分からないとなると厳しいかもしれません。 なお、「正規表現」については http://www.sixnine.net/regexp/regexp1.html が参考になるかと思います。 簡単に言えば、文字列の内容があるパターン(規則)に従っているかどうかを調べるためのもので、この時に指定するパターンやその書き方を「正規表現」といいます。 ちなみにこの方法では、No.1の補足で心配されているような、新機種の登場ごとに処理を加える必要は全くありません。 では解説を。(まずは解析ルーチンの方) >   if ($ua =~ m!^DoCoMo/1\.\d/([^/]+)!) { 「$ua =~ m!正規表現!」で、$ua が mova のユーザエージェントであるかどうかを調べています。 ここでの正規表現は、 「(先頭)DoCoMo/1.(数字1文字)/(「/」でない文字が1文字以上)」 というものです。 >     $info{TYPE} = 'mova'; >     $info{MODEL} = $1;  # 機種名 >     ($info{SERIES}) = $info{MODEL} =~ /(\d+)/; info という名のハッシュ(連想配列)に、解析したデータを格納しています。 2行目の $1 は、先ほどの正規表現で ( ) で囲んでいた部分で、機種名が入っています。 3行目では、先ほどの機種名($info{MODEL})に含まれる数字の部分(シリーズ番号)を正規表現で取り出し、$info{SERIES} に格納しています。 FOMA の方も考え方は同じです。 次に分岐ルーチンの方を。 > if ($info{TYPE} eq 'FOMA') { 演算子 eq は、2つの文字列が等しいか調べます。 ※数値比較の場合は == を使いますが、文字列比較ではこちらを使います。 >   if ($info{SERIES} =~ /^5/ && $info{SERIES} >= 505) { if (条件1 && 条件2) という構文はいいですよね? 1つ目の条件 $info{SERIES} =~ /^5/ は、ここでも正規表現を使い、$info{SERIES} の先頭が 5 であるか調べています。 解析ルーチンでは正規表現に / が含まれていたので m!正規表現! という書き方をしましたが、本来はここのように /正規表現/ と簡略して書くことがほとんどです。 2つ目の $info{SERIES} >= 505 は、機種のシリーズ番号を数値比較し、505 以上であることを調べています。 つまり、現状では 505 と 506 のシリーズのみが真と判定されます。 これで主要部分は解説できたと思います。 もし、本当に Perl でプログラムを書かれるなら、もう少し基礎を学ばれるとよいと思います。

参考URL:
http://www.sixnine.net/regexp/regexp1.html
ponpon-kankan
質問者

お礼

すみません、質問をするカテゴリを間違えていたようです…。 開発もphpで行っています。 しかし、説明でよく分かり、目的の判別ができました! ありがとうございました!

その他の回答 (2)

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.2

何を以って「最善」とし、何の「効率」を求めているのかが不明ですので、「後のメンテナンス」に重点をおいてアドバイスしたいと思います。 振り分け処理というのは、   ユーザエージェントを解析し、   特定の条件を満たしていたら分岐する。 という2つの要素から成ります。このうち、前者は端末側の仕様に関する部分で、後者は自分側の仕様に関する部分です。 これらがごちゃ混ぜに入り組んだコードを書いてしまうと、自分側の仕様変更なのに端末側のコードまでいじることになったりして、労力がかさむ上にバグが入りやすくなります。なので、端末側の仕様に関する「ユーザエージェント解析ルーチン」と、自分側の仕様による「条件分岐ルーチン」を別にするとよいでしょう。 解析ルーチンでは、分岐ルーチンで利用しそうな情報を全て調べます。質問に書かれた条件からは、最低でも「mova/FOMA の別」と「機種のシリーズ番号」が必要です。他にも「機種名」くらいはあるとよいかもしれません。 # 解析ルーチンの例 sub getAgentInfo {   my ($ua) = @_;   my %info;   if ($ua =~ m!^DoCoMo/1\.\d/([^/]+)!) {     $info{TYPE} = 'mova';     $info{MODEL} = $1;  # 機種名     ($info{SERIES}) = $info{MODEL} =~ /(\d+)/;   }   elsif ($ua =~ m!^DoCoMo/2\.\d ([^(]+)!) {     $info{TYPE} = 'FOMA';     $info{MODEL} = $1;     ($info{SERIES}) = $info{MODEL} =~ /(\d+)/;   }   return %info; } ※ユーザエージェントの詳細は「DoCoMo Net(参考URL)」の「端末スペック」にある「ユーザエージェント一覧」や「ユーザエージェントの説明」などを参照してください。 ※DoCoMo/ に続くブラウザバージョンは、今のところ 1.0(mova)と 2.0(FOMA)しかありませんが、今後 . 以下の数字が変わらないとも限りませんので、正規表現 \d を使っています。 これを使った分岐ルーチンは、次のような感じです。 my %info = getAgentInfo($ENV{HTTP_USER_AGENT}); if ($info{TYPE} eq 'FOMA') {   # FOMA } elsif ($info{TYPE} eq 'mova') {   if ($info{SERIES} =~ /^5/ && $info{SERIES} >= 505) {     # mova の 505 以上   } else {     # mova の 505 未満   } } else {   # その他の端末 } ※「505以上」というのがよく分からなかったので、このような書き方をしました。意図と違っていましたら修正してください。 ※コード内に全角空白を使っているので、コピーする場合はタブ等に置き換えてください。

参考URL:
http://www.nttdocomo.co.jp/p_s/imode/make/
ponpon-kankan
質問者

補足

回答尾ありがとうございます。 ソースの意味はなんとなくわかりましたが、現在phpで開発初心者で、記入されているソースの意味がいまいちわかりません…(演算子?「=~」など)。すみません。 また、正規表現の意味が調べてみましたが、良くわかりません。 大変お手数ですが、意味を教えていただくとありがたいです。 よろしくお願い致します。

noname#25358
noname#25358
回答No.1

 あのエージェント情報という奴は、本来はあくまで人間が読むためにあるもので、フォーマットに規格があるわけではありません。  よって、「現在出ている各社の書式を信じる」か「書式を何らかの形でデータベース化しておく」か、どちらかの方策しかないように思います。  前者は、たとえばNTTの場合は DoCoMo/505/..... となるわけですが、現在は「先頭の DoCoMo は常に固定で 505 の部分がカウントアップしていく」という仕様になっています。  この仕様を全面的に信じるならば、将来 DoCoMo というキャリアがなくなるまでこの書式は有効であることになります。  後者の場合、たとえば "DoCoMo\/(\d+)" といったような正規表現文字列をデータファイルに格納しておき、そのデータファイルを書き換えるだけで将来の書式変更に備える方法です。  どちらも一長一短ですので、ご自分の判断でやられたらよろしいかと思います。

ponpon-kankan
質問者

お礼

回答ありがとうございます。 やはり、新機種の登場等にあわせてソースに条件を付け足して行くしかないのでしょうか…。

関連するQ&A

専門家に質問してみよう