練習問題

問題1

ユーザーから好きな食べ物を3つ入力してもらうフォームを表示し、それを1つのファイルに保存して表示するプログラムを作ってみてください。

ヒント

ユーザーから3つの入力を得ます。どのように3つのデータを1つのファイルに保存できるでしょうか。PHPの配列を保存するには、serialize()関数を使うことができるのでした。

答え

file:food-form.php

<?php
// データの保存先
$save_file = dirname(__FILE__)."/food.txt";
// ユーザーからデータが送信されているか?
if (isset($_GET["food"])) {
    save_data();
} else {
    show_form();
}
// データの保存
function save_data() {
    global $save_file;
    $self = $_SERVER["SCRIPT_NAME"];
    // データの検証
    $list = $_GET["food"];
    if (count($list) != 3 || $list[1] == "" || $list[2] == "") {
        echo "<a href='$self'>食べ物を3つ入力してください。</a>";
        exit;
    }
    // 保存
    file_put_contents($save_file, serialize($list));
    echo "<a href='$self'>保存しました</a>";
}
// フォームの表示
function show_form() {
    global $save_file;
    if (file_exists($save_file)) {
        echo "<h3>好きな食べ物</h3>";
        $list = unserialize(file_get_contents($save_file));
        foreach ($list as $food) {
            echo htmlspecialchars($food) . "<br/>";
        }
        echo "<hr/>";
    }
    echo <<< __FORM__
<h3>好きな食べ物を3つ入力してください</h3>
  <form>
  <input type="text" name="food[]" /><br/>
  <input type="text" name="food[]" /><br/>
  <input type="text" name="food[]" /><br/>
  <input type="submit" value="保存" />
</form>
__FORM__;
}
画面
画面
画面
画面

あるいは、serialize()関数を使わなくても、適当な区切り記号(例えば改行)で文字列を区切って保存するという方法もあります。

file:food-form2.php から抜粋

// 保存
$str = implode("\n", $list); // 改行を使ってリストを区切る
file_put_contents($save_file, $str);
// ...
// 読込
$str = file_get_contents($save_file);
$list = explode("\n", $str);

※配列を任意の区切り文字で結合するのが「implode()」関数で、文字列を任意の区切り記号で区切って配列にするのが「explode()」関数です。

問題2

先ほど作った問題1のプログラムを改良して、パスワードによる保護機能をつけてください。つまり、入力した好きな食べ物を本人以外が変更できないように改良してみてください。(ここではパスワード自体をPHPのプログラム内に書くことにします。)

ヒント

パスワードの入力欄を増やし、パスワードの照合処理を追加するようにします。

答え

パスワードの保護を行う部分以外は、ほとんど同じです。そのため、変更が必要となっている部分だけを抜粋して紹介ます。

file: food-form3-pass.php

<?php
// データの保存先
$save_file = dirname(__FILE__)."/food.txt";
// 書き換えのためのパスワード
$master_password = "test";
...
// データの保存
function save_data() {
    global $save_file;
    global $master_password;
    $self = $_SERVER["SCRIPT_NAME"];
    // パスワードの検証
    if (isset($_GET["pass"]) && $_GET["pass"] !== $master_password) {
        echo "パスワードが違います。"; exit;
    }
    ...
}
// フォームの表示
function show_form() {
    ...
    echo <<< __FORM__
<h3>好きな食べ物を3つ入力してください</h3>
  <form>
  <input type="text" name="food[]" /><br/>
  <input type="text" name="food[]" /><br/>
  <input type="text" name="food[]" /><br/><br/>
  パスワード: <input type="password" name="pass" /><br/>
  <input type="submit" value="保存" />
</form>
__FORM__;
}