三陸牡蠣復興支援プロジェクト「SAVE SANRIKU OYSTER」



ファイルシステム関数

関数一覧
chmod() /  clearstatcache() /  copy() /  fclose() /  feof() /  fgetc() /  fgetcsv() /  fgets() /  file() /  file_exists() /  file_get_contents() /  filemtime() /  filesize() /  flock() /  fopen() /  fpassthru() /  fputs() /  fread() /  fseek() /  ftell() /  ftruncate() /  fwrite() /  is_readable() /  is_writable() /  is_writeable() /  mkdir() /  readfile() /  rename() /  rewind() /  rmdir() /  set_file_buffer() /  stream_set_write_buffer() /  unlink()
機能一覧
ファイルをオープン・クローズする /  ファイルポインタの位置取得/移動 /  ファイルからの読み込み/ファイルへの書き込み・バッファ設定/出力/「EOF」か調べる /  ファイルを指定したサイズに丸める /  ファイルをロック・アンロックする /  ファイルからデータを全部読み込む・出力する /  ファイルの状態をチェックする/ファイル情報のキャッシュのクリア /  ファイルのリネーム(移動)/複製/削除/モード変更/ディレクトリの作成/削除 /  ファイルのモード(パーミッション)を変更する

ファイルをオープン・クローズする

掲示板等のスクリプトは、記事データをログファイル(記録用に用意したファイル)に保存し、データを読み込んだり書き込んだりするわけですが、ログファイルを扱う場合はそのファイルをまず「オープン」し、用が済んだら「クローズ」する必要があります。

ファイルポインタとは

ファイルをオープンすると、関数はファイルへのリファレンス(参照)、「ファイルポインタ」を返します。このファイルポインタは、オープンしたファイルの、処理対象となっている位置(何バイト目か)を指すものです。

fopen()関数
resource fopen(string ファイル, string モード[, bool インクルードパス使用])
指定した「ファイル」を指定した「モード(下表参照)」でオープンし、オープンしたファイルへのリファレンス(ファイルポインタ)を返します。失敗するとエラーになり、「FALSE」を返します。ファイル位置を含んだエラーメッセージを出力しないように「@(アットマーク)」(エラー制御演算子)を使用するのが一般的です。
「インクルードパス使用」に「TRUE」を指定すると、インクルードパス内のファイルも扱えるようになります。デフォルト値は「FALSE」です。

この関数に与える「モード」は以下のようになっています。

モード説明
'rb'【 読み込みモード 】 でオープン
'r+b'【 読み込み+上書モード 】 でオープン
書き込み処理は、そこにデータがある場合、上書します
'ab'【 追記モード 】 でオープンし
書き込み処理は、常にファイルの終端以降に追記していきます
ファイルが存在しない場合に作成を試みる
'a+b'【 追記+読み込みモード 】 でオープン
書き込み処理は、常にファイルの終端以降に追記していきます
ファイルが存在しない場合に作成を試みる
'wb'【 再書き込みモード 】 でオープン
ファイルが存在する場合は中身をクリアし、存在しない場合は作成を試みる
'w+b'【 再書き込み+読み込みモード 】 でオープン
ファイルが存在する場合は中身をクリアし、存在しない場合は作成を試みる
'xb'【 新規作成・書き込みモード 】 でオープン
ファイルが既に存在する場合にエラーとなり、存在しない場合に作成を試みる
'x+b'【 新規作成・書き込み+読み込みモード 】 でオープン
ファイルが既に存在する場合にエラーとなり、存在しない場合に作成を試みる

表に記述した「モード」を表す文字列はいずれも最後が「'b'」になっていますが、本来「'b'」は付いていません。が、最後に「'b'」を付加する事が推奨されているのでここではこのように記述しました。その理由については本家のマニュアルを参照下さい。

何れのモードも、オープン時のファイルポインタの位置は先頭(「0」)です。

注: 空ではないファイルを「追記+読み込みモード」でオープンし、書き込み処理をした場合、「fpassthru()」関数を実行しても何も得られない事から、ファイルポインタは終端にあると考えられるのですが、「ftell()」関数を実行してみると、何故か“書き込み開始位置に、書き込んだ文字列のバイト数を加算した値”を返し、更に「feof()」関数は「FALSE」を返します。このことから、ファイルポインタは終端には無いという事が判るのですが、意味が解かりません(爆)。書き込み処理後の「ftell()」関数が示すファイルポインタから何かを得たい場合は、書き込み処理をした後に「fseek($fp, 0, SEEK_CUR);」を実行(ここでファイルポインタは移動していません)すると、ちゃんと読み込まれるようになります。これってバグなんでしょうか?別にどうでもいい所なんですけど、謎です。

