Archive for PHP

PHPセッションのGC

PHPのセッションハンドラをデフォルトで使っている場合のガーベージコレクタ(GC)の話。

PHPはサーバ上で保存してあるセッション情報を保存してあるファイルをを定期的に削除している。
削除するタイミングはPHPが起動する時、HTTPリクエストまたはコマンドラインからPHPが起動した際に一定の確立でGCが起動するようになっている。Javaのアプリケーションサーバならメモリ上にJVMが常駐しているからプログラムの起動とは非同期にできるが、PHPは同期で処理している。そのため、PHPではGCが起動したときにプログラムの実行時間が長ってしまう。

よって、大規模サイトになったときには必然的にセッションファイルが扱うセッションが多くなるため、GCにかかる時間が長くってしまうから、GCはPHPに任せないで自前で用意すべき。

PHPのGCを制御する設定はphp.iniに記載されている以下の3つ。

session.gc_probability = 1
session.gc_divisor     = 1024
session.gc_maxlifetime = 1440

GCの起動確立は、gc_divisor 分のgc_probability。上記の例では1/1024の確立でGCが起動する。
セッションファイルの最終変更時間がgc_maxlifetime秒以前だったらセッションを削除する。
(PHP4.2.3以降はファイルの最終更新日、それより前は最終アクセス時間)

gc_probabilityを0にすればPHPのGCは無効になる。

以下は、GCをcronで一定時間に削除する例。

*/10 * * * * daemon nice -n 18 find /tmp -type f -name "sess_*" -mmin +120 -exec rm {} \;

上記の例では、10分に1回GCを起動し、最終変更時間から2時間経ったら削除する例。
プロセスの優先度は低めにしてある。

PHPで2GB以上のファイルを扱う

x86のLinuxにてPHPを普通にコンパイルすると2GBまでのファイルしか扱えない!OSやファイルシステムが対応していても、だめ。普通にコンパイルするとファイルシステム周りは32bit空間(ファイルシステムだと約2GB分)しか扱えないらしい。

アプリケーションからログを出力してて、気づかないうちに2GBになったら、アプリケーションが途中で止まっちゃう。

ここに、対応策が書いてあった。
http://bugs.php.net/bug.php?id=36478

gccへ”-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64″というフラグをgccへ渡すと、ファイルシステム周りのライブラリは64bit空間を利用できるようになる。

例:

% CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" ./configure...

リモートホストのIPアドレスを表示。

サーバのアクセス制限をするときに自分のグローバルIPアドレスを調べたいときあるよね。
いちいち「確認君」というフレーズをぐぐるのがめんどくさいから、スクリプト作ってブックマーク入れておく方が楽。

グローバルIPアドレスだけ確認君

ソース

PHPのsleepとusleepのメモ

sleep(1) = usleep(1000000)

usleepの引数はマイクロ秒。

PHPのSession IDの長さを変更する

PHPのセッションIDの生成方法、長さを変えるにはphp.iniのsession.hash_bits_per_characterを変更する。

php.iniには以下のような説明が書いてある。

; Define how many bits are stored in each character when converting
; the binary hash data to something readable.
;
; 4 bits: 0-9, a-f
; 5 bits: 0-9, a-v
; 6 bits: 0-9, a-z, A-Z, “-”, “,”
session.hash_bits_per_character = 4

session.hash_bits_per_characterの値とセッションID文字数の対応

session.hash_bits_per_character
4 32
5 26
6 22

テストスクリプト

ミスターアクセス解析Lite調査

PHPで動くアクセス解析アプリケーションがあった。
Liteは無料でExは有償(約30万円)。

http://www.mr-analizer.com/

以下に簡単に利点欠点をまとめてみた。

メリット

  • HTMLでタグ埋め込みで、cookieを使っているためセッションをカウントできる
  • マーケティングに利用できる指標を出力してくれる。
  • 日本で作成されているので文字化けの対処をしないでいい
  • スクリプトの改編利用可能
  • URLのpathでグループ化可能
  • コンバージョンカウンター搭載

デメリット

  • コピーライトを挿入し、提供元へのリンクを入れる制約がある
  • 独自でログファイルを出力するためディスク容量を食う
  • PV毎に動作するスクリプトなのでサーバリソース(CPU,DISK)を食う
  • ログファイルのバックアップ設定を追加で行うことが必要に応じてある
  • 有償版にアップグレードするとなると高価(約30万円)

1度のメッセージ呼び出しに対する複数の例外補足

PHPにて、1度のメッセージ呼び出しで例外が発生し、

