ラベル PHP の投稿を表示しています。 すべての投稿を表示
ラベル PHP の投稿を表示しています。 すべての投稿を表示

2011年3月21日月曜日

[PHP] cakephp+sencha-touchでiphoneWebアプリ開発<停滞章>

iphone(ipod touch)でセッションが保持できないの件は

毎回(AJAX通信含む)のリクエストでセッションIDを生成しなおしているのが原因ぽい

ページリクエスト時のとAJAX時のサーバーのリクエストヘッダを見て判明した。



iphoneのsafariだとリクエストヘッダにCookie: ......がない

のでサーバー側で新たに生成してしまっている



ってことはsenchaの非同期通信機構にバグがあるのか?それともsafariの仕様なのか?



いずれにせよ解決にはまだ時間がかかりそうだ



2011年3月9日水曜日

[PHP] cakephp+sencha-touchでiphoneWebアプリ開発<序章その2>

セッションの件はわからないけれど、携帯用にSJIS出力する際のメモ

基本文字コードはUTF-8で統一ですが、一部ガラケーはUTF-8に対応していないので、Shift-JISに変換する必要があります。



app_controller.php(自分の場合はすべてのcontrollerの基底クラスとして定義) 内に以下のメソッドを定義します。




function beforeRender() {
parent::beforeRender();
if ($this->RequestHandler->isMobile()) {
if ($this->__isSmartPhone()) {
$this->viewPath = 's';
$this->layoutPath = 's';
} else {
$this->viewPath = 'm';
$this->layoutPath = 'm';
Configure::write('debug', 0);
$this->RequestHandler->respondAs('html', array('charset' => 'Shift_JIS'));
}
}
}



※beforeRender内ではレイアウトパスの変更と、文字コードヘッダの指定を(デバッグモードを切っておかないと面倒なようです)

この場合だとviews/layout/s/内にスマホのviews/layout/m/内にガラケー用のレイアウトファイルを配置します


function afterFilter()
{
parent::afterFilter();
if ($this->RequestHandler->isMobile() && !$this->__isSmartPhone()) {
//header("Content-type: text/html; charset=Shift_JIS");
//Configure::write('App.encoding', 'Shift_JIS');
$this->output = mb_convert_kana($this->output, 'rak');
$this->output = mb_convert_encoding($this->output, 'SJIS-win', 'UTF-8');
//$this->RequestHandler->respondAs('xhtml', array('charset' => 'Shift_JIS'));
}
}



※afterFilter内では出力するhtmlの文字コードを変換します。

後は送信データのコンバートをしないといけない(追記予定)

2011年3月8日火曜日

[PHP] cakephp+sencha-touchでiphoneWebアプリ開発<序章>

タイトルのとおり



iphone(ipod touch)のセッション引継ぎがなかなかうまくいかん

ブラウザから認証情報を非同期でpost⇒認証おk⇒セッションに値格納⇒ブラウザにレスポンス返す⇒レスポンスおkならリダイレクト

ってな流れで処理しているのだけど、なぜかiphone版に作った画面では引き継がれない



関係ないかもしれないけど、この問題がクリアになったら是非試したい情報があったのでメモ



認証情報保持時にクッキーの変わりにローカルストレージを使う

http://suin.asia/2009/09/13/iphone_local_strage_for_email_password_remainder



週末までには解決したいなぁ



2009年12月14日月曜日

[PHP]CakePHP モデルのfindメソッド等のfield

cakephpではDBアクセスがかなり簡単になっています。

findメソッドを使うだけで長いSQLを書く必要がなくなります。



で、使っていて詰まった所

・fieldを指定する時、エイリアスを使う時のASは大文字で無いと機能しません



以下は動作しません






$data = $this->hoge->find('all',
array(
'conditions' => array(),
'fields' => array(
'hoge.id as id',
'hoge.name as name'
)
)
);

2009年9月25日金曜日