fclose()関数
bool fclose(resource ファイルポインタ)
「ファイルポインタ」は、「fopen()」関数でオープンしたファイルへのリファレンス(ファイルポインタ)を格納した変数です。「ファイルポインタ」が指すファイルをクローズします。
クローズに成功したか否かを真偽値(TRUEFALSE)で返します。

以下にサンプル。

<?php
    $filename = "./hode.log";
    $fp = @fopen($filename, 'rb');
    
    #試しに出力してみる
    echo $fp, "<hr />";
    var_dump($fp);
    
    fclose($fp);
    
    /*出力結果
    Resource id #2
    ----------------------------------
    resource(2) of type (stream) 
    */
?>

PageTop


ファイルポインタの位置取得/移動

fopen()」関数でオープンしたファイルの読み込み/書き込み処理は、「ファイルポインタ」が指す位置(何バイト目か)から処理をしていきます。処理するごとに処理終了位置までファイルポインタは移動していきます。また関数で移動出来ます。

ftell()関数
mixed ftell(resource ファイルポインタ)
「ファイルポインタ」が指す位置(何バイト目か)を返します。エラーが発生した場合は「FALSE」を返します。
rewind()関数
bool rewind(resource ファイルポインタ)
「ファイルポインタ」を先頭に移動します。成功したか否かを真偽値(TRUEFALSE)で返します。
返り値が違う以外、「fseek(ファイルポインタ, 0);」と同じです。
fseek()関数
int fseek(resource ファイルポインタ, int オフセット[, int 開始位置])
「ファイルポインタ」を「開始位置」から「オフセット」バイト目に移動します。
「開始位置」には、次の3つの定数が指定出来ます。

SEEK_SET」(ファイルの先頭から)、
SEEK_CUR」(現在位置から)、
SEEK_END」(ファイルの終端から)

デフォルト値は「SEEK_SET」です。
成功したか否かは整数値(0-1)で返します。

以下にサンプル。

abcdefghijklmnopqrstuvwxyz
ほでなすPHPをよろしくね。

↑「hode.log」という名前のログファイル

<?php
    $filename = "./hode.log";
    
    echo "<p>&gt;ファイルサイズ : ", 
                  filesize($filename), " バイト</p>";
    
    $fp = @fopen($filename, 'rb');
    
    echo "<p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    fseek($fp, 0, SEEK_END);
    echo "<p>FPをEOFへ移動しました。</p>", 
         "<p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    fseek($fp, 12);
    echo "<p>FPを先頭から12バイト目へ移動しました。</p>", 
         "<p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    fseek($fp, 14, SEEK_CUR);
    echo "<p>FPを現在位置から14バイト目へ移動しました。</p>", 
         "<p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    rewind($fp);
    echo "<p>FPを先頭へ移動しました。</p>", 
         "<p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    fclose($fp);
    
    /*出力結果(FP:ファイルポインタ)
    >ファイルサイズ : 55 バイト
    
    >FP位置 : 0 バイト目
    
    FPをEOFへ移動しました。
    
    >FP位置 : 55 バイト目
    
    FPを先頭から12バイト目へ移動しました。
    
    >FP位置 : 12 バイト目
    
    FPを現在位置から14バイト目へ移動しました。
    
    >FP位置 : 26 バイト目
    
    FPを先頭へ移動しました。
    
    >FP位置 : 0 バイト目
    */
?>

PageTop


ファイルからの読み込み/ファイルへの書き込み・バッファ設定/出力/「EOF」か調べる

以下の関数は、「fopen()」関数で得た「ファイルポインタ」を使用して、オープンしたファイルから文字列を読み込んだり書き込んだりします。

処理を終えると、終えた位置までファイルポインタが移動します。

「EOF」について

EOF」は「End Of File」の頭文字をとったもので、そのまんま「ファイルの終端」という意味です。読み込んだり書き込んだりなんかして、ファイルポインタがファイルの終端に達した時、PHPは「ここが“EOF”であります」と認識するんです。多分。よく解かりません。

