flock関数の基本構文
ファイルのロックを行います。共有ロック、排他ロック、ブロックモードのコントロールができます。
flock ( resource $handle, int $operation , int &$would_block = null ) : bool
パラメータ
型 | 名前 | 初期値 | 説明 |
resource | $handle | fopenで取得したファイルポインタを管理するリソース型のオブジェクト(ファイルハンドラやファイルストリームと同意) | |
int | $operation | ロックの機能を指定する ※後述の説明参照 | |
int | &$would_block | null | ロックがブロック(errno=EWOULDBLOCK)された場合に1になる |
ロックの種類
共有ロック(読み込みロック)→読んでいるので他の人が書くの禁止
排他ロック(書き込みロック)→書いているので他の人は読みも書きも禁止
設定値 | 機能 | 説明 |
LOCK_SH | 共有ロック(読み込みロック) | 読むときに使う。他人は読んでいいが書くの禁止 |
LOCK_EX | 排他ロック(書き込みロック) | 書くときに使う。他人は読むのも書くのも禁止 |
LOCK_UN | ロック解除 | |
LOCK_NB | 非ブロックモード | 他者アクセス時に待たずにすぐにエラー返す |
ブロックモード・非ブロックモードについて
LOCK_SH, LOCK_EXではブロックモードで動作します。
ブロックモードとはロックしたファイルに他者がアクセスした際、ロックが解除されるまで待機させるモードです。
逆に非ブロックモードは待機せずに即座に失敗(false)を返すモードです。
これにするにはLOCK_SH | LOCK_NBなどとLOCK_NBを組み合わせて使います。
返り値(戻り値)
型 | 説明 | 例 |
bool | 成功 true 失敗 false |
flock関数の使い方
ファイルを1行ずつ読み込んで表示するサンプルソースコード
//=======================================================
// ファイルから1行ずつ読み込んで表示するサンプル
//=======================================================
$read_file = 'input/line-1.txt'; //読み込みファイル
// ファイルのオープン
$fp_r = fopen($read_file, "rb"); //読み込みファイルオープン
// 読み込みファイルを1行ずつ読み込みループする
while (($buffer = fgets($fp_r)) != false) {
echo $buffer; //表示
}
fclose($fp_r); //読み込みファイルクローズ
ファイルを1行ずつ読み込んで表示するサンプルソースコード【ロック&エラー処理あり完全バージョン】
//=======================================================
// ファイルから1行ずつ読み込んで表示するサンプル(ロック&エラー対応版)
//=======================================================
$read_file = 'input/line-1.txt'; //読み込みファイル
try{
echo "処理開始" . PHP_EOL;
//---------------------------------------
// 読み込みファイルのオープン&ロック処理
//---------------------------------------
$fp_r = fopen($read_file, "rb");
if(is_resource($fp_r) === true){
echo "読み込みファイルオープン成功 {$read_file}" . PHP_EOL;
if (flock($fp_r, LOCK_SH) === true) { // ファイルをロックする(共有ロック)
echo "読み込みファイルのロック成功 {$read_file}" . PHP_EOL;
}else{
throw new Exception("読み込みファイルのロック失敗 {$read_file}");
}
}else{
throw new Exception("読み込みファイルオープン失敗 {$read_file}");
}
//---------------------------------------
// 読み込みファイルを1行ずつ読み込みループする
//---------------------------------------
$line_num = 0;
while (($buffer = fgets($fp_r)) != false) {
++$line_num;
echo $buffer;
}
//---------------------------------------
//終了後のチェック
//---------------------------------------
if (feof($fp_r) === false) {
throw new Exception("読み込みファイルが最後まで処理されていません {$read_file}");
}
echo "正常終了" . PHP_EOL;
}catch(Exception $ex) {
//---------------------------------------
// エラー処理
//---------------------------------------
echo "エラーメッセージ: " . $ex->getMessage() . PHP_EOL;
} finally { //finallyはPHP5.5より
//---------------------------------------
// 後処理。正常終了・エラー終了のいずれにしても実行
//---------------------------------------
if (is_resource($fp_r) === true) {
echo "読み込みファイルロック解除 {$read_file}" . PHP_EOL;
flock($fp_r, LOCK_UN); //ロック解除
echo "読み込みファイルクローズ {$read_file}" . PHP_EOL;
fclose($fp_r);
}
}
関連するファイルシステム関数
ファイル入出力関数の特徴まとめ
関数 | 利用シーン | 機能 | 処理単位 | ハンドル の管理 | ロック | 速度 | メモリ節約 | 安全性 | エラー時 |
fgetc | 1文字ずつ処理する | 読み | 1文字ずつ | 別途 | 別途 | × | ○ | △自前 | 終端でfalse |
fgets | 1行ずつ処理する | 読み | 1行ずつ | 別途 | 別途 | △ | ○ | △自前 | 終端かエラー でfalse |
fread | 固定バイトごとに 処理する | 読み | 指定バイト | 別途 | 別途 | ○一括 ×分割 | ×一括 ○分割 | △自前 | エラーでfalse |
fgetcsv | CSVファイルを 1行ずつ読み込む | 読み | 1行ずつ | 別途 | 別途 | × | ○ | △自前 | エラーで0かnull |
file | ロック不要のファイル を行ごとに高速処理 &同時アクセスが少ない | 読み | データ全部 | 不要 | ロックなし | ○ | × | × | エラーでfalseや E_WARNING |
file_get_contents | ロック不要のファイル の文字列全体を高速取得 &同時アクセスが少ない | 読み | データ全部 | 不要 | ロックなし | ○ | × | × | エラーでfalseや E_WARNING |
fwrite fputs | ハンドル利用時の 書込処理全般 | 書き | 指定バイト | 別途 | 別途 | ○一括 ×分割 | ×一括 ○分割 | △自前 | エラーでfalse |
fputcsv | CSVを1行ずつ書込時 | 書き | 1行ずつ | 別途 | 別途 | × | ○ | △自前 | エラーでfalse |
file_put_contents | 1~数回だけ書込する時。 繰り返しは非常に遅い。 | 書き | データ全部 | 不要 | ロック指定可能 | ○一括 ×分割 | ×一括 ○分割 | △フラグ指定 | エラーでfalse |
コメント