‘php’ カテゴリーのアーカイブ

参照変数に関する注意点

2008年10月30日

関数で参照を返す

関数の戻り値を参照にする事もできます。関数名の前に&を付けて、戻り値が参照である事を明示しておきます。返ってきた参照を代入する時も同様に&を付けます。この場合、どちらの&が欠けても参照渡しにはなりません。

PHP

  1. function & toRef(&$val) {
  2.   return $val;
  3. }
  4. // 参照渡し
  5. $val = 'BEFORE';
  6. $ref =& toRef($val);
  7. $ref = 'AFTER';
  8. print $val;// AFTER
  9. // コピー渡し
  10. $val = 'BEFORE';
  11. $notref = toRef($val);
  12. $notref = 'AFTER';
  13. print $val;// BEFORE

関数に参照を渡したい時は、必ず定義する時に&を付けておく必要があります。
引数に&をつけて関数を呼ぶ方法は、今後廃止される予定です。

PHP

  1. // 正
  2. function func(&$arg) {}
  3. func($arg);
  4. // 誤
  5. function func($arg) {}
  6. func(&$arg);

インスタンス生成時の注意点

PHP4でコンストラクタ定義で&を付ける必要はありません。ただし、インスタンス生成時にnewがコピーを返すので注意が必要です。

PHP

  1. class Test {
  2.   var $value = 'foo';
  3.   function Test() {
  4.     $GLOBALS['test'] =& $this;
  5.   }
  6.   function set($value) {
  7.     $this->value = $value;
  8.   }
  9.   function display() {
  10.     echo '<br />' . $this->value;
  11.   }
  12. }
  13. $obj = new Test();
  14. $obj->set('bar');
  15. $obj->display(); // bar
  16. $test->display();// foo
  17. $obj =& new Test();
  18. $obj->set('bar');
  19. $obj->display(); // bar
  20. $test->display();// bar

インスタンスの代入

PHP5からインスタンスの扱いはJAVA同様に参照となります。

PHP

  1. $obj =& new Class();
  2. // PHP4
  3. $ref_obj =& $obj;// 2つは同じ
  4. $copy_obj = $obj;// 2つは独立
  5. // PHP5
  6. $ref_obj = $obj;// 2つは同じ
  7. $copy_obj = clone $obj;// 2つは独立

参考資料


ユーザーエージェント携帯判別

2008年10月30日

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

まとめ

PHP

  1. $agent = $_SERVER['HTTP_USER_AGENT'];
  2. if (preg_match('{^DoCoMo/[12]\.0}', $agent)) {
  3.   return 'd';// docomo
  4. } else if (preg_match('{^(J\-PHONE|Vodafone|MOT\-[CV]980|SoftBank)/}', $agent)) {
  5.   return 's';// softbank
  6. } else if (preg_match('/^KDDI\-|UP\.Browser/', $agent)) {
  7.   return 'a';// au
  8. } else if (preg_match('{^PDXGW/|DDIPOCKET;|WILLCOM;}',
  9.   $agent)) {
  10.   return 'w';// willcom
  11. } else {
  12.   return 'p';// pc
  13. }

更に詳しい端末情報が欲しい場合は個体識別番号(吐かない端末あり)を解析すれば取得できます。また、PDAの様なモバイルPCを判別したい場合はSHやSANYO、KYOCERAといった社名から判断できる場合があります。

参考資料

携帯サイト開発用品

  • iモードHTMLシミュレータ
    • i-mode用コンテンツ動作テスター
      ヘッダの確認や、サイズオーバー等の携帯特有の警告も確認できます。
      FLASHのテストも可能。
  • Openwave SDK
    • EZweb用コンテンツ動作テスター
      WAP2.0対応ブラウザとHDMLブラウザの切り替え機能付き。
  • User Agent Switcher Extension
    • Mozilla Firefoxでユーザーエージェントを偽装して携帯サイトの閲覧が可能に。

自前Utilityクラス

2008年10月30日

私が使っている便利な関数を紹介していきます。
ウェブアプリでは、文字をチェック、加工したい場面が頻繁に訪れます。
よく使う処理を関数化して、このクラスに集めておくと便利です。