fread()関数
string fread(resource ファイルポインタ, int 長さ)
「ファイルポインタ」から、最大「長さ」バイト読み込み、それを返します。
「長さ」バイト読み込んだか、「EOF」に達した時点で読み込みを終えます。
fwrite()関数
mixed fwrite(resource ファイルポインタ, string 文字列[, int 長さ])
「ファイルポインタ」が指す位置に「文字列」を書き込み、書き込んだバイト数を返します。エラー時には「FALSE」を返します。
「長さ」を指定した場合、書き込む長さは最大「長さ」バイトに制限されます。
fputs()関数
mixed fputs(resource ファイルポインタ, string 文字列[, int 長さ])
fwrite()」関数のエイリアス(別名)で、全く同じものです。
stream_set_write_buffer()関数
int stream_set_write_buffer(resource ファイルポインタ, int バッファサイズ)
「ファイルポインタ」が指すファイルへの「fwrite()」関数による書き込み処理が2つあった場合、書き込む内容を指定した「バッファサイズ」バイト分書き込む毎に停止して他方に書き込み処理が移ります(?)。成功したか否かを「0EOF」で返します。
「バッファサイズ」に「0」を設定するとバッファはせず、全部書き込んでから他方の書き込み処理が行われます。
この関数をコールしなかった場合、「バッファサイズ」の値は「8192」に設定されます。
set_file_buffer()関数
int set_file_buffer(resource ファイルポインタ, int バッファサイズ)
stream_set_write_buffer()」関数のエイリアス(別名)で、全く同じものです。
fgets()関数
mixed fgets(resource ファイルポインタ[, int 長さ])
「ファイルポインタ」から最大「長さ−1」バイト数分読み込み、それを返します。エラー時には「FALSE」を返します。
この関数は、「長さ−1」バイト数分読み込んだか、改行文字を検出したか、「EOF」に達した時点で読み込みを終えます。つまり最大1行分しか読み込みません。
「長さ」のデフォルト値は「1024」です。
fgetc()関数
mixed fgetc(resource ファイルポインタ)
「ファイルポインタ」から1バイト読み込み、それを返します。「EOF」に達した場合に「FALSE」を返します。
1バイトずつ読み込むので、マルチバイト文字列を含む場合はそのまま使うと文字列が壊れてしまうので注意。
fgetcsv()関数
mixed fgetcsv(resource ファイルポインタ, int 長さ[, string デリミタ[, string 囲い子]])
この関数は「fgets()」関数と同じ様に動作しますが、読み込んだ行を「CSV(コンマ区切り)」として読み込み、指定した「デリミタ(デフォルト値は「,(コンマ)」)」で区切られた値を要素とする配列を生成し返します。
所得した一つ一つのデータの左右にあるホワイトスペース(タブや半角スペース、改行文字の事)は自動的にカットされます(バージョン(新しい方の)によっては改行のみカット)。
「囲い子(デフォルト値は「"(ダブルクォーテーション)」)」を指定した場合は、「囲い子」で括られた部分は「デリミタ」は関係なく、左右のホワイトスペースもカットされることなく、一つの要素となります。
「デリミタ」と「囲い子」に指定できるのは単一文字のみです。
「\(円マーク)」の後にある「囲い子」は(エスケープされて?)無効になります。
空行の場合は、NULL」1つを要素とする配列を生成します。単に「FALSE」を返します。
fpassthru()関数
mixed fpassthru(resource ファイルポインタ)
「ファイルポインタ」以降、「EOF」まで全てを読み込んで出力し、読み込んだ文字数を返します。読み込んだバイト数を返します。エラー時には「FALSE」を返します。
この関数は自動的にファイルをクローズします。よってこの関数をコールした時点で関数に与えたファイルポインタは無効になります。
※.取り消し線が引いてある所は、マニュアルに記載してある内容です。当方の環境での結果と異なっているので、確認した結果を記述しています。バージョンの違い?
feof()関数
bool feof(resource ファイルポインタ)
ファイルポインタが「EOF」(ファイルの終端)に達しているかどうかを調べ、「EOF」に達しているかエラーの場合に「TRUE」を、その他の場合に「FALSE」を返します。
注:fwrite()」関数等により移動した場合は「EOF」を検出しますが、「fseek()」関数でファイルポインタをファイルの終端まで移動させても、「EOF」は検出されません。

以下にサンプル。

abcdefghijklmnopqrstuvwxyz
ほでなすPHPをよろしくね。

↑「hode.log」という名前のログファイル

<?php
    $filename = "./hode.log";
    
    echo "<p>&gt;ファイルサイズ : ", 
                  filesize($filename), " バイト</p>";
    
    $fp = @fopen($filename, 'r+b');
    
    echo "<p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    $str = fread($fp, 15);
    echo "<p>15バイト分読み込みました。<br />&gt;{$str}</p>", 
         "<p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    $str = fread($fp, 15);
    echo "<p>15バイト分読み込みました。<br />&gt;{$str}</p>", 
         "<p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    $str = fread($fp, 300);
    echo "<p>300バイト分読み込みました。<br />&gt;{$str}</p>", 
         "<p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    if(feof($fp))
        echo "<p>「EOF」に達しました。</p>";
    
    stream_set_write_buffer($fp, 0);
    
    fwrite($fp, "夏は暑いねぇ。", 2);
    echo "<p>「夏は暑いねぇ。」を2バイト分だけ書き込みました。</p>";
    
    rewind($fp);
    echo "<p>FPを先頭へ移動しました。</p>", 
         "<p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    echo "<p>1文字ずつ読み込みます(いい加減です)。</p><p>";
    $flg = true;
    while(!is_bool($str = fgetc($fp))){
        if(!mb_eregi("^[a-zA-Z0-9]{1}$", $str) && $flg){
            $pre_str = $str;
            $flg = !$flg;
            continue;
        }
        echo "&gt;", $pre_str.$str, "<br />";
    	$pre_str = "";
    	$flg = true;
    }
    echo "</p><p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    fclose($fp);
    
    /*出力結果(FP:ファイルポインタ)
    >ファイルサイズ : 55 バイト
    
    >FP位置 : 0 バイト目
    
    15バイト分読み込みました。
    >abcdefghijklmno
    
    >FP位置 : 15 バイト目
    
    15バイト分読み込みました。
    >pqrstuvwxyz ほ
    
    >FP位置 : 30 バイト目
    
    300バイト分読み込みました。
    >でなすPHPをよろしくね。 
    
    >FP位置 : 55 バイト目
    
    「EOF」に達しました。
    
    「夏は暑いねぇ。」を2バイト分だけ書き込みました。
    
    FPを先頭へ移動しました。
    
    >FP位置 : 0 バイト目
    
    1文字ずつ読み込みます。
    
    >a
    >b
    …
    >y
    >z
    > 
    >ほ
    >で
    >な
    >す
    >P
    >H
    >P
    >を
    >よ
    >ろ
    >し
    >く
    >ね
    >。
    > 
    >夏
    
    >FP位置 : 57 バイト目
    */
?>

以下にサンプルパート2。

<?php
    $filename = "./hode.log";
    
    echo "<p>&gt;ファイルサイズ : ", 
                  filesize($filename), " バイト</p>";
    
    $fp = @fopen($filename, 'r+b');
    
    echo "<p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    while($str = fgets($fp, 16)){
    	echo "<p>最大16-1バイトずつ読み込みます。<br />", 
             "&gt;", $str, "<br />", 
             "&gt;バイト数 : ", mb_strwidth($str), "<br />", 
             "&gt;文字数 : ", mb_strlen($str), "</p>";
    }
    
    echo "<p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    fseek($fp, -14, SEEK_CUR);
    echo "<p>FPを現在位置から-14バイト目へ移動しました。</p>", 
         "<p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    echo "&gt;";
    $str_len = fpassthru($fp);
    echo "<p>残り{$str_len}バイト分全部出力しました。</p>", 
         "<p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    fclose($fp);
    
    /*出力結果(FP:ファイルポインタ)
    >ファイルサイズ : 55 バイト
    
    >FP位置 : 0 バイト目
    
    最大16-1バイトずつ読み込みます。
    >abcdefghijklmno
    >バイト数 : 15
    >文字数 : 15
    
    最大16-1バイトずつ読み込みます。
    >pqrstuvwxyz 
    >バイト数 : 11
    >文字数 : 13
    
    最大16-1バイトずつ読み込みます。
    >ほでなすPHPをよ
    >バイト数 : 15
    >文字数 : 9
    
    最大16-1バイトずつ読み込みます。
    >ろしくね。 
    >バイト数 : 10
    >文字数 : 7
    
    >FP位置 : 55 バイト目
    
    FPを現在位置から-14バイト目へ移動しました。
    
    >FP位置 : 41 バイト目
    
    >よろしくね。 
    残り14バイト分全部出力しました。
    
    >FP位置 : 55 バイト目
    */