[PHP] phpMyAdmin でポート指定

phpMyAdminでportの指定をする場合



config.inc.phpの以下の部分を改変する。



$cfg['Server'][$i]['port'] = '3306';

複数のサーバーを管理したい場合は上記の設定を増やす
※$iをincrementした上で



2009年7月24日金曜日

[PHP] QRコード作成ツール

PHPからQRコードを自動生成する事は可能とは知っていましたが

実際開発に携わったことはないんですよね。



ちょうど一つ前の、へびにょろ(携帯版)のエントリーでQRコードが使えそうだったので



QRコード作成&活用のススメ



こちらを利用させて頂いて、作成しました。



最近ASばかりでPHPから離れつつあるので、自前で作ってみるのも

リハビリがてら良いかもしれない

2009年1月24日土曜日

Smarty 文字操作

smartyを使用していて、テンプレート内で文字列の操作をしたいときのメモ



・配列やオブジェクトのプロパティなどを操作したい

{assign var="変数名" value="<配列、オブジェクトなど>"}

⇒{$変数名}で取り出せます。

⇒初期化もこれで出来ます。(空文字等を代入して)



・単純文字列置換をしたい

{$hoge|replace:'A':'B'}

⇒$hoge内の[A]という文字を[B]に変換します。



・foreach内でループ情報を取得したい

{$smarty.foreach.(foreach名).iteration} : 現在のループ回数

{$smarty.foreach.(foreach名).last} : 最後のループか



・PHPで定数定義した定数をテンプレート内で参照したい

{$smarty.const.(定数名)}



・PHPのグローバルスコープ変数を参照したい

{$smarty.post.(変数名)} : $_POST[(変数名)]に相当

{$smarty.get.(変数名)} : $_GET[(変数名)]に相当

{$smarty.session.(変数名)} : $_SESSION[(変数名)]に相当

{$smarty.cookie.(変数名)} : $_COOKIE[(変数名)]に相当

{$smarty.server.(変数名)} : $_SERVER[(変数名)]に相当




2008年9月24日水曜日

[php] file_get_contentsでのUA詐称

file_get_contentsでのアクセス時にUserAgentを変更する方法。



php.ini の user_agent を設定することで file_get_contents などのアクセス時のUserAgentを変更できるようですね。

��デフォルトは PHP という文字列とバージョンがUserAgentとして設定されています)



次のように ini_set 関数でも設定が可能のようです。

ini_set('user_agent', 'User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)');

2008年9月17日水曜日

[PHP] phpをコマンドラインから使う

phpをコマンドラインで使う方法

処理バッチとしては使った事があったけど、Cやperlみたく標準入力から対話型のプログラムも作れるみたい



http://www.spencernetwork.org/memo/tips-6.php


2008年9月7日日曜日

PHPインストール

やってきましたPHPインストールw

最新版の5.2.6をオフィシャルからダウンロードして展開



展開したフォルダにcdして

'./configure' '--prefix=/usr/local/php5' '--enable-pic' '--disable-rpath' '--enable-inline-optimization' '--with-bz2' '--with-curl' '--with-gd' '--enable-gd-native-ttf' '--with-gdbm' '--with-gettext' '--with-ncurses' '--with-gmp' '--with-iconv' '--with-openssl' '--with-png' '--with-jpeg' '--with-regex=system' '--with-xml' '--with-xsl' '--with-xmlrpc=shared' '--with-pcre' '--with-zlib' '--with-layout=GNU' '--enable-bcmath' '--enable-exif' '--enable-ftp' '--enable-safe-mode' '--enable-sockets' '--enable-sysvsem' '--enable-sysvshm' '--enable-wddx' '--with-pear=/usr/share/pear' '--with-mysqli=/usr/local/mysql/bin/mysql_config' '--with-mysql=/usr/local/mysql' '--enable-soap' '--enable-spl' '--enable-memory-limit' '--enable-shmop' '--enable-calendar' '--enable-dbx' '--enable-dio' '--enable-mcal' '--enable-mbstring' '--enable-discard-path' '--with-ttf' '--enable-xslt' '--enable-zend-multibyte' '--with-apxs2=/usr/local/apache2/bin/apxs' '--with-libjpeg-dir=/usr' '--enable-so' '--enable-gd-imgstrttf' '--with-jpeg-dir=usr/lib' '--with-freetype-dir=/usr'