その例外の抽象度によってハンドリングする内容を変える方法は、tryを入れ子にしなければならない。

try{
  try{
      throw new OriginalException('exception');
    }catch(OriginalException $e){
    // handling for OriginalException
    throw $e;
    }
  }catch(Exception  $e){
  // handling for Exception
}

もっと詳しく >>

PHPの日時に関連する関数の制限

■問題意識
PHPが表現できる日付に制限があり、1800年といった表記をdate関数から
出力できないため、1800年から2500年程度の時間表現を行う方法を導く。

■実験内容
まず、制限値の詳細を知るために
1.date関数の第2引数に与えられるタイムスタンプの範囲を調べる。
2.strtotime関数の引数に指定できる時間の範囲を調べる。

■実験結果
1.date関数の第2引数にタイムスタンプとして指定した場合:
最小値:-2147483648(1901-12-14 05:45:52)
最大値: 2147483647 (2038-01-19 12:14:07)

2.strtotime関数の引数に時間を指定した場合
最小値: 1901-12-14 05:45:52
最大値: 2038-01-19 12:14:07

■まとめ
32ビット環境において、
PHPで整数を扱う場合は-2^31から2^31-1しか扱えない。

■次の問題意識
pearのDateクラスは有効か調査する。

■実験内容
2.1 コンストラクタに2147483647を指定し、
秒を追加してゆき、getDateを表示してみて
想定する結果との差異を検証。

2.2
コンストラクタに-2147483648を指定し、
秒を減らしてゆき、getDateを表示してみて
想定する結果との差異を検証。

■実験結果
2.1
9999-12-31 23:59:59 まで表示可能その後に1秒を足すと現在時刻に初期化される。

Date.phpのソースコードを追ってみると、年・月・日や時・分・秒はそれぞれ変数になっている。
なぜ、999年までしかいけないかというと、addSpanメソッドで無理矢理4桁に処理されているため。

2.2
999-12-31 23:59:59 まで表示可能。その後に1秒を引くと9909-12-31 23:59:58となる

■まとめ
西暦が4桁ならば正常に動作。

■次の問題意識
3.1 mktimeのサポートする範囲

■実験結果
3.1
年の入力に制限がある。
年の入力範囲:0-38,70-110,1903-2038

■まとめ
mktimeは1903年から2038年まで。

■次の問題意識
4.checkdateのサポートする範囲

■実験結果
4.西暦1年1月1日から、西暦32767年12月31日

■まとめ
西暦は16ビット分。チェックには利用可能。

■次の問題意識
mktime,strtotimeが表現できる日時に制限があるため、目的の範囲を
サポートする日時のvalidation方法はあるのか。

■調査
・symphonyはmktime,strtotimeを利用してチェック。
・zend frameworkはcheckdateにて日付をチェック。
・Mapleはcheckdateにて日付のみチェック。

■結論
PHPのネイティブ関数でサポートする日時表記の積集合部分は
1901-12-14 05:45:52から2038-01-19 12:14:07である。

日付のチェックはcheckdateを使えば実用に問題はない。

時間のチェックは自分で書く。

ネイティブでサポートされていない日時表記のためにはPearのDateクラスを利用すれば
1000年から9999年まで表現できる。

もっと詳しく >>

PHP 5.2.5 と nucleus

PHP5.2.5にしたらnucleusの管理ページにて、segmentention faultしちゃう。

5.2.4に戻したら解決

—————————————-

こんなんでいいんすか。PHPよ。

$a = 1;
$b = “1a”;

if($a == $b){
print ’same’;  // ←表示されるし。凸(`、´メ)
}

WebからPHPのPEARをインストール

新規案件のサーバをセットアップしているときに、pearでライブラリを入れていたら、
「Webのインストーラあるよ」と表示されたからちょっと試しに使ってみた。

PEAR: Optional feature webinstaller available (PEAR’s web-based installer)
PEAR: Optional feature gtkinstaller available (PEAR’s PHP-GTK-based installer)
PEAR: Optional feature gtk2installer available (PEAR’s PHP-GTK2-based installer)
To install use “pear install pear/PEAR#featurename”

初期設定はこんな感じ。ホームディレクトリは /home/matsu/ ね。

cd public_html
mkdir go-pear
cd go-pear
wget http://pear.php.net/go-pear
mv go-pear go-pear.php
chmod 777 /home/matsu/public_html/go-pear

go-pear.phpにアクセスしたところ。


1 start up, originally uploaded by supermatsubokkuri.

もっと詳しく >>

 

リンク