?>

以下にサンプルパート3。

<?php
    $filename = "./hode.log";
    
    echo "<p>&gt;ファイルサイズ : ", 
                  $where = filesize($filename), " バイト</p>";
    
    $fp = @fopen($filename, 'rb');
    
    echo "<p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    fseek($fp, $where); //「EOF」に到達したはず
    
    echo "<p>&gt;FP位置 : ", ftell($fp), " バイト目</p>";
    
    if(feof($fp))
        die("<p>「EOF」に達しました。</p>");
    else
        die("<p>「EOF」に達していません。</p>");
    
    /*出力結果(FP:ファイルポインタ)
    >ファイルサイズ : 55 バイト
    >FP位置 : 0 バイト目
    >FP位置 : 55 バイト目
    「EOF」に達していません。
    */
?>

以下にサンプルパート4。

テスト。
犬, \"ワン\",   骨, "犬太郎, 犬次郎, 犬衛門"
猫, \"ニャァ\", 魚, "猫助, 猫ひろし"
牛, \"モー\",   草, "ヤスヒロ(以前頂いた牛の名前)"

↑「hode.log」という名前のログファイル

<?php
    $filename = "./hode.log";
    
    $fp = @fopen($filename, 'rb');
    
    while($arr = fgetcsv($fp, 1024))
        print_r($arr);
    
    fclose($fp);
    
    /*出力結果
    Array
    (
        [0] => テスト。
    )
    Array
    (
        [0] => 犬
        [1] => \"ワン\"
        [2] => 骨
        [3] => 犬太郎, 犬次郎, 犬衛門
    )
    Array
    (
        [0] => 猫
        [1] => \"ニャァ\"
        [2] => 魚
        [3] => 猫助, 猫ひろし
    )
    Array
    (
        [0] => 牛
        [1] => \"モー\"
        [2] => 草
        [3] => ヤスヒロ(以前頂いた牛の名前)
    )
    */