番号とパスワードの妥当性チェック

PHP

  1. function isDigit($id) {
  2.   if (!preg_match('/^[1-9][0-9]*$/', $id)) $id = '';
  3.   return $id;
  4. }
  5. function isPass($pass) {
  6.   if (!preg_match('/^[0-9a-z]+$/i', $pass)) $pass = '';
  7.   return $pass;
  8. }

isDigitは、引数が0から始まらず数字のみで構成されているかどうかを判断します。
単に数字の羅列かどうかを調べたいなら、is_numeric関数が用意されています。
isPassは、引数が半角英数字のみで構成されているかどうかを判断します。

メールアドレス、URLの妥当性チェック

PHP

  1. function isMail($mail) {
  2.   if (!preg_match('/^[\w\-\.]+@[\w\-]+(\.[\w\-]+)+$/', $mail)) {
  3.     $mail = '';
  4.   }
  5.   return $mail;
  6. }
  7. function isUrl($url) {
  8.   if (!preg_match('/^(https?|ftp):\/\/[\w+$\;?-\/.%,!#~*:@&=]+$/', $url)) {
  9.     $url = '';
  10.   }
  11.   return $url;
  12. }
  13. // \w = 英数字[_a-zA-Z0-9]

メールアドレスの妥当性はこれで大体計れますが、厳密には相当長い正規表現になります。更に、携帯用アドレスには例外もあります。旧J-PHONE機で「?」「/」「+」が含まれるものや、上記関数では通りますが、ピリオドが連続するような不思議なアドレスも存在します。

文字列からURLをリンクで置換する

PHP

  1. function autolink($str) {
  2.   return preg_replace(
  3.     '/(https?|ftp)(:\/\/[\w+$\;?-\/.%,!#~*:@&=]+)/',
  4.     '<a href="$1$2">$1$2</a>', $str);
  5. }

第二引数の$1、$2は後方参照と言って、第一引数内括弧()一番目、二番目に相当します。
($0は第一引数の正規表現全部にマッチした文字列になります。)

秒数を計る

PHP

  1. function getMicrotime() {
  2.   list($usec, $sec) = explode(' ', microtime());
  3.   return ((float)$sec + (float)$usec);
  4. }
  5. // $start = getMicrotime(); ~ループなどの処理~ $end = getMicrotime();
  6. // 所要時間(秒) = $end - $start;

ベンチマークなど、処理経過時間を計算したい時に使います。
microtime

文字列の最初と最後の余分なホワイトスペースを取り除く

PHP

  1. function mb_trim($str, $chars='\s ') {
  2.   $str = mb_ereg_replace("^[$chars]+"'', $str);
  3.   $str = mb_ereg_replace("[$chars]+$"'', $str);
  4.   return $str;
  5. }
  6. // \s = 空白文字[ \t\n\r\f]

内蔵のtrim関数に全角スペースを追加した機能。
(PHPでマルチバイトを正確に扱うには注意が必要です。)
マルチバイト文字列関数
UTF-8の場合はpreg_replaceで書けます。

PHP

  1. function mb_trim($str, $chars='\s ') {
  2.   $str = preg_replace("/^[$chars]+/u"'', $str);
  3.   $str = preg_replace("/[$chars]+$/u"'', $str);
  4.   return $str;
  5. }

改行コードをBRタグに変換する

PHP

  1. function nlToBr($str) {
  2.   $str = preg_replace("/\x0D\x0A|\x0D|\x0A/""\n", $str);
  3.   $str = preg_replace("/\n{3,}/""\n\n", $str);
  4.   $str = str_replace("\n"'', $str);
  5.   return $str;
  6. }

フォームから受け取った文章内の改行をBRタグに変換します。改行を表す改行コードはOSによって異なる為、統一してから変換するとどのOSでも同じ効果が得られます。

OS 表示記号 改行コード 改行文字
Windows CRLF \x0D\x0A \n
Macintosh CR (Carriage Return 改行) \x0D \n
Unix LF (Line Feed 行頭復帰) \x0A \n

(注) 内蔵のnl2br(string)は改行文字の前に改行タグを挿入します。