25. テキストデータの書き込み

ファイルを書き込む前に

フォルダのアクセス権変更

Mac や Linux ではファイルを書き込むために、フォルダの書き込み権限を付与する必要がします。Windows ネイティブの場合は基本的に必要ありません。

ターミナルで変更する場合

VSCode でターミナルを開き、アクセス権限をフル(777) に変更します。今回は都合上 777 で設定しましたが、Webサーバが書き込める権限にあわせてください。

chmod 777 data

ファイルを確認します。

ls -al

data フォルダの書き込み権限が 777(rwxrwxrwx) に変更されました。

drwxrwxrwx   6 xxx  xxx   xxx  data

MacのFinderで変更する場合

Macではファイルの情報でアクセス権限を変更できます。data フォルダを右クリックして「情報を見る」を選択します。

鍵をロック解除して「読み/書き」に変更します。

入力フォームの作成

ファイル構成

information/
    ├── data/
    │         └── information.txt
    ├── add.php
    └── list.php

結果

「list.php」に入力フォームを追加します。フォームの送信先は「add.php」とします。

list.php
        <h3 class="h3">お知らせ入力</h3>
        <div class="container mb-3">
            <form action="add.php" method="post">
                <div class="row">
                    <input type="text" name="information" class="form-control col-8">
                    <button class="btn btn-primary">追加</button>
                </div>
            </form>
        </div>

お知らせの書き込み

データ書き込み処理

メソッド定義

「add.php」にinsert() メソッドを定義します。ファイルパスと書き込みデータを引数とします。

add.php
function insert($file_path, $data)
{

}

データ書き込みの実装

入力されたデータの行末に改行コードを追加し、fput() でデータ書き込みの処理をします。書き込み中は flock() で制御しておくとより安全です。

function insert($file_path, $data)
{
    if (!file_exists($file_path)) return;
    if (!$data) return;

    //改行コードを追加
    $data .= PHP_EOL;

    $file = fopen($file_path, 'a+');
    //ファイルロック
    flock($file, LOCK_EX);
    //データ書き込み
    fputs($file, $data);
    //ファイルロック解除
    flock($file, LOCK_UN);
    fclose($file);
}

データ書き込みの実行

POSTデータがあれば、insert() を実行します。

add.php
$file_path = 'data/information.txt';

if (isset($_POST['information'])) {
    insert($file_path, $_POST['information']);
}

ソース

add.php
if (isset($_POST['information'])) {
    insert($file_path, $_POST['information']);
}

header('Location: list.php');

function insert($file_path, $data)
{
    if (!file_exists($file_path)) return;
    if (!$data) return;
    
    $data .= PHP_EOL;

    $file = fopen($file_path, 'a+');
    flock($file, LOCK_EX);
    fputs($file, $data);
    flock($file, LOCK_UN);
    fclose($file);
}
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>Document</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>

<body>
    <div class="container">
        <h3 class="h3">お知らせ入力</h3>
        <div class="container mb-3">
            <form action="" method="post">
                <div class="row">
                    <input type="text" name="information" class="form-control col-8">
                    <button class="btn btn-primary">追加</button>
                </div>
            </form>
        </div>
        <h3 class="h3">お知らせ</h3>
        <dl>
            <?php if ($informations) : ?>
                <?php foreach ($informations as $information) : ?>
                    <dd><?= $information ?></dd>
                <?php endforeach ?>
            <?php endif ?>
        </dl>
    </div>
</body>

</html>

    <form action="add.php" method="post">
        <div>
            <label for="">お知らせ</label>
            <input type="text" name="information">
        </div>
        <button>書き込み</button>
    </form>

PHP超入門