?>

PageTop


ファイルを指定したサイズに丸める

ftruncate()関数
bool ftruncate(resource ファイルポインタ, int サイズ)
「ファイルポインタ」が指すファイルを「サイズ」バイトに丸めます。成功したか否かを真偽値(TRUEFALSE)で返します。

以下にサンプル。

abcdefghijklmnopqrstuvwxyz
ほでなすPHPをよろしくね。

↑「hode.log」という名前のログファイル

<?php
    $filename = "./hode.log";
    
    echo "<p>&gt;ファイルサイズ : ", 
                  filesize($filename), " バイト</p>";
    
    $fp = @fopen($filename, 'rb');
    
    if(ftruncate($fp, 5))
        echo "<p>ファイルサイズを5バイトに丸めました。</p>";
    else
        echo "<p>失敗しました。</p>";
    
    clearstatcache();
    
    echo "<p>&gt;ファイルサイズ : ", 
                  filesize($filename), " バイト</p>";
    
    fclose($fp);
    
    echo "<hr />";
    
    $fp = @fopen($filename, 'r+b');
    
    if(ftruncate($fp, 5))
        echo "<p>ファイルサイズを5バイトに丸めました。</p>";
    else
        echo "<p>失敗しました。</p>";
    
    clearstatcache();
    
    echo "<p>&gt;ファイルサイズ : ", 
                  filesize($filename), " バイト</p>";
    
    fclose($fp);
    
    /*出力結果
    >ファイルサイズ : 53 バイト
    失敗しました。
    >ファイルサイズ : 53 バイト
    -------------------------------------------------
    ファイルサイズを5バイトに丸めました。
    >ファイルサイズ : 5 バイト
    */
?>

PageTop


ファイルをロック・アンロックする

掲示板の様なスクリプトは、ログファイルを用意しそれにデータを書き込んだり読み込んだりしますが、ログファイルは1つしかないので、同時に複数の要求があった場合に、書き込んでいる最中に他の書き込み処理が割り込んでしまえばファイルの内容は予期しない状態に壊れてしまうし、書き込み処理中に読み込もうとすれば、適切に読み込めません。

