まとめ ブログ ダウンロード 掲示板 メール

れぶろぐ

< 2008-12-26 (金) 2009-01-01 (木) > 最新


2008-12-30 (火)

ignore_user_abort(true) の設定はあまり意味がない

今まで、PHP 4 で file_put_contents() 相当の処理を行うには、以下のように書いていました。

function write_file($filename, $data)
{
    $fp = fopen($filename, file_exists($filename) ? 'r+b' : 'wb');
    if ($fp === false) {
        return false;
    }
    flock($fp, LOCK_EX);
    $last = ignore_user_abort(1);
    rewind($fp);
    $bytes = fwrite($fp, $data);
    fflush($fp);
    ftruncate($fp, ftell($fp));
    ignore_user_abort($last);
    fclose($fp);
    return $bytes;
}

ignore_user_abort() という珍しい関数を使っていますが、これは、 開発談義/23 - PukiWiki Plus! に書かれていたのを参考にしたものです。 でもこれって、本当に必要なのかな? とずっと思っていたのですが、最近、こんな記事を見つけました。

どうも、画面表示を含まない処理なら、わざわざ ignore_user_abort(true) に設定する必要は無いみたいです。 ということで、実験してみました。

<?php

ignore_user_abort(false);

$filename = 'log.txt';

$fp = fopen($filename, 'ab');
flock($fp, LOCK_EX);
for ($i = 0; $i < 10; ++$i) {
    fwrite($fp, "$i\n");
    sleep(1);
}
fclose($fp);

こんなスクリプト log.php を作って、

  • ブラウザ1から log.php にアクセス
  • ブラウザ2から log.php にアクセス
  • ブラウザ1の「中止」ボタンを押す

というのを数秒の間にやった場合、ログファイルがどうなるかというと、

0  // ブラウザ1からのリクエストに対する処理開始
1
2
3  // ブラウザ2からのリクエストに対する処理は、排他ロックがかかっているので後回し
4
5
6  // 「中止」ボタンが押されたが、処理はそのまま続けられる
7
8
9  // ブラウザ1からのリクエストに対する処理終了
0  // ブラウザ2からのリクエストに対する処理開始
1
2
3
4
5
6
7
8
9  // ブラウザ2からのリクエストに対する処理終了

のように、きちんと書き出されました。 やはり、上の file_put_contents() の例で言えば、ignore_user_abort() は不要っぽいです。

Tags: PHP | このエントリを含む del.icio.us | このエントリを含むはてなブックマーク | このエントリを含む livedoor クリップ | Permalink
本日のリンク元

編集