PHP用の組み込みDBを探してみました。JavaのHSQLDBやH2DBみたいに、アプリケーションに同梱して配布できたらいいなぁ・・・と。
PHPならMySQLとかが使いやすいんでしょうけど、不特定多数の人に配布するには敷居が高いような気がするんで。解凍してサーバのディレクトリに置くだけで使えるようなものが欲しかったんです。
検索してみると、見つけました。
その名も「Posql」!
普通のファイルをDBとして扱え、しかもSQLが使えるようですね。
今すぐには必要ないので忘れないようにメモ。いつか使ってみたいものです。
カテゴリ : PHP | コメント(0)
PHP経由でwmvを出力していると、MediaPlayerを直接起動するとうまくいかず、ダウンロードなら正常に処理が実行されるという、なんだかよくわからない現象に遭遇しました。
解決するのに少し手間取ったのでメモ。
MediaPlayerとサーバとの通信をパケットキャプチャでみると、ダウンロードとの違いは、MediaPlayerは複数のコネクションを張るということっぽいです。
ということは、2本目以降のコネクションでPHPが途中で止まっているんではないか?と目星をつけてコードを地道に追いかけて行きました。
すると、どうやらsession_startで止まっているようです。
で、Google先生にお伺いしてみると、『セッションデータは、同時書き込みを防ぐためにロックされるため、あ る時点であるセッションの処理ができるスクリプトは、1つだけです。』 と仰るではないですか!うすうす感づいていたんですが、書いているところが地味すぎます…。
結局、時間がかかる処理(今回はwmvの出力)の前に、session_write_close関数を呼んで、セッションのロックを解放することにしました。
・・・PHPのセッションの保存先をファイルではなくメモリとかにすればロックされないんですかね?
(参考資料)
PHPマニュアル: session_write_close
カテゴリ : PHP | コメント(0)
PHPで標準で以下のような機能が実装されています。
- ブラウザとの接続が切れた場合(ブラウザの「中止」ボタンが押された場合や閉じられた場合)に処理を中断する
- ブラウザからのリクエストがあってから、30秒以上経過しても処理が終わらなければ中断する
これらの機能は、スクリプトにバグがある場合などで処理が終了できなくなった際の予防です。ですが仕事でPHPを使っている場合、どうしても処理を中断させたくない場合があります。
この場合、上記の2つの機能を無効にする必要があります。ただしタイムアウト時間を無限にした場合、本当に無限ループに入っている場合に終わらなくなってしまいますので、タイムアウト時間を十分に長いものに指定することをお勧めします。設定方法は以下のようになります。
【php.iniに設定する場合】
ignore_user_abort = On
max_execution_time = 86400
【.htaccessに設定する場合】
php_value ignore_user_abort On
php_value max_execution_time 86400
【プログラム中で設定する場合】
ignore_user_abort(1);
set_time_limit(86400);
ただし、PHPがセーフモードで動いている場合は効果がありません。また、ブラウザで処理に時間がかかるプログラムを呼び出した場合は、定期的に何かを出力していないとブラウザ側でタイムアウトしてしまう場合があります。(処理自体は最後まで実行されます)
参考:
PHP マニュアル その他の関数(Misc)
PHP マニュアル PHP オプションと情報(info)
カテゴリ : PHP | コメント(4)
接続したデータベースやネットワークの切断だとか、テンポラリファイルの削除だとか、プログラミングしていると後処理を書くことがあるかと思います。
JavaやPHP5等ではfinally節やデストラクタで後処理を書くことが多いと思いますが、PHP4ではクラスは定義できますがデストラクタの仕組みはなく、finally節どころかcatchさえできません。
スクリプトの最後に後処理を書けばいいかとお思いの方がおられるかもしれませんが、それではexit関数が呼ばれた場合や、ブラウザの停止ボタンが押されて中止された場合に、最後に書かれた後処理が実行されなくなってしまいます。
そこで、PHP4では register_shutdown_function 関数を使います。
この関数に関数名を登録しておくと、スクリプト終了時に実行されることになります。
これは、ブラウザの停止ボタンを押した場合など、スクリプトが中止された場合でも有効です。
参考資料:
PHPマニュアル (register_shutdown_function)
カテゴリ : PHP | コメント(0)
現在サイトを見ている人の人数を数えたいという要求がありました。
HTTPは基本的に状態を持たないステートレスなものなので、厳密に言えばアクセス中の人数をカウントすることは不可能です。そこで(かなり曖昧ですが)、セッションが有効であればアクセス中とすることにします。
PHPにおけるセッションはデフォルトではファイルに保存されています(session.save_handlerで変更可能です)。1セッション につき1ファイルになり、無効なセッションは削除されていきます。そこでセッションファイルが保存されているディレクトリにあるファイルの数をアクセス中 の人数とすることとしました。ただし、同一サーバ上の他のサイトでもPHPを動かしていてセッションを使っている場合、そのままではセッションファイルが 保存されるディレクトリも共通になります。そこでセッションを開始する前に、対象のサイト独自でセッションファイルを保存するディレクトリを指定します。 スクリプト内で指定するには、以下のようにsession_save_path関数を使用します。これはsession_start関数の前に呼び出す必 要があります。
(例)
session_save_path(”session_dir”);
session_start();
セッションファイルをカウントするコードは以下のようになります。
(例)
function getActiveCount() {
$path = session_save_path();
if (empty($path)) {
return 0;
}
$files = glob("$path/sess_*");
if ($files === false) {
return 0;
}
return count($files);
}
できるだけ厳密に人数を数えたい場合は、セッションファイルの削除タイミングを調節する必要があります。これは、設定ファイルの以下の項目に該当します。
session.gc_probability
session.gc_divisor
session.gc_maxlifetime
session.cache_expire
参考:
PHPマニュアル CXXXVII. セッション処理関数(session)
カテゴリ : PHP | コメント(0)
ユーザが入力した文字列を画面に出力したい場合、気をつけるべき事柄がいくつかあります。
その一つが、今回のお題である「出力する文字列はサニタイジングすること」です。
PHPには文字列をエスケープするための関数がいくつか用意されていますが、サニタイジングするためにはhtmlentities関数を使用し、しかも第2と第3引数を指定する必要があります。
(例)
$string = htmlentities($string, ENT_QUOTES, mb_internal_encoding());
よくhtmlspecialchars関数が使われていたり、htmlentities関数を使っていても第1引数しか指定されていなかったりしますが、これでは穴が残ることになります。
参考:
PHP マニュアル htmlentities
カテゴリ : PHP | コメント(0)
レンタルサーバ等でPEARがインストールされておらず、またルート権限が使えないために新たにインストールできないときは、インクルードパスに自分が管理できるディレクトリをset_include_path関数で追加します。
やり方は以下のとおり。
1.プログラム内で自分の管理するディレクトリをインクルードパスに追加する
(例:set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . “/lib”);)
2.PEARのページ(http://pear.php.net/)から必要なパッケージをダウンロードする
(依存関係があるパッケージも全てダウンロードする)
3.1で追加したパスにダウンロードしたPEARパッケージのファイルをアップロードする
これでOKです。
カテゴリ : PHP | コメント(0)
PHPの最新メジャーバージョンが5になってから結構経ちますが、まだPHP4が多く使われているように思います。
PHP5とPHP4では完全な互換がないことはよく知られていますが、PHP5をPHP4互換モードとして動かすことができるのはご存知でしょうか。
この設定はphp.iniだけでなく.htaccessで指定できるので、環境を混在させるときに便利です。
.htaccessで設定するときは以下のように記述します。
php_flag zend.ze1_compatibility_mode On
これを設定すると、『Zend Engine 1 (PHP 4) との互換モードを有効にします。 この設定は、オブジェクトのコピー、キャスト (プロパティを 保持しないオブジェクトが FALSE あるいは 0 のいずれになるか)、 そして 比較 に影響を与えます。このモードの場合、オブジェクトを渡す際の デフォルトの方法は、参照渡しではなく値渡しとなります。』だそうです。
参考:
コア php.ini ディレクティブに関する説明
カテゴリ : PHP | コメント(0)
PHPはデフォルトでは、リクエストの入力にクォーテーション(’)、ダブルクォーテーション(”)、バックスラッシュ(\)がある場合に、自動的に前にバックスラッシュ(\)が付加されます。
これはセキュリティ上あったほうがいいのですが、自分でサニタイジングしたい場合に結構邪魔だったりします。
そんなときは.htaccessに
php_flag magic_quotes_gpc Off
と記述すると自動エスケープを抑制することができます。
参考:
PHP オプションと情報(info)
カテゴリ : PHP | コメント(0)
携帯用サイトを作るときなど、表示用の文字コードと内部の文字コードを別にしたい場合があります。このような時、下記のような設定を.htaccessに記述するとPHPが自動的に変換してくれます。
php_flag output_buffering On
php_value output_handler mb_output_handler
php_value default_charset UTF-8
php_value mbstring.language Japanese
php_flag mbstring.encoding_translation On
php_value mbstring.http_input auto
php_value mbstring.http_output UTF-8
php_value mbstring.internal_encoding UTF-8
php_value mbstring.substitute_character none
ここでの各項目の意味は次のようなものになるようです。文字コードを指定する箇所は”UTF8″、”EUC-JP”、”SJIS”等を記述します。ただし、default_charseにシフトJISを設定する場合は”Shift_JIS”にしたほうがいいかも。
| output_buffering |
出力バッファリングの有無 |
| output_handler |
スクリプトの全ての出力を関数にリダイレクトすることがでる
ここにmb_output_handlerを設定すると自動変換してくれる |
| default_charset |
HTTPのContent-typeヘッダで出力する文字コード |
| mbstring.language |
mbstringで使用される言語のデフォルト値 |
| mbstring.encoding_translation |
HTTP入力文字エンコーディング検出および内部文字エンコーディングへの変換を行うか |
| mbstring.http_input |
HTTP入力文字エンコーディングのデフォルト値 |
| mbstring.http_output |
HTTP出力文字エンコーディングのデフォルト値 |
| mbstring.internal_encoding |
内部文字エンコーディングのデフォルト値 |
| mbstring.substitute_character |
無効な文字を代替する文字 |
参考:
マルチバイト文字列関数(mbstring)
コア php.ini ディレクティブに関する説明
カテゴリ : PHP | コメント(1)