この問題を回避するために、オープンしたファイルを「ロック」し、操作しようとしているファイルがロックしている間ブロック(待機させる)し、「アンロック」されてから操作するようにします。

flock()関数
bool flock(resource ファイルポインタ, int モード)
「ファイルポインタ」が指すファイルを指定した「モード」でロックし、成功したか否かを真偽値(TRUEFALSE)で返します。
この関数でロックされたファイルは、アクセス出来なくなるわけではなく、単に「ロックしてますから」とこの関数に対して知らせるだけです。よって、例えば別のスクリプトで同じファイルをオープンし、この関数を使用しなかった場合、読み書き操作することが出来ます。
Windowsでは機能しません。

この関数に与える「モード」は以下のようになっています。

モード説明
LOCK_SH【 共有ロック(読み手) 】
同じモードでのロックはブロックしません
LOCK_EX【 排他的ロック(書き手) 】
アンロックされるまで排他的にブロックします
LOCK_NB【 ノンブロック 】
LOCK_SH | LOCK_NB」や「LOCK_EX | LOCK_NB」のように指定する
ロック中の時はブロックを行わずに「FALSE」を返す
LOCK_UN【 アンロック 】
ロックを開放します

通常、ロック中にロックしようとすると「ブロック(開放されるまでそこで待機)」されますが、「LOCK_SH | LOCK_NB」や「LOCK_EX | LOCK_NB」のように指定すると、ロック中でもブロックせずに、ただ「FALSE」を返してスルーします。

アンロックしなくても、クローズするなりすれば、自動的にロックは開放されます。

以下にサンプル。

<?php
    $filename = "./hode.log";
    
    $fp1 = @fopen($filename, 'r+b');
    $fp2 = @fopen($filename, 'r+b');
    $fp3 = @fopen($filename, 'r+b');
    
    if(flock($fp1, LOCK_SH))
        echo "fp1 ロックに成功しました。<br />";
    else
        echo "fp1 ロックに失敗しました。<br />";
    
    if(flock($fp2, LOCK_SH | LOCK_NB))
        echo "fp2 ロックに成功しました。<br />";
    else
        echo "fp2 ロックに失敗しました。<br />";
    
    if(flock($fp3, LOCK_EX | LOCK_NB))
        echo "fp3 ロックに成功しました。<br />";
    else
        echo "fp3 ロックに失敗しました。<br />";
    
    fclose($fp1);
    fclose($fp2);
    fclose($fp3);
    
    echo "<hr />";
    
    $fp1 = @fopen($filename, 'r+b');
    $fp2 = @fopen($filename, 'r+b');
    $fp3 = @fopen($filename, 'r+b');
    
    if(flock($fp1, LOCK_EX))
        echo "fp1 ロックに成功しました。<br />";
    else
        echo "fp1 ロックに失敗しました。<br />";
    
    if(flock($fp2, LOCK_SH | LOCK_NB))
        echo "fp2 ロックに成功しました。<br />";
    else
        echo "fp2 ロックに失敗しました。<br />";
    
    if(flock($fp3, LOCK_EX | LOCK_NB))
        echo "fp3 ロックに成功しました。<br />";
    else
        echo "fp3 ロックに失敗しました。<br />";
    
    fclose($fp1);
    fclose($fp2);
    fclose($fp3);
    
    /*出力結果
    fp1 ロックに成功しました。
    fp2 ロックに成功しました。
    fp3 ロックに失敗しました。
    -------------------------------------------------
    fp1 ロックに成功しました。
    fp2 ロックに失敗しました。
    fp3 ロックに失敗しました。
    */
?>

PageTop


ファイルからデータを全部読み込む・出力する