いつもながら長っ!w



libxml2が無いよーと怒られるので

apt-get install libxml2-dev



opensslが無いよーと若干本気で切れられるので

apt-get install libssl-dev



bzip2が無いよーと半ば投げやりに呆れられるので

apt-get install libbz2-dev



ここからMDB関連のエラーでにっちもさっちもいかん状態に:;

↓に解決法があります。





libjpeg libpng libfreetype6 libgmp3 libxslt1

それぞれのdevを求められるので、これもaptでインストールしておく



で

make



rootにsuして

make install



↓DBA(QDBM)エラーの解決法


やっと対応策が判明したので追記



configure: error: DBA: Could not find necessary header file(s).

このエラーでコンパイル停止してしまう。



原因?と思われるものが書いてあるページ(英語)

http://bugs.php.net/bug.php?id=31585&edit=1



どうもQDBMのエラーと思っていたがGDBMのdevelが無いのが原因らしい

��色々試した結果)



やった事


  • qdbm関連モジュールのインストール

    apt-cache search qdbm

    で出てきたパッケージを片っ端からインストール

  • Tru64関連モジュールのインストール

    apt-cache search Tru64

    で出てきたパッケージを片っ端からインストール

  • GDBM関連モジュールのインストール

    apt-cache search gdbm

    で出てきたパッケージを片っ端からインストール




結局以上の事をしたが、おそらく必要だったのは以下のパッケージ

libgdbm-dev

tdb-dev



debianだからだろうか・・・

こんなエラー実務では見たことなかった。

ってかこれだけエラー内容が不明瞭でわかりずりーっつーの





09/04/26現在最新の5.2.9のコンパイルオプションは以下

'./configure' '--prefix=/usr/local/php5' '--with-pic' '--disable-rpath' '--enable-inline-optimization' '--with-bz2' '--with-curl' '--with-gd' '--enable-gd-native-ttf' '--with-gdbm' '--with-gettext' '--with-ncurses' '--with-gmp' '--with-iconv' '--with-openssl' '--with-png-dir=/usr/lib'  '--with-regex=system' '--with-xml-dir=/usr' '--with-xsl' '--with-xmlrpc=shared' '--with-zlib' '--with-layout=GNU' '--enable-bcmath' '--enable-exif' '--enable-ftp' '--enable-safe-mode' '--enable-sockets' '--enable-sysvsem' '--enable-sysvshm' '--enable-wddx' '--with-pear=/usr/share/pear' '--with-mysqli=/usr/local/mysql/bin/mysql_config' '--with-mysql=/usr/local/mysql' '--enable-soap' '--enable-spl' '--enable-shmop' '--enable-calendar'  '--enable-mbstring' '--enable-discard-path' '--with-ttf' ' '--enable-zend-multibyte' '--with-apxs2=/usr/local/apache2/bin/apxs' '--enable-gd-native-ttf  '--with-jpeg-dir=usr/lib' '--with-freetype-dir=/usr' '--with-pgsql=/usr/local/pgsql'

postgresをPHPから操作する場合は

/etc/ld.so.conf

に

/usr/local/pgsql/lib

を追記しておく。

※これをやっていないとapacheの起動でコケる





WEB鯖を立ち上げる時のインストールの順番は以下

・Apache

・(qmail)

・MySQL or Postgres

・PHP

2008年8月19日火曜日

array_merge

配列の結合に使われる

array_merge







(PHP 4, PHP 5)


array_merge -- ひとつまたは複数の配列をマージする




