記事表示

PHPでファイル入出力

ファイル入出力と排他処理のメモ。

主にこのあたりを読んでみて、結局のところどうやってロックするか。すごく今更ですが、PHPからはデータベースばかり使っていたので自分用にメモしておきます。
あくまでもメモであって、上の内容のまとめとかでは無いです。ツッコミは歓迎。

data.txt に、1行を1件として処理番号と処理時間を記録していくとする。具体的には以下のようなデータファイルを扱うとする。(<tab> の部分はタブが入る。)

4<tab>17:02:08
3<tab>16:53:20
2<tab>16:43:03
1<tab>16:42:02

データの破損を避けるために、ファイル入出力の際はロック処理を行う。

$fp = fopen('data.txt', 'r+') or exit('error!');
flock($fp, LOCK_EX);  //有効なロック
fwrite($fp, '追記したいデータ');
flock($fp, LOCK_UN);
fclose($fp);

ただし、'r+' だとファイルの内容がクリアされないので、文章を編集したり一行削除したりする場合には利用できない(以前の内容がファイル内に残ってしまう可能性がある。)つまり「ファイルサイズが増えることがあっても減ることはない」という場合は 'r+' でのロックは有効だが、「ファイルの内容が減る可能性がある」という場合には使えない。

このような場合には 'w' でオープンすると、以前の内容がクリアされる。ただし、ロック方法に注意する。

$fp = fopen('data.txt', 'w') or exit('error!');
flock($fp, LOCK_EX);  //fopenの時点でファイルがクリアされるので、このロックは無意味
fwrite($fp, '書き込みたいデータ');
flock($fp, LOCK_UN);
fclose($fp);

この処理はロックができていないけど、ロック処理の例としてこのコードが紹介されていることは多い気がする…。

で、'w' を使う場合の、定番のロック方法は無いっぽい。
処理方法を色々変えるのもヤヤコシイので、入出力を行うファイル自体にはロックを行わず、ロック専用ファイルを用意した方が良さそう。

以下の自作関数で、ファイルロックを行う。

function file_lock()
{
  $fp = fopen('lock.txt', 'w') or exit('error!');
  flock($fp, LOCK_EX);

  return $fp;
}

function file_unlock($fp)
{
  flock($fp, LOCK_UN);
  fclose($fp);
}

file_lock() でロックを行い、file_unlock() でロックを解除する。つまり、ファイルロック用に lock.txt を用意し、このファイルに排他処理を行う。実際に読み書きするファイルにはロックを行わない。(排他ロック中は他のプロセスが割り込めないので、ロックは1つかければ十分。)

具体的には以下のような流れで処理する。

$lp = file_lock();

~ここでファイルの読み書き~

file_unlock($lp);

ファイル入出力を行う際は「ファイルの内容を読み込みモードで開き、一旦変数に読み出す。その後ファイルを書き込みモードで開き、一気に書き込む」に統一してみる。

続く

ページ移動

トラックバックURL

  • http://www.favorite-labo.org/blog/trackback/18

トラックバック

  • トラックバックはまだありません。

コメント

  • コメントはまだありません。

コメント投稿

  • コメントを入力して投稿ボタンを押してください。
投稿フォーム
名前
Eメール
URL
コメント
投稿キー

投稿キーには以下の数値を半角で入力してください。(スパム対策)

投稿キー

ユーティリティ

2008年12月

- 1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31 - - -

ツールメニュー

メッセージ

匿名で一言送信できます。

送信フォーム
メッセージ

RSSリーダー

  • JavaScriptをONにすると、RSSリーダーが表示されます。

利用ツール