file()関数
array file(string ファイル[, bool インクルードパス使用])
指定した「ファイル」の内容を全て読み込み、各行(改行文字も含みます)を各要素にセットした配列を返します。失敗するとエラーになり、「FALSE」を返します。ファイル位置を含んだエラーメッセージを出力しないように「@(アットマーク)」(エラー制御演算子)を使用するのが一般的です。
「インクルードパス使用」に「TRUE」を指定すると、インクルードパス内のファイルも扱えるようになります。デフォルト値は「FALSE」です。
file_get_contents()関数
string file_get_contents(string ファイル[, bool インクルードパス使用])
指定した「ファイル」の内容を全て読み込み、そのまま文字列として返します。失敗するとエラーになり、「FALSE」を返します。ファイル位置を含んだエラーメッセージを出力しないように「@(アットマーク)」(エラー制御演算子)を使用するのが一般的です。
「インクルードパス使用」に「TRUE」を指定すると、インクルードパス内のファイルも扱えるようになります。デフォルト値は「FALSE」です。
readfile()関数
int readfile(string ファイル[, bool インクルードパス使用])
指定した「ファイル」の内容を全て読み込み、そのまま出力し、読み込んだバイト数を返します。失敗するとエラーになり、「FALSE」を返します。ファイル位置を含んだエラーメッセージを出力しないように「@(アットマーク)」(エラー制御演算子)を使用するのが一般的です。
「インクルードパス使用」に「TRUE」を指定すると、インクルードパス内のファイルも扱えるようになります。デフォルト値は「FALSE」です。

以下にサンプル。

abcdefghijklmnopqrstuvwxyz
ほでなすPHPをよろしくね。

↑「hode.log」という名前のログファイル

<?php
    $filename = "./hode.log";
    
    $str1 = "";
    
    foreach((array)@file($filename) as $line)
        $str1 .= $line;
    
    $str2 = @file_get_contents($filename);
    
    echo $str1, "<hr />", 
         $str2, "<hr />", 
         "[".@readfile($filename)."]";
    
    /*出力結果
    abcdefghijklmnopqrstuvwxyz ほでなすPHPをよろしくね。
    -----------------------------------------------------------
    abcdefghijklmnopqrstuvwxyz ほでなすPHPをよろしくね。
    -----------------------------------------------------------
    abcdefghijklmnopqrstuvwxyz ほでなすPHPをよろしくね。 [55]
    */
?>

PageTop


ファイルの状態をチェックする/ファイル情報のキャッシュのクリア

ファイルを読み込んだり、書き込み処理等、何だりかんだりする場合、当の処理対象であるファイル(もしくはディレクトリ)が存在していなかったり、指定した処理が許可されていなかったりすると、エラーを発して果ててしまいます。そんな自体に備えて、ファイルが書き込み可能であるか、それ以前にファイルが存在するのか等の確認を、処理前にチェックします。

file_exists()関数
bool file_exists(string ファイル・ディレクトリ)
指定した「ファイル・ディレクトリ」が存在するか否かを真偽値(TRUEFALSE)で返します。
is_readable()関数
bool is_readable(string ファイル・ディレクトリ)
指定した「ファイル・ディレクトリ」が存在し、かつ読み込み可能であるか否かを真偽値(TRUEFALSE)で返します。
is_writable()関数
bool is_writable(string ファイル・ディレクトリ)
指定した「ファイル・ディレクトリ」が存在し、かつ書き込み可能であるか否かを真偽値(TRUEFALSE)で返します。
is_writeable()関数
bool is_writeable(string ファイル・ディレクトリ)
is_writable()」関数のエイリアス(別名)で、全く同じものです。
filesize()関数
mixed filesize(string ファイル・ディレクトリ)
指定した「ファイル・ディレクトリ」のサイズを返します(ディレクトリを指定した場合は常に「0」を返します)。エラーが発生した場合は「FALSE」を返します。
存在しないファイル・ディレクトリを指定すると「E_WARNING」警告を発し、失敗します。
filemtime()関数
mixed filemtime(string ファイル・ディレクトリ)
指定した「ファイル・ディレクトリ」の最終更新時のUNIXタイムスタンプを返します。エラーが発生した場合は「FALSE」を返します。
存在しないファイル・ディレクトリを指定すると「E_WARNING」警告を発し、失敗します。

ファイルに関する情報はキャッシュされます

filesize()」関数等の、ファイルに関する情報を取得する関数は、1回目の戻り値をキャッシュし、2回目以降は1回目にコールされた時の値を使用します。

これでは、1回目のコールと2回目以降のコールの間にファイルの情報が変化した場合、正確な値を得る事が出来ないので、そんな時はキャッシュをクリアします。

clearstatcache()関数
void clearstatcache(void)
キャッシュされたファイルに関する情報をクリアします。

以下にサンプル。

abcdefghijklmnopqrstuvwxyz
ほでなすPHPをよろしくね。

↑「hode.log」という名前のログファイル