説明


array array_merge ( array array1 [, array array2 [, array ...]] )

array_merge() は、前の配列の後ろに配列を追加することにより、ひとつまたは複数の配列の要素をマージし、得られた配列を返します。


入力配列が同じキー文字列を有していた場合、そのキーに関する後に指定された値が、前の値を上書きします。しかし、配列が同じ添字番号を有していても 値は追記されるため、このようなことは起きません。


配列が一つだけ指定され、その配列が数字で添字指定されていた場合、 キーの添字が連続となるように振り直されます。


 











例 1. array_merge() の例








<?php

$array1 
= array("color" => "red", 2, 4);

$array2 = array("a", "b", "color" => "green", "shape" => "trapezoid", 4);

$result = array_merge($array1, $array2);

print_r($result);

?>

上の例の出力は以下となります。








Array

(

    [color] => green

    [0] => 2

    [1] => 4

    [2] => a

    [3] => b

    [shape] => trapezoid

    [4] => 4

)



 











例 2. 簡単な array_merge() の例








<?php

$array1 
= array();

$array2 = array(1 => "data");

$result = array_merge($array1, $array2);

?>

数値添字が振りなおされることに注意!








Array

(

    [0] => data

)

配列を完全に維持し、単に追加だけしたい場合には、+ 演算子を使用してください:








<?php

$array1 
= array();

$array2 = array(1 => "data");

$result = $array1 + $array2;

?>

数値添字は維持され、関連が保持されます。








Array

(

    [1] => data

)













警告

array_merge() の動作は PHP 5 で変更されました。PHP 4 とは異なり、 array_merge() は、array 型のパラメータのみを受け取るようになりました。しかし、 他の型をマージするために型キャストを使用することも可能です。詳細は以下の例を参照してください。


 











例 3. array_merge() PHP 5 の例








<?php

$beginning 
= 'foo';

$end = array(1 => 'bar');

$result = array_merge((array)$beginning, (array)$end);

print_r($result);

?>

上の例の出力は以下となります。








Array

(

    [0] => foo

    [1] => bar

)







2008年8月12日火曜日

smarty プラグイン作成法

http://www.y2sunlight.com/ground/?PHP5.0%2F8.Smarty%A4%F2%CD%FD%B2%F2%A4%B9%A4%EB

2008年8月11日月曜日

携帯UA まとめ

