【PHP】これで分かる関数! – ファイル操作その1 –

PHP

更新履歴

更新日更新者更新内容
2021/8/23JJI・”はじめに”の段落を追加
・サンプルプログラムの実行結果に画面の画像を追加
・サンプルプログラムにファイルシステムの関数の使い方を追記

はじめに

サンプルプログラムの中で次の記事で載せている関数を使用している場合があります。

ファイルの基本操作

ファイルの各操作を紹介する前に基本操作として次の内容について説明します。

  1. ファイルを1行ずつ読み込んで表示し、ファイルをクローズする
  2. ファイルオープンのエラー処理
  3. ファイルを作成して書き込み、書き込んだファイルを読み込んで表示する

サンプルプログラム1

ファイルを1行ずつ読み込んで表示する処理の流れは次の通りです。

1.ファイルをオープンする
ファイルをオープンする場合、次のようにfopen()関数を使用します。
第1引数がオープンするファイル名、第2引数がファイルのモードです。
ファイルを読み込み専用で開くため、ファイルのモードは”r”を使用しています。
fopen()関数の戻り値はファイルポインタを呼ばれ、後の処理でこの戻り値を使用し、ファイルの読み込み、書き込みなどを行います。

 $fp = fopen(ファイル名, "r")

2.ファイルを1行ずつ表示する
ファイルを1行ずつ表示する場合、次のようにfgets()関数を使用し、ファイルのデータがなくなるまでループして表示する方法が一般的です。

while($line = fgets($fp)) {
    echo $line;
}

3.ファイルをクローズする
ファイルをクローズする場合、次のようにfclose()関数を使用します。

fclose($fp);

上記の1から3を使用したサンプルプログラムです。

<?php
    // 引数の値への厳密な型付け
    declare(strict_types = 1);
    // 共通ライブラリの読み込み
    require_once __DIR__ . "../../../lib/sample_common.php";

    echo "ファイル名:" . basename(__FILE__) . "<br>\n";
    echo "【PHP】ファイル基本操作<br>\n";

    echo "ファイルの読み込み<br>\n";

    // ファイルを読み取り専用でオープンする
    $fp = fopen("data/file1.txt", "r");

    $i = 1;
    // ファイルを1行ずつ読み込み、表示する
    while($line = fgets($fp)) {
        echo  "${i}行目:" . preg_replace("/\n/", "<br>\n", $line);

        $i++;
    }

    // ファイルのクローズ
    fclose($fp);
?>

実行結果です。

・画面

・HTML

ファイル名:sample02_08_01.php<br>
【PHP】ファイル基本操作<br>
ファイルの読み込み<br>
1行目:テストファイル
<br>
2行目:テスト文字列
<br>
3行目:テストテストテスト
<br>
4行目:
<br>
5行目:あああああ
<br>
6行目:いいいいい
<br>
7行目:ううううう
<br>
8行目:
<br>
9行目:えええええ
<br>
10行目:
<br>

使用したファイルの内容は次の通りです。

data/file1.txt

テストファイル
テスト文字列
テストテストテスト

あああああ
いいいいい
ううううう

えええええ

サンプルプログラム2

ファイルをオープンする場合、ファイルが存在しない、何らかの理由でファイルがオープンできないことがあるため、チェック処理、またはエラー処理が必要になります。
ファイルオープンをチェックする処理、またはエラー処理を行う方法として次のように5つの方法があります。
最もよく使用するのは、3のファイルオープン前にファイル存在有無をチェックする方法だと思います。

1.PHPからのエラー抑止なしでif文でファイルのオープン状態を判定する
次のコードのようにfopen()関数の戻り値を判定して処理を行います。
ただし、このコードの場合、PHPのエラーが表示されます。

$fp = fopen(ファイル名, "r");
if($fp == false) {
    // 何らかのエラー処理
}

2.PHPからのエラーを抑止し、if文でファイルのオープン状態を判定する
1と同じようなコードですが、 fopen()関数の前に@をつけてPHPのエラーを表示されないようにしています。

$fp = @fopen(ファイル名, "r");
if($fp == false) {
    // 何らかのエラー処理
}

3.ファイルのオープン前にファイルの存在有無を判定する
次のコードのようにfile_exists()関数を使用し、ファイルオープン前にファイルの存在有無をチェックします。

if(!file_exists(ファイル名)) {
    // 何らかのエラー処理
}

4.ファイルのオープンに失敗した場合、例外をスローする
次のコードのようにfopen()関数の戻り値を判定し、ファイルオープンに失敗した場合、例外をスローします。
自作で例外をスローしないといけないため、他の方法に比べてコードが長くなります。

try {
    $fp = @fopen(ファイル名, "r");
    if($fp == false) {
        // ファイルのオープンに失敗した場合、例外をスローする
        throw new Error("Failed to open file", 1001);
    }
} catch(Error $e) {
    // catch句で例外をキャッチし、何らかのエラー処理を行う
    echo $e->getLine() . ":" . $e->getCode() . ":" . $e->getMessage() . "<br>\n";
}

5.ファイルのオープンに失敗した場合、die()関数を使用する
PHPの本でよく紹介されている方法だと思います。
die()関数を使用した場合、そこで処理が終わるため、後の処理が必要かどうか考えて使わないと期待した動作にならないので、使用する際は注意が必要です。

$fp = @fopen(ファイル名, "r") or die("Error: Failed to open file");