<?php
    $filename = "./hode.log";
    
    if(!file_exists($filename))
        die("<p> - 指定されたファイルが存在しません。 - </p>");
    
    echo "<p>&gt;処理前のファイルサイズ : ", 
                  filesize($filename), " バイト</p>";
    
    if(is_writable($filename)){
        $fp = @fopen($filename, 'r+b');
        ftruncate($fp, 5);
        fclose($fp);
    }else
        die("<p> - 書き込み権限がありません。 - </p>");
    
    echo "<p>&gt;処理後のサイズ(キャッシュクリア前) : ", 
                  filesize($filename), " バイト</p>";
    
    clearstatcache();
    
    echo "<p>&gt;処理後のサイズ(キャッシュクリア後) : ", 
                  filesize($filename), " バイト</p>";
    
    echo "<hr />最終更新日時 : ", 
                  date("Y/m/d H:i", filemtime($filename));
    
    /*出力結果
    >処理前のファイルサイズ : 55 バイト
    >処理後のサイズ(キャッシュクリア前) : 55 バイト
    >処理後のサイズ(キャッシュクリア後) : 5 バイト
    --------------------------------------------------------
    最終更新日時 : 2004/08/10 17:05
    */
?>

PageTop


ファイルのリネーム(移動)/複製/削除/ディレクトリの作成/削除

rename()関数
bool rename(string ファイル・ディレクトリ, string リネーム後ファイル・ディレクトリ)
「ファイル・ディレクトリ」を「リネーム後ファイル・ディレクトリ」にリネームします。成功したか否かを真偽値(TRUEFALSE)で返します。
存在しないファイル・ディレクトリを指定したり、既に存在するファイル名にリネームしようとすると「E_WARNING」警告を発し、失敗します。
copy()関数
bool copy(string ファイル, string 複製後ファイル)
「ファイル」を「複製後ファイル」として複製します。成功したか否かを真偽値(TRUEFALSE)で返します。
「複製後ファイル」が既に存在する場合は、上書されます。
存在しないファイルやディレクトリを指定すると「E_WARNING」警告を発し、失敗します。
unlink()関数
bool unlink(string ファイル)
「ファイル」を削除します。成功したか否かを真偽値(TRUEFALSE)で返します。
存在しないファイルや、ディレクトリを指定すると「E_WARNING」警告を発し、失敗します。
ディレクトリを削除する場合は「rmdir()」関数を使用します。
mkdir()関数
bool mkdir(string ディレクトリ[, int モード])
「ディレクトリ」を作成し、パーミッションを「モード」に設定します。成功したか否かを真偽値(TRUEFALSE)で返します。
「ディレクトリ」が既に存在する場合は「E_WARNING」警告を発し、失敗します。
「モード」には8進数でパーミッションの値を指定します。「モード」のデフォルト値は「0777」です。
rmdir()関数
bool rmdir(string ディレクトリ)
「ディレクトリ」を削除します。成功したか否かを真偽値(TRUEFALSE)で返します。
「ディレクトリ」は空でなくてはなりません。
空のディレクトリ以外のものを指定すると「E_WARNING」警告を発し、失敗します。
ファイルを削除する場合は「unlink()」関数を使用します。

以下にサンプル。

<?php
    /*
    「/html/public_html/hode/hode.log」というファイルがあると想定
    */
    
    $dirname1 = "/html/public_html/hode/";
    $dirname2 = "/html/public_html/nasu/";
    
    $filename = "hode.log";
    
    #元のファイルを「hode.log.bak」として複製
    copy($dirname1.$filename, $dirname1.$filename.".bak");
    
    #新ディレクトリ作成
    mkdir($dirname2, 0701);
    
    #元のファイルを新ディレクトリに移動
    rename($dirname1.$filename, $dirname2.$filename);
    
    #複製したファイルを削除
    unlink($dirname1.$filename.".bak");
    
    #元のディレクトリを削除
    rmdir($dirname1);
    
    /*
    「/html/public_html/nasu/hode.log」が残る
    */
?>

PageTop


ファイルのモード(パーミッション)を変更する

chmod()関数
bool chmod(string ファイル, int モード)
「ファイル」のパーミッション(アクセス権)を「モード」に設定します。成功したか否かを真偽値(TRUEFALSE)で返します。

以下にサンプル。

<?php
    $filename = "./hode.log";
    
    chmod($filename, 0606);
?>

PageTop


作成日:2004年08月03日 最終更新日:2004年08月10日
【印刷モード風モード で表示】