■携帯ブラウザのユーザーエージェント

  1. パソコンのブラウザと同様に、ドコモ、au、ソフトバンクの各携帯電話のブラウザのユーザーエージェントをプログラムで取得することができます。

  2. ユーザーエージェントを利用して機種判別やキャリア判別を行うことができます。

  3. ユーザーエージェントには、ドコモなら「DoCoMo」、au・TU-KAなら「UP.Browser」、ソフトバンクなら「J-PHONE」、「Vodafone」、「SoftBank」という文字が含まれてます。

    これでキャリア判別を行います。

    ただし、Vodafoneの一部の機種に「UP.Browser」という文字がユーザーエージェントの途中に含まれています。

    「先頭の文字が何で始まるか」で判別した方が良いと思います。

  4. ユーザーエージェントには、機種名が含まれています。

  5. ユーザーエージェントのサンプル

    ユーザーエージェントは、機種ごとにたくさんありますが、書き方のパターンは以下のどれかに当てはまります。

    詳細は、各キャリア公式サイトを参照。

    • ドコモの例

      • タイプ1(MOVA)

        DoCoMo/1.0/N503i/c10

        個体識別情報を得た場合は、

        DoCoMo/1.0/N503i/c10/ser12345678901

      • タイプ2(FOMA)

        DoCoMo/2.0 N901iS(c100;TB;W24H12)

        個体識別情報を得た場合は、

        DoCoMo/2.0 N901iS(c100;TB;W24H12;ser123456789012345;icc12345678901234567890)

      • /c10や(c100)が付かず、機種名で終わる場合もある。

      • 個体識別情報は、個体識別情報を参照。



    • auの例

      • 旧タイプ

        UP.Browser/3.04-SN12 UP.Link/3.4.4

      • 新タイプ

        KDDI-HI21 UP.Browser/6.0.2.254 (GUI) MMP/1.1

      • auは機種名ではなく、デバイスタイプ(SN12など)で表記されている。

        デバイスタイプと製品名の対応表は、キャリアのサイトにある。



    • ソフトバンクの例

      • SoftBank 4-2 Series(Jフォン時代のもの)

        J-PHONE/3.0/J-SH07

      • SoftBank 6-5 Series(Jフォン時代のもの)

        J-PHONE/4.0/J-SH51/SN12345678901 SH/0001a Profile/MIDP-1.0 Configuration/CLDC-1.0

      • SoftBank 3G Series(ボーダフォン時代のもの)

        Vodafone/1.0/V904SH/SHJ001/SN123456789012345 Browser/VF-NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1

      • SoftBank 3G Series(ソフトバンク時代のもの)

        SoftBank/1.0/910T/TJ001/SN123456789012345 Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1

      • 基本的に、J-PHONE(or Vodafone or SoftBank)/ブラウザバージョン/機種名/その他、になってます。





  6. IP帯域

    パソコンのブラウザでは、任意のユーザーエージェントに設定できるものがあります。

    ユーザーエージェントを携帯電話と同じにして、携帯サイトへアクセスされることも予想されます。

    完璧にパソコンからのアクセスを防ぐには、.htaccessなどで携帯電話で使われるIPアドレスの帯域を指定し、パソコンからのアクセスを防ぎます。

    各キャリアが使用しているIPの帯域は、公式サイトで公開されています。

  7. ホスト名

    ユーザーエージェントは、偽装できてもリモートのホスト名は、偽装できません。

    ユーザーエージェントの他にホスト名も判別に入れれば、より精度が高くなります。

    • ドコモ

      • docomo.ne.jp



    • au

      • ezweb.ne.jp



    • ソフトバンク

      • jp-d.ne.jp

        jp-h.ne.jp

        jp-t.ne.jp

        jp-c.ne.jp

        jp-k.ne.jp

        jp-r.ne.jp

        jp-n.ne.jp

        jp-s.ne.jp

        jp-q.ne.jp

      • jp-t などは、Jフォン東京などの名残。






■キャリア判別のサンプルソース

  • Perlの場合

    #ユーザーエージェントのみで判別する場合
    $agent = $ENV{'HTTP_USER_AGENT'};
    if($agent =~ /^DoCoMo/){

    }elsif($agent =~ /^J-PHONE|^Vodafone|^SoftBank/){

    }elsif($agent =~ /^UP.Browser|^KDDI/){

    }


    #ホスト名も判別する場合
    $agent = $ENV{'HTTP_USER_AGENT'};
    $host = $ENV{'REMOTE_HOST'};
    if($agent =~ /^DoCoMo/ && $host =~ /.+docomo\.ne\.jp$/){

    }elsif($agent =~ /^J-PHONE|^Vodafone|^SoftBank/ && $host =~ /.+jp-.\.ne\.jp$/){

    }elsif($agent =~ /^UP.Browser|^KDDI/ && $host =~ /.+ezweb\.ne\.jp$/){

    }


  • PHPの場合

    $agent = $_SERVER['HTTP_USER_AGENT'];
    if(ereg("^DoCoMo", $agent)){

    }else if(ereg("^J-PHONE|^Vodafone|^SoftBank", $agent)){

    }else if(ereg("^UP.Browser|^KDDI", $agent)){

    }


  • Javaの場合

    String agent = request.getHeader("user-agent");
    if(agent.indexOf("DoCoMo") == 0){

    }else if(agent.indexOf("J-PHONE") == 0 || agent.indexOf("Vodafone") == 0 || agent.indexOf("SoftBank") == 0){

    }else if(agent.indexOf("UP.Browser") == 0 || agent.indexOf("KDDI") == 0){

    }