上記の1~5を使用したサンプルプログラムです。

<?php
    // 引数の値への厳密な型付け
    declare(strict_types = 1);
    // 共通ライブラリの読み込み
    require_once __DIR__ . "../../../lib/sample_common.php";

    echo "ファイル名:" . basename(__FILE__) . "<br>\n";
    echo "【PHP】ファイル基本操作<br>\n";

    echo "ファイル読み込みのエラー処理<br>\n";

    $fp = null;

    echo "1.if文でエラー判定、PHPのメッセージ抑止なし<br>\n";
    $fp = fopen("data/dummy.txt", "r");
    if($fp == false) {
        echo "Error: Failed to open file<br>\n";
    }
    echo "<br>\n";

    echo "2.if文でエラー判定、PHPのメッセージ抑止あり<br>\n";
    $fp = @fopen("data/dummy.txt", "r");
    if($fp == false) {
        echo "Error: Failed to open file<br>\n";
    }
    echo "<br>\n";

    echo "3.file_exists()関数でファイルの存在チェック<br>\n";
    if(file_exists("data/dummy.txt")) {
        $fp = fopen("data/dummy.txt", "r");
    } else {
        echo "Error: Failed to open file<br>\n";
    }
    echo "<br>\n";

    echo "4.例外をthrowしてエラーのキャッチ、PHPのメッセージ抑止あり<br>\n";
    try {
        $fp = @fopen("data/dummy.txt", "r");
        if($fp == false) {
            throw new Error("Failed to open file", 1001);
        }
    } catch(Error $e) {
        echo $e->getLine() . ":" . $e->getCode() . ":" . $e->getMessage() . "<br>\n";
    } 
    echo "<br>\n";

    echo "5.die()関数でエラー処理、die関数の場合、スクリプトは終了する、PHPのメッセージ抑止あり<br>\n";
    $fp = @fopen("data/dummy.txt", "r") or die("Error: Failed to open file");

    echo "Succeeded in opening the file.<br>\n";
?>

実行結果です。

・画面

・HTML

ファイル名:sample02_08_02.php<br>
【PHP】ファイル基本操作<br>
ファイル読み込みのエラー処理<br>
1.if文でエラー判定、PHPのメッセージ抑止なし<br>
<br />
<b>Warning</b>:  fopen(data/dummy.txt): failed to open stream: No such file or directory in <b>C:\private\repo\app\php-git\php-sample\htdocs\sample2\sample2_8\sample02_08_02.php</b> on line <b>15</b><br />
Error: Failed to open file<br>
<br>
2.if文でエラー判定、PHPのメッセージ抑止あり<br>
Error: Failed to open file<br>
<br>
3.file_exists()関数でファイルの存在チェック<br>
Error: Failed to open file<br>
<br>
4.例外をthrowしてエラーのキャッチ、PHPのメッセージ抑止あり<br>
40:1001:Failed to open file<br>
<br>
5.die()関数でエラー処理、die関数の場合、スクリプトは終了する、PHPのメッセージ抑止あり<br>
Error: Failed to open file

サンプルプログラム3

新規作成のファイルに書き込む場合、ファイルのオープン後に次のようにfwrite()関数が使用します。

 fwrite($fp, "1行目、ハローワールド。\n");

新規作成のファイルに書き込み、書き込んだファイルを表示するプログラムです。
ファイルのオープン、クローズ、表示はサンプルプログラム1で紹介した方法を使用しています。

<?php
    // 引数の値への厳密な型付け
    declare(strict_types = 1);
    // 共通ライブラリの読み込み
    require_once __DIR__ . "../../../lib/sample_common.php";

    // デフォルトタイムゾーンの設定
    date_default_timezone_set("Asia/Tokyo");

    echo "ファイル名:" . basename(__FILE__) . "<br>\n";
    echo "【PHP】ファイル基本操作<br>\n";
    echo "ファイルの新規作成・読み込み<br>\n";

    // ファイル名をfile_yyyymmddhhmiss.txt(yyyymmddhhmiss:現在時刻)とする
    $filename = "data/write/file_"  . date_format(date_create(), "YmdHis") . ".txt";

    // ファイルを読み書き/書き込み、追記なしでオープンする
    // ファイルが存在しない場合、ファイルを新規作成する
    $fp = fopen($filename, "w+");

    // ファイルへの書き込みを行う
    fwrite($fp, "1行目、ハローワールド。\n");
    fwrite($fp, "second line hello world.\n");

    // ファイルのクローズ
    fclose($fp);

    // 新規作成したファイルの存在チェック
    if(file_exists($filename)) {
        echo $filename . "は存在します<br>\n";
    }

    // 書き込んだファイルを読み込み専用オープンする
    $fp = fopen($filename, "r");

    // ファイルを1行ずつ読み込み、表示する
    $i = 1;
    while($line = fgets($fp)) {
        echo  "${i}行目:" . preg_replace("/\n/", "<br>\n", $line);
        $i++;
    }

    // ファイルのクローズ
    fclose($fp);
?>

実行結果です。

・画面

・HTML

ファイル名:sample02_08_03.php<br>
【PHP】ファイル基本操作<br>
ファイルの新規作成・読み込み<br>
data/write/file_20210630211254.txtは存在します<br>
1行目:1行目、ハローワールド。<br>
2行目:second line hello world.<br>

コメント