記事表示

PHPでファイル入出力(続き)

この記事の続き。ファイル入出力の具体的なコード。

/* ファイルの先頭に追加 */
$no   = 0;
$data = '';

$fp = fopen('data.txt', 'r') or exit('error!');
while ($line = fgets($fp)) {
  if (intval($line) > $no) {
    $no = intval($line);
  }
  $data .= $line;
}
fclose($fp);

$no++;

$fp = fopen('data.txt', 'w') or exit('error!');
fwrite($fp, "$no\t" . date('H:i:s') . "\n$data");
fclose($fp);
/* ファイルの末尾に追加 */
$no   = 0;
$data = '';

$fp = fopen('data.txt', 'r') or exit('error!');
while ($line = fgets($fp)) {
  if (intval($line) > $no) {
    $no = intval($line);
  }
  $data .= $line;
}
fclose($fp);

$no++;

$fp = fopen('data.txt', 'w') or exit('error!');
fwrite($fp, "$data$no\t" . date('H:i:s') . "\n");
fclose($fp);
/* 任意の行を編集 */
$no   = 3;  //No.3のデータを編集
$data = '';

$fp = fopen('data.txt', 'r') or exit('error!');
while ($line = fgets($fp)) {
  if (intval($line) == $no) {
    $data .= "$no\t" . date('H:i:s') . "\n";
  } else {
    $data .= $line;
  }
}
fclose($fp);

$fp = fopen('data.txt', 'w') or exit('error!');
fwrite($fp, $data);
fclose($fp);
/* 任意の行を削除 */
$no   = 3;  //No.3のデータを削除
$data = '';

$fp = fopen('data.txt', 'r') or exit('error!');
while ($line = fgets($fp)) {
  if (intval($line) != $no) {
    $data .= $line;
  }
}
fclose($fp);

$fp = fopen('data.txt', 'w') or exit('error!');
fwrite($fp, $data);
fclose($fp);

でも、単にファイルの末尾にデータを追加し続ける場合は、'a+'を使って、ロックも自前で行ったほうが圧倒的に効率が良さそう。(この場合は、一時的にデータを保存する変数のために、無駄に巨大なメモリを消費する必要は無いので。)

/* ファイルの末尾に追加 */
$fp = fopen('data.txt', 'a+') or exit('error!');
flock($fp, LOCK_EX);

$no = 0;
while ($line = fgets($fp)) {
  if (intval($line) > $no) {
    $no = intval($line);
  }
}
$no++;

fwrite($fp, "$no\t" . date('H:i:s') . "\n");

flock($fp, LOCK_UN);
fclose($fp);

今のところ、こんな感じで。

ページ移動

トラックバックURL

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

トラックバック

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

コメント

tifos URL

こんばんわ。

何となくお気付きかと思いますが、fopen()の"w"モードは少々危険です。
特に「編集スクリプト」の場合、例えばfopen()後のfwrite()処理時にエラーでスクリプトが終了してしまうと…
ファイルの中身が空になったまま、文字通りthe endです。
ファイルロックの仕組みは、他プロセスからはロックしてくれますが、自プロセスのトラブルには無力です。

私もいろいろ試行錯誤の結果、編集の場合は、どんな瞬間にエラーで終了しても被害が最小限になるよう、
・"r+"モードのfopen()でファイルを開きっぱなしにする。(もちろん排他ロック)
・元データを消してしまわないようにファイルポインタを適切に操作しながら、上書き保存する。
という方法に落ち着きました。

ご参考まで。

  • 2008/03/24 00:41

ないと

こんばんはー。コメントありがとうございます。

> fopen()の"w"モードは少々危険です。

ご指摘ありがとうございます。
気になるものの、編集によってファイルの内容が減る場合には'w'モードを使うしかないのだと思っていました。(自動バックアップの仕組みでも作るしかないかなぁ…と考えていました。)

でも少し調べていると、'r+'を使った場合でもファイルポインタを操作すれば何とかなりそうなので、こんな風に変更してみました。↓
http://www.favorite-labo.org/blog/view/19

まだ細かく検証できていないですが、'w'を使わなくても何とかなりそうです。(^^)

  • 2008/03/24 23:57

コメント投稿

  • コメントを入力して投稿ボタンを押してください。
投稿フォーム
名前
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リーダーが表示されます。

利用ツール