■機種判別のサンプルソース(機種名を取得する)

  • Perlの場合

    • ドコモ

      $agent = $ENV{'HTTP_USER_AGENT'};
      if(index($agent, "DoCoMo/1.0") >= 0 && index($agent, "/", 11) >= 0){
      $device = substr($agent, 11, (index($agent, "/", 11) - 11));
      }elsif(index($agent, "DoCoMo/2.0") >= 0 && index($agent, "(", 11) >= 0){
      $device = substr($agent, 11, (index($agent, "(", 11) - 11));
      }else{
      $device = substr($agent, 11);
      }


    • au(エージェントは、2タイプとも取得できる)

      $agent = $ENV{'HTTP_USER_AGENT'};
      $device = substr($agent, (index($agent, "-") + 1), (index($agent, " ") - index($agent, "-") - 1));


    • ソフトバンク(x-jphone-msnameで機種名だけ取得できる)

      $device = $ENV{'HTTP_X_JPHONE_MSNAME'};




  • PHPの場合

    • ドコモ

      $agent = $_SERVER{'HTTP_USER_AGENT'};
      if(strpos($agent, "DoCoMo/1.0") >= 0 && strpos($agent, "/", 11) >= 0){
      $device = substr($agent, 11, (strpos($agent, "/", 11) - 11));
      }elsif(strpos($agent, "DoCoMo/2.0") >= 0 && strpos($agent, "(", 11) >= 0){
      $device = substr($agent, 11, (strpos($agent, "(", 11) - 11));
      }else{
      $device = substr($agent, 11);
      }


    • au(エージェントは、2タイプとも取得できる)

      $agent = $_SERVER{'HTTP_USER_AGENT'};
      $device = substr($agent, (strpos($agent, "-") + 1), (strpos($agent, " ") - strpos($agent, "-") - 1));


    • ソフトバンク(x-jphone-msnameで機種名だけ取得できる)

      $device = $_SERVER{'HTTP_X_JPHONE_MSNAME'};




  • Javaの場合

    • ドコモ

      String agent = request.getHeader("user-agent");
      String device = "";
      if(agent.indexOf("DoCoMo/1.0") >= 0 && agent.indexOf("/", 11) >= 0){
      device = agent.substring(11, agent.indexOf("/", 11));
      }else if(agent.indexOf("DoCoMo/2.0") >= 0 && agent.indexOf("(", 11) >= 0){
      device = agent.substring(11, agent.indexOf("(", 11));
      }else{
      device = agent.substring(11);
      }


    • au(エージェントは、2タイプとも取得できる)

      String agent = request.getHeader("user-agent");
      String device = agent.substring(agent.indexOf("-") + 1, agent.indexOf(" "));


    • ソフトバンク(x-jphone-msnameで機種名だけ取得できる)

      String device = request.getHeader("x-jphone-msname");





携帯UA 振り分け

