効率的な条件分岐の方法を探す

このQ&Aのポイント
  • アクセス端末によって見え方を変えさせるため、条件節ifで分岐させているが、コードが長くなりすぎて制作に支障が出ている。
  • アクセスの95%程度うまく分けられれば良いため、共通の部分を見つけてまとめているが、それでも非効率かつ長くなってしまう。
  • =~で別で用意したデータを,で分解してそれぞれと比べる方法などを模索中。
回答を見る
  • ベストアンサー

複数の比較( =~ )を効率よくまとめたい

アクセス端末によって見え方を変えさせるため、条件節ifで =~ を使って分岐させているのですが、ユーザーエージェントがあまりにも多く、コードが長くなりすぎ制作に支障が出てきています 100%完璧に分岐させるところまでは求めていないため(アクセスの95%程度うまく分けられればいいかと思ってます)、たとえばスマホの場合はiPhoneとかAndroid、PCの場合はMSIEなど極力共通の部分を見つけてまとめてはいますが、それでも携帯、スマホ、PCと分けると非常に多くなり、 if(($ENV{'HTTP_USER_AGENT'} =~ /MSIE/) || ($ENV{'HTTP_USER_AGENT'} =~ /Firefox/)){} など比較の片方は同じなのに同じことを何度も書く必要があり、非効率かつ強烈に長くなってしまい何とかまとめられないかと格闘しています たとえば別で $os_pc = "MSIE,Firefox"; $os_mb = "DoCoMo,KDDI"; など別でまとめて、 if($ENV{'HTTP_USER_AGENT'} =~ /$os_pcの,で分解したそれぞれの文字列と比較/){ PCと判定 }elsif($ENV{'HTTP_USER_AGENT'} =~ /$os_mbの,で分解したそれぞれの文字列と比較/){ 携帯と判定 } といったように、スマートに条件分岐させられないかと模索中ですが、=~ で別で用意したデータを,で分解してそれぞれと比べるとかできないでしょうか。 =~での比較ではなく、他の方法でもかまいませんので、ぜひお知恵をお貸しください。 よろしくお願いします。

  • choei
  • お礼率63% (286/451)
  • Perl
  • 回答数4
  • ありがとう数4

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

  • ベストアンサー
  • t-okura
  • ベストアンサー率75% (253/335)
回答No.2

端末タイプの表を作って繰り返しの中で判定してはどうでしょうか。 use strict; use warnings; use Encode; use utf8; my %agent_type = ( qr/msie/i => 'pc', qr/firefox/i => 'pc', qr/docomo/i => '携帯', qr/kddi/i => '携帯', ); my $ua = $ENV{'HTTP_USER_AGENT'}; my $ua_type = "その他"; foreach my $key ( keys %agent_type ) { if ( $ua =~ $key ) { $ua_type = $agent_type{$key}; last; } } print Encode::encode( 'utf8', $ua_type ), "\n"; ハッシュで作った表だと、上から順に比較されるわけではないので、比較パターンとする文字列はユニークにしないといけません。

choei
質問者

お礼

回答ありがとうございます 確かに表にしてforeachで比較すると別でまとめられてすっきりします。 ただ、「比較パターンとする文字列はユニークに」のユニークとはどういう意味でしょうか? 補足頂けますとありがたいです

その他の回答 (3)

  • t-okura
  • ベストアンサー率75% (253/335)
回答No.4

> ただ、「比較パターンとする文字列はユニークに」のユニークとは > どういう意味でしょうか Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; InfoPath.1 Mozilla/5.0 (Windows NT 6.0; rv:7.0.1) Gecko/20100101 Firefox/7.0.1 のようなユーザエージェントがあるとき、 if ($ENV{'HTTP_USER_AGENT'} =~ /MSIE/) { } elsif ($ENV{'HTTP_USER_AGENT'} =~ /Mozilla/) { } ... のようにするときは、比較順序が決まっているので Firefox が最初の条件に一致することはありません。 しかし、keys で取り出したハッシュのキーはどういう順序になるかわからないため、上の例の2番目の比較が先に行われ、どちらも同じブラウザと判定されてしまうかもしれません。 これを避けるために、どんな順序で比較されてもよいよう、区別したいユーザエージェントだけに一致するようなパターンを指定する必要があります。

