24. テキストデータ読み込み

ファイル操作の関数

PHP には外部データを読み込む関数がいくつかあります。今回は fgets()fgetcsv() で、外部ファイルからデータ取得してみましょう。

関数名 用途
file_exists() ファイルが存在するかチェック
fopen() ファイルを開く
fgets() データを1行ずつ読み込み
fgetcsv() CSVデータを1行ずつ読み込み
flock() ファイルロック
fclose() ファイルを閉じる

file_exists()

file_exists() はファイルが存在するかチェックます。結果は true/false で返ってきます。

bool = file_exists(ファイルパス)

fopen()

fopen() はファイルパスを指定してファイル開くメソッドで、読み込みが成功すると resource(ファイルリソース)が返ります。失敗すると falseになります。

ファイルリソース = fopen(ファイルパス, オプション)
オプション

fopen() のオプションはいくつかあり、処理する用途によって使い分けましょう。

用途 オプション
読み込み専用 r
書き込み(上書き) w
書き込み(追記) a
書き込み(上書き)& 読み込み w+
書き込み(追記)& 読み込み a+

flock()

ファイルが他の処理で割り込みされないように flock() が用意されています。

flock(リソース, オプション);
オプション 動作
LOCK_SH 共有ロック:書き込みを許可しない
LOCK_EX 排他的ロック:読み書き込み許可しない
LOCK_UN ロック解除
LOCK_NB ロック中に flock() でブロックしない

fclose()

ファイル操作が終了したら fclose() でファイルを閉じます。ファイルを閉じないと予期せぬエラーになることがあるので注意しましょう。

fclose(ファイルリソース)

データ読み込み

ファイル構成

data/
      └── information.txt
oneline.php

データファイルの作成

「data」フォルダを作成し、「information.txt」を用意します。テキストデータにお知らせ情報を1行ずつ書き込んでおきます。

information.txt
コーヒーを入荷しました
リニューアルオープンしました
メンテナンスのお知らせ

ファイル設定

ファイルパスの設定

「oneline.php」を作成し、テキストファイルのパスの変数「data/information.txt」を定義します。

$file_path = 'data/information.txt';

ファイルのチェック

ファイルパスが存在するか、file_exists() でチェックします。ファイルがない場合は、returnで処理を終了します。

if (!file_exists($file_path)) return;

データ読み込み

読み込み専用で開く

ファイルリソースを読み込み専用で開きます。

oneline.php
$file_path = 'data/information.txt';
if (!file_exists($file_path)) return;
//読み込みモードで開く
$file = fopen($file_path, 'r');

1行読み込み

fgets() でデータを1行読み込みます。オプションで読み込む長さ(バイト)を指定できますが、今回は指定しません。

データ = fgets(ファイルリソース, 長さ)

「information.txt」の最初の行を読み込んでみましょう。

oneline.php
$file_path = 'data/information.txt';
if (!file_exists($file_path)) return;

$file = fopen($file_path, 'r');
//1行読み込む
$data = fgets($file);

ファイルを閉じる

fopen() でファイルリソースを閉じます。

oneline.php
$file_path = 'data/information.txt';
if (!file_exists($file_path)) return;

$file = fopen($file_path, 'r');
$data = fgets($file);
//ファイルを閉じる
fclose($file);
HTML部分

HTML で読み込んだデータを表示します。

<h3 class="h3">お知らせ</h3>
<ul>
    <li><?= $data ?></li>
</ul>
結果

ブラウザでデータが表示されるか確認しましょう。

コーヒーを入荷しました

すべてのデータを読み込み

fgets() はデータを1行だけ読み込みましたが、繰り返しを使ってすべての行を読み込みます。

ファイル構成

    ├── data
    │   └── information.txt
    ├── list.php
    └── oneline.php

データ読み込み

メソッドの定義

「list.php」に loadInformations() を定義し、ファイルパスを引数にします。

list.php
function loadInformations($file_path)
{

}

whileで繰り返し

「oneline.php」と同様の処理でファイルを開きます。

list.php
function loadInformations($file_path)
{
    if (!file_exists($file_path)) return;

    $informations = [];
    $file = fopen($file_path, 'r');

    fclose($file);
}

配列に追加

while文で、gets() を最後まで繰り返します。読み込んだデータは配列に1行ずつデータ追加し、returnで返します。

list.php
function loadInformations($file_path)
{
    if (!file_exists($file_path)) return;

    $informations = [];
    $file = fopen($file_path, 'r');
    //繰り返し
    while ($data = fgets($file)) {
        //配列に1行ずつ追加
        $informations[] = $data;
    }
    //データを返す
    return $informations;
    fclose($file);
}

お知らせデータ読み込み

loadInformations() にファイルパスを指定して実行します。読み込んだ結果(配列)は変数に代入しておきます。

$file_path = 'data/information.txt';
$informations = loadInformations($file_path);

データを HTML で表示する

お知らせ情報を endforeach() 文で繰り返し、HTML表示してみましょう。

<h3 class="h3">お知らせ</h3>
<dl>
    <?php if ($informations) : ?>
        <?php foreach ($informations as $information) : ?>
            <dd><?= $information ?></dd>
        <?php endforeach ?>
    <?php endif ?>
</dl>
結果

お知らせ

コーヒーを入荷しました
リニューアルオープンしました
メンテナンスのお知らせ

ソース

list.php
<?php
$file_path = 'data/information.txt';
$informations = loadInformations($file_path);

function loadInformations($file_path)
{
    if (!file_exists($file_path)) return;

    $informations = [];
    $file = fopen($file_path, 'r');
    while ($data = fgets($file)) {
        $informations[] = $data;
    }
    fclose($file);
    return $informations;
}
?>

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>お知らせ</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
 rel="stylesheet">
</head>

<body>
    <div class="container">
        <h3 class="h3">お知らせ</h3>
        <dl>
            <?php if ($informations) : ?>
                <?php foreach ($informations as $information) : ?>
                    <dd><?= $information ?></dd>
                <?php endforeach ?>
            <?php endif ?>
        </dl>
    </div>
</body>

</html>

PHP超入門