NTT DoCoMo
MOVA ブラウザフォン
DoCoMo/1.0で始まる。
DoCoMo/1.0/N505iS/c20/TB/W20H10
FOMA (XHTML)
DoCoMo/2.0で始まる。
DoCoMo/2.0 F901iC(c100;TB;W23H12)
SoftBank
1G, 2G
J-PHONEで始まる。
J-PHONE/5.0/V801SH/SN000000000 SH/0005aa Profile
/MIDP-1.0 Configuration/CLDC-1.0 Ext-Profile/JSCL-1.1.0
3G (XHTML)
MOT-C980かMOT-V980で始まる。
MOT-C980/80.2F.2E. MIB/2.2.1 Profile/MIDP-2.0 Configuration/CLDC-1.1
MOT-V980/80.2F.2E. MIB/2.2.1 Profile/MIDP-2.0 Configuration/CLDC-1.1
3G (XHTML)
Vodafoneで始まるが、AUと同じUP.Browserが含まれる場合がある。
Vodafone/1.0/V802SH/SHJ000 Browser/UP.Browser/7.0.2.1 Profile
/MIDP-2.0 Configuration/CLDC-1.1 Ext-J-Profile/JSCL-1.2.2
3G (XHTML)
SoftBankで始まる。
SoftBank/1.0/910T/TJ001/SN Browser/NetFront/3.3 Profile
/MIDP-2.0 Configuration/CLDC-1.1
AU
WAP1 (HDML)
UP.Browserが含まれる。
UP.Browser/3.04-CA14 UP.Link/3.4.5.8
SIE-M65/12 UP.Browser/7.0.0.1.c.3 (GUI) MMP/2.0 Profile
/MIDP-2.0 Configuration/CLDC-1.1
WAP2 (XHTML)
KDDI-で始まる。
KDDI-CA23 UP.Browser/5.2.0.1.126 (GUI) MMP/2.0
WILLCOM
EDGE LINK
PDXGWで始まる。
PDXGW/1.0 (TX=8;TY=7;GX=96;GY=84;C=C256;G=BF;GI=2)
Air EDGE PHONE
DDIPOCKETが含まれる。
Mozilla/3.0 (DDIPOCKET;KYOCERA/AH-K3001V/1.5.2.8.000/0.1
/C100) Opera 7.0
Mozilla/3.0 (DDIPOCKET;JRC/AH-J3001V,AH-J3002V/1.0/0100
/c50) CNF/2.0
WILLCOM
WILLCOMが含まれる。
Mozilla/3.0(WILLCOM;SANYO/WX310SA/2;1/1/C128) NetFront/3.3
Mozilla/3.0(WILLCOM;KYOCERA/WX300K/1;1.0.2.8.000000/0.1/C100) Opera/7.0

携帯UAの固体識別番号

oCoMo
// MOVA
DoCoMo/1.0/X503i/c10/ser12345678901
serの後に11桁英数字

// FOMA
DoCoMo/2.0 N2001(c10;ser12345678901;
icc12345678901234567890)
serの後に15桁英数字
iccの後に20桁英数字
改行が含まれます。
PLAIN TEXTPHP: // ser以降で判別$agent = $_SERVER['HTTP_USER_AGENT'];$hasSubno = preg_match('/ser[0-9A-Za-z]{11,15}/', $agent);

SoftBank
// Vodafone
Vodafone/1.0/V802SH/SHJ002/SN123456789012345 Browser/UP.Browser/7.0.2.1 Profile/
MIDP-2.0 Configuration/CLDC-1.1 Ext-J-Pr

// SoftBank
SoftBank/1.0/705P/PJP10/SN123456789012345 Browser/Teleca-Browser/3.1 Profile/
MIDP-2.0 Configuration/CLDC-1.1

いずれも/SNの後に15桁英数字
PLAIN TEXTPHP: // /SN以降で判別$agent = $_SERVER['HTTP_USER_AGENT'];$hasSubno = preg_match('/\/SN[0-9A-Za-z]{15}/', $agent);

AU
AUの場合だけ先にユーザーエージェントに番号を付けます。

PLAIN TEXTPHP: // 05051234567890_ae.ezweb.ne.jp// 4桁地域コードと10桁端末コード$subno = $_SERVER['HTTP_X_UP_SUBNO'];// KDDI-CA23 UP.Browser/5.1 (GUI) MMP/2.0/SUB05051234567890_ae$_SERVER['HTTP_USER_AGENT'] .= '/SUB'.substr($subno, 0, -12);

PLAIN TEXTPHP: // 連結した末尾で判別$agent = $_SERVER['HTTP_USER_AGENT'];$hasSubno = preg_match('/\/SUB0\d0\d\d{10}_[a-z\d]{2}$/', $agent);