choei
質問者

お礼

回答ありがとうございます。 「唯一無二」という意味でのユニークだったのですね、ありがとうございました (ユニークという意味は人によって違う意味で使われますし、プログラミング用語の中での専門用語なのかなとも考えていて分かりませんでした) 確かに仰る通りハッシュはどの順番で格納されるか分からないので、ユーザーエージェントをまとめる時に問題になりますね 特にSafariで今悩んでます ありがとうございました

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

Tie::RegexpHash なんてのもあるみたい.

choei
質問者

お礼

ありがとうございます。 CPAN読んでみたのですが、今ひとつ理解できず、他サイトのサンプルを探してみたのですが思うようなものが出てきませんでした。 また時間をかけてこのコードは勉強させて頂きます

回答No.1

単純に正規表現をちゃんと使うのではダメなのですか? if ($ENV{'HTTP_USER_AGENT'} =~ /(MSIE|Firefox)/) { PCと判定 } elsif ($ENV{'HTTP_USER_AGENT'} =~ /(DoCoMo|KDDI/) { 携帯と判定 } という具合で。

choei
質問者

お礼

早速の回答ありがとうございます 確かに|ですれば少しスリムになりますが、それでもかなり比べるものが多いのであれこれ書き並べるとモニター上で何行にもなるため、できればMSIEとかKDDIとかといったものを別のところに一括してまとめて、この条件節のところではもっとシンプルにできないかと考えています。

関連するQ&A

  • orとelsif

    質問があります。 HTTP_USER_AGENTによって携帯端末とPC端末を振り分けるCGIを製作中です。 その際に疑問に思ったのですが、 if(($ENV{'HTTP_USER_AGENT'} =~ /***/i) or ($ENV{'HTTP_USER_AGENT'} =~ /***/i) or.....{ ~~~ } のように1行でorで繋げる方法と if($ENV{'HTTP_USER_AGENT'} =~ /***/i){ ~~~ } elsif($ENV{'HTTP_USER_AGENT'} =~ /***/i){ ~~~ } のようにelsifで繋げる方法とどちらが効率がいいのでしょうか? メモリの消費 サーバーへの負担 処理の速度 を中心にお願いします。

    • ベストアンサー
    • Perl
  • 携帯端末認識User-Agentについて

    初心者なのですが、CGIで携帯サイトを作っていますが。 実機がうまく動きません。User-Agentに問題があると考えています。 現在のソースと主な現象を記しますので、適切なものを教えて下さい。お願いします。 #----------# # 端末認識 # #----------# sub useragent { my $ua; #次にi-mode端末かどうかチェック if ($ENV{'HTTP_USER_AGENT'} =~ /^DoCoMo\/\d/) { $ua = 1; #次にJ-Phone端末かどうかチェック } elsif ($ENV{'HTTP_USER_AGENT'} =~ /^J-PHONE\/\d/) { $ua = 2; #EZweb端末かどうかチェック } elsif (($ENV{'HTTP_USER_AGENT'} =~ 'UP.B') && ($ENV{'HTTP_X_UP_SUBNO'} ne "")){ $ua = 3; #その他はPCとする } else { $ua = 0;} #PCブラウザ再判定 if ($ENV{'HTTP_USER_AGENT'} =~ /Mozilla\/|MSIE|Netscape|Opera|Lynx|AOL|Gecko/) {$ua = 0;} return $ua; } 主な現象 AU:ページ表示ごとに、いちいちブラウザメニューからページ更新をしなければならない(AUの特性もありますが) ソフトバンク:携帯版ではなく、PC版が表示されてしまう。 ドコモ :Pは問題ないようだが、SHは会員登録画面のフォームが半分の項目しか表示されず、次のページで残りの半分 は表示されるが、フォームにすべて書き込んで、登録送信をクリックしても、エラーデータ、の表示が出る。

    • 締切済み
    • CGI
  • 書き方を教えてください

    まだ初心者なのですが、 if($ENV{'HTTP_USER_AGENT'} =~ /UP.Browser/) { unless($ENV{'HTTP_X_UP_SUBNO'} =~ /.ezweb.ne\.jp$/) { push(@error, '番号を通知して下さい。'); } } という構文を作りました。 ($ENV{'HTTP_X_UP_SUBNO'} =~ /.ezweb.ne\.jp$/) もしくは unless($ENV{'HTTP_USER_AGENT'} =~ /SN/) の時に push(@error, '番号を通知して下さい。'); と言うように書きたいのですが、どう書いて良いかわかりません。 どなたか教えてください。

    • ベストアンサー
    • Perl
  • ブラウザ毎に外部CSSファイルでデザイン変更したい

    CGIソースファイル http://www.loplopland.com/test/newfile.html このCGIでインターネットエクスプローラーだけ別の外部CSSファイルでデザイン変更したいんですが、どのようにしたらいいでしょうか? 別のところで $ua = $ENV{'HTTP_USER_AGENT'}; if (index($ua, "compatible; MSIE") >= 0) { $stylebase = "stylebase_IE.css"; } else { $stylebase = "stylebase.css"; } を入れたらいいと言われたんですが、どこにどう入れたらいいかいまいちわかりませんでした。

  • ユーザーエージェント IE6のブラウザ判別について

    調べているんですが、解決に至らず… 教えていただけると助かります! phpで、ブラウザ判別(ユーザーエージェント)を行い、IE6の場合のみ別ページへジャンプさせています。 全てというわけではないのですが、IE7でもIE6と認識される場合があり、困っています。 スクリプトは以下のとおりです。 <?php $user_agent = $_SERVER['HTTP_USER_AGENT']; $msie6 = ereg('Mozilla/4.0 (compatible; MSIE 6.0)', $user_agent); if ($msie6) { include( "http://○○/attention" ); } else { ?> <html>~ IE7のブラウザのうち、IE6と認識されるブラウザの法則性は分かりません。 いろいろと調べてみましたが、辿りつかず、類似の解説があれば教えてください。 また、上記スクリプトがおかしい点ありましたら教えてください! よろしくお願いします!

    • ベストアンサー
    • PHP
  • スマホのみアクセス可能なサイトを作りたい

    のですが、PCからのアクセスを遮断、もしくは別フォルダに飛ばしたいと考えております。 その際に.htaccessファイルなどを活用したのがうまく行きません。 方法をご存知ないでしょうか? 閲覧可能⇒スマホ(アイフォン&アンドロイド) 閲覧不可⇒PC(携帯は見れても良い。) ↓現在設定中 # Options -Indexes # < IfModule mod_rewrite.c> # iPod RewriteCond %{HTTP_USER_AGENT} iPod RewriteRule ^$ index.html [R] # iPhone RewriteCond %{HTTP_USER_AGENT} iPhone RewriteRule ^$ index.html [R] # Android RewriteCond %{HTTP_USER_AGENT} Android RewriteRule ^$ index.html [R] # PC Internet Explorer Firefox RewriteCond %{HTTP_USER_AGENT} Mozilla RewriteRule ^$ /pc/ [R] # PC Opera RewriteCond %{HTTP_USER_AGENT} Opera RewriteRule ^$ /pc/ [R] # Mac Safari RewriteCond %{HTTP_USER_AGENT} Safari RewriteRule ^$ /pc/ [R] # < /IfModule>

  • ユーザーエイジェントの置き換え

    ユーザーエイジェントを検索して UP.Browserという文字列があった場合、 ユーザーエイジェントをauという置き換え表示したいと思っています。 具体的には KDDI-KC3R UP.Browser/6.2_7.2.7.1.K.4.310 (GUI) MMP/2.0 ↓ au と表示したいのですが、 Perlで記述する場合以下のように書いて間違えありませんか? 間違いなどありましたご指摘ください。 if($ENV{'HTTP_USER_AGENT'} =~ /UP.Browser/) { $agent=~s/$ENV{'HTTP_USER_AGENT'} /au/g; }

    • ベストアンサー
    • Perl
  • perlでアクセス端末の解像度を知りたい

    アクセス元の端末(たとえばスマホなのかPCなのか)で表示する画像を変えたいため、アクセス端末の解像度を取得したいのですがどうすればよいでしょうか? いろいろ探してみたのですが、javascriptばかりヒットし、use Term::ReadKeyというものも出てきたのですが、その参考ページをそっくり入れてみても動作しません。 sub agent{ %agent_type = ( qr/MSIE/i => 'p', qr/iPhone/ => 's', qr/iPad/ => 't', qr/Android/ => 's', 一部省略 ); } sub browser{ &agent; my $ua = $ENV{'HTTP_USER_AGENT'}; foreach my $key(keys %agent_type){ if ($ua =~ $key){ $ua_type = $agent_type{$key}; last; } } } 上記のような環境変数で振り分けることも考えたのですが、Androidだとスマホとタブレットと解像度が大きく違うものでも同じものをはき出してしまうかと思い、正確な振り分けができず困っています。 どうかperlだけで解決できる方法がありましたらぜひ教えてください。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • CGIにてソフトバンクがPCとして認識されます。

    掲示板のCGIなのですが、ソフトバンクではPC画面へ飛ばされてしまいます。下記の部分あたりではないかと思うのですが、書き直しで解決できるのでしょうか?このCGIを使いたいので、お願い致します。 #▼ホスト名・UA取得 $HOST = $ENV{'REMOTE_HOST'}; $ADDR = $ENV{'REMOTE_ADDR'}; $UA = $ENV{'HTTP_USER_AGENT'}; $SN = $ENV{'HTTP_X_UP_SUBNO'}; if ($UA =~ /^DoCoMo\/\d/) { $AGEN = "i-mode"; }elsif ($UA =~ /^Vodafone\/\d/) { $AGEN = "Vodafone"; }elsif (($UA =~ 'UP.B') && ($SN ne "")){ $AGEN = "AU"; }else { $AGEN="PC";} if ($UA =~ /Mozilla\/|MSIE|Netscape|Opera|Lynx|AOL|Gecko/) {$AGEN="PC";} if ($HOST eq '') { $HOST = $ADDR; } if ($HOST eq $ADDR) { $HOST = gethostbyaddr(pack('C4',split(/\./,$HOST)),2) || $ADDR; }

    • 締切済み
    • CGI
  • ユーザーエージェント(ソフトバンク)

    初めて投稿いたします。 現在PHPで携帯とPCの振り分けのプログラムを 作っていますが、ソフトバンクのエミュレーターで 試したところ、どうしてもPCの方のサイトへ飛んでいってしまい ます。ユーザーエージェントは "SoftBank"を返すはずなので 問題ないはずなんですが、どなたか原因が分かりましたら ご教授いただけると大変幸いです。 ----------------------------------------------------------- $user_agent= explode( "/", $_SERVER['HTTP_USER_AGENT']); $GB['user_agent0']=$user_agent[0]; if(preg_match("/^KDDI/",$user_agent[0])) $GB['env'] = "i"; switch( $user_agent[0] ){ case "DoCoMo" : case "L-mode" : case "ASTEL" : case "UP.Browser" : case "PDXGW" : case "SoftBank" : case "Vodafone" : case "J-PHONE" : $GB['env'] = "i";

    • 締切済み
    • PHP

専門家に質問してみよう