目次
PHPテキストファイルの保存と読込み(下書)
PHPでは同一サーバー上にあるテキストファイルを読み込みしたり書き出しする事ができます。
- fopen・・・ファイルを開く
- fclose・・・開いたファイルを閉じる
- fget・・・行単位で読み込む
- file_get_contents・・・ファイル全体を読み込む
- fwrite・・・ファイルハンドルを使って書き出す
- file_put_contents・・・ファイル全体に書き出す
fopenとfclose
ファイルの読み書きを行うには、どのファイルにどの方法でアクセスするのかfopen関数で指定する必要があり、処理が終わったらfclose関数で解放が必要です。
ハンドル=fopen(ファイル名,モード); fclose(ハンドル);
開いて閉じるだけのプログラム例
$fh=fopen('sample.txt','r+'); //ここに読み書きする処理が入る fclose($fh);
モード説明
| r | 読み込み専用、ファイルポインタを先頭にセット |
|---|---|
| r+ | 読み込み/書き込み、他はrと同じ |
| w | 新規書き込み専用、既存ファイルがある場合はファイルサイズを0にします、無い場合は作成します |
| w+ | 新規読み込み/書き込み、他はwと判事 |
| a | 書き込み専用、ファイルポインタを終端にセット、ファイルが無い場合は作成します |
| a+ | 読み込み/書き込み、他はaと同じ |
| x | 書き込み専用、ファイルが存在する場合はエラー、ファイルポインタは先頭にセット |
| x+ | 読み込み/書き込み、他はxと同じ |
| c | 書き込み専用、ファイルポインタを先頭にセット、無い場合は作成します、v5.2.6から追加 |
| c+ | 読み込み/書き込み、他はcと同じ、v5.2.6から追加 |
オプションフラグ(モードと合わせて使用)
| b | バイナリモードで開く |
|---|---|
| t | Windowsでテキストモードで開く時にテキストの改行コードをOSに合わせて自動変換します(\n→\r\n) |
fget
1行ごと読み込むにはfget関数を使います。行末に改行がある場合は改行も含むので注意が必要です。(改行コードを除去したい場合は追加でrtrim()関数などをつかうと良いです)
echo '<p>'; $fh=fopen('sample.txt','r'); //書き込みする場合は'r+'に while(!feof($fh)){ $str=fgets($fh); echo $str.'<br>'; } fclose($fh); echo '</p>';
少しでも短くしたい場合は下記でもOK
while ($str=fgets($fh)){ echo $str.'<br>' }
file_get_contents
全文を読み込み。
$str=file_get_contents('sample.txt'); echo $str.'<br>';
fwrite
ファイルハンドルを使って書き出す
上書きモード
$str='書き込む内容'; $fh=fopen('sample.txt', 'w'); fwrite($fh,$str); fclose($fh);
追記モード
$str='書き込む内容'; $fh=fopen('sample.txt', 'a'); fwrite($fh,$str); fclose($fh);
file_put_contents
全文書き出す。
上書きモード
$str='書き込む内容'; file_put_contents('sample.txt',$str);
追記モード
$str='書き込む内容'; file_put_contents('sample.txt',$str,FILE_APPEND);
ファイルかディレクトリか判定
対象がファイルかディレクトリかわからない場合は is_file 関数で調べてからオープンします。(これ以外にfile_existsとis_dirの組み合わせでも可能です)
$fileNmae='log'; if(is_file($fileName)){ $fh=fopen($fileName,'r+'); //処理 fclose($fh); }else{ echo '通常ファイルではありません'; }
ロック
//ファイルが無いときは作成する(存在しないとロックできない) if ( $fp = @fopen ( ファイル名 , "x" ) ) { fclose ( $fp ); } $fh=fopen(ファイル名 , "r+"); if (flock($fh, LOCK_EX)){ //ロック中か確認しロック中なら待機、未ロックならロックして処理aへ //処理a flock($fh, LOCK_UN); }else{ echo('<p>ロックできません</p>'); } fclose($fh);
多数のファイルを扱う場合は個別にロック→ロック解除すると時間がかかるのでロック確認用のファイルを1つだけロックして全部の処理が終わったらロックを解除するのが良い。ただし同ファイルにアクセスするすべてのプログラムで同じロック処理をしないと不具合が発生する可能性があります。
ロック中は他のプロセスが待ち状態になるので、できるだけロック時間が短くなるようにします。
ロック処理では同時にファイルに読み書きする事での不具合を回避できますが。書き込むデータの新旧の比較はしないので古いデータや別のデータで上書きが発生する可能性があります。
新ファイルのAさん、旧ファイルのBさんがほぼ同時にアップロード ↓ Aさんが少し早かったのでAさんロックでBさん待機 Aさん新ファイルのアップロード完了 ↓ Aさん終了・Bさん待機解除 Bさん旧ファイルのアップロード完了 ↓ サーバーには旧ファイルが残る。
?ロック専用ファイルでロックする時は、空にしてもOKなのでwが使える?「$fh=fopen(ファイル名 , “w”);」
