データを登録する

HTMLのフォームに入力されたデータをPHPで処理してデータベースに登録する

  • 登録
  • リダイレクト
  • バリデーション

    PHPの定義済み変数

    PHPで定義されている変数。外部から情報などが取得できる

    $_ENV

  • 環境変数 連想配列として受け取る

    $_POST

  • POSTされた情報 連想配列として受け取る

    $_GET

  • URLパラメータの情報 連想配列として受け取る

    $_SERVER

  • サーバや実行時の環境情報 連想配列として受け取る

    REQUEST_METHOD: ページにアクセスする際に使用されたメソッド名

    'GET','POST'など

    マジック定数

    使われる場所によって値が変化する定数がマジック定数

    __DIR__

    そのファイルの存在するディレクトリ名

    __FILE__

    そのファイルの古パスとファイル名

    __LINE__

    そのファイル上の現在の行番号

    外部ファイルの読み込み

    共通の処理は別ファイルにまとめて、そのファイルを読み込んで使おう

    require

    指定したファイルを読み込む。読み込みが失敗すると処理がそこで中断される
    1
    require 'somefile.php';'

    require_once

    reuireとほぼ同じ。一度しかファイルを読み込まない

    悩んだらrequire_onceを使うことを推奨
    1
    require_once 'somefile.php';'

    共通の関数などをライブラリのファイルにまとめる

    複数のファイルで共通する関数などをまとめたライブラリを作り、実行するファイルから読み込んで使用する
  1. libフォルダ(ライブラリ置き場)を実行ファイルの階層に作る
  2. libフォルダに関数をまとめるファイルを作る(例mysqli.php)
  3. 実行するファイルから読み込む

    ライブラリのファイル

    libフォルダ以下にmysqli.phpファイルを作る
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <?php

    require __DIR__ . '/../../vendor/autoload.php';

    function dbConnect()
    {
    $dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/../..');
    $dotenv->load();

    $dbHost = $_ENV['DB_HOST'];
    $dbUsername = $_ENV['DB_USERNAME'];
    $dbPassword = $_ENV['DB_PASSWORD'];
    $dbDatabase = $_ENV['DB_DATABASE'];

    $link = mysqli_connect($dbHost, $dbUsername, $dbPassword, $dbDatabase);
    if (!$link) {
    echo 'Error: データベーに接続できません' . PHP_EOL;
    echo 'Debugging error: ' . mysqli_connect_error() . PHP_EOL;
    exit;
    }
    return $link;
    }

    実行ファイルでの読み込み

    実行ファイルでの読み込み
    create.php
    1
    2
    3
    4
    5
    6
    <?php

    require_once __DIR__ . '/lib/mysqli.php'; // ライブラリのファイルを読み込み(関数が使えるようになる)
    ...
    // データベースに接続する
    $link = dbConnect();

    登録する情報をPHPへ送る

    情報の送り先ファイルをaction属性の値に、データの登録なのでメソッドはPOST
    送り先のphpファイルに設定してフォームを送信すると、

    $_POSTの連想配列として情報が渡せる
    1
    2
    3
    4
    5
    <form action="create.php" method="POST">
    ...
    ...
    <button type="submit">登録する</button>
    </form>

    PHPで受け取った情報をデータベースに登録する

  4. HTTPメソッドがPOSTだったら
  5. POSTされた会社情報を変数に格納する
  6. バリデーションする
  7. データベースに接続する
  8. データベースにデータを登録する
  9. データベースとの接続を切断する

HTTPメソッドがPOSTだったら

1
2
3
if ($_SERVER['REQUEST_METHOD'] === 'POST'){
// メソッドがPOSTのときだけPOSTされた会社情報を変数に格納する
}

POSTされた会社情報を変数に格納する

1
2
3
4
5
$company = [
'name' => $_POST['name'],
'establishment_date' => $_POST['establishment_date'],
'founder' => $_POST['founder']
];

バリデーションする

あとで

データベースに接続する

1
$link = dbConnect();

データベースにデータを登録する

1
createCompany($link, $company);

データベースとの接続を切断する

1
mysqli_close($link);

リダイレクト

データを保存した後、登録情報が表示されるページに遷移させる

遷移先のページを作る
index.php

表示する内容をHTMLで記述しておく

データ登録後にページを遷移させる

1
header("Location: index.php");

アクセスログとエラーログを出力

ログとはプログラムの実行状況・データ送受信などを記録しておくもの

PHP・Apacheのログ

ログには主にアクセスログとエラーログがある。

PHPはエラーログ、Apacheはアクセスログとエラーログを主に出力

ログを確認

Dockerコンテナ内のログを確認するコマンドdocker logs

  • docker ps コンテナ名を確認
  • docker logs -f <コンテナ名> - ログを確認するとき(-f: follow ログの出力を表示し続ける)
  • docker logs <コンテナ名> -f 2>/dev/null - アクセスログを確認(エラーログ捨てる)
  • docker logs <コンテナ名> -f 1>/dev/null - エラーログを確認(アクセスログを捨てる)

    ログにエラーを記録

    mysqli関数にエラーがあったときにログを出力
    1
    2
    3
    4
    5
    $result = mysqli_query($link, $sql);
    if (!$result) {
    error_log('Error: Fail to create company');
    error_log('Debugging Error: ' . mysqli_error($link));
    }

    バリデーション処理

    バリデーション処理に使う関数
  • strlen()

    文字のあるなしを判定。
  • explode(区切り文字列, 入力文字列)

    文字列を区切って配列に格納
  • count()

    配列の要素を数えて数を返す
  • checkdate(月, 日, 年)

    暦が正しいかを判定
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    function validate($company) {

    // エラーを`$errors`という配列を準備して配列に格納する
    $errors = [];

    // 会社名
    if (!strlen($company['name'])) { // 入力がない場合
    $errors['name'] = '会社名を入力してください';
    } elseif (strlen($company['name']) > 255) { // 文字数が多い場合
    $errors['name'] = '会社名は255文字以内で入力してください';
    }
    // 設立日
    $dates = explode('-', $company['establishment_date']); // 日付の形式 yyyy-mm-dd を"-"で分割している。
    if (!strlen($company['establishment_date'])) { // 入力がない場合
    $errors['establishment_date'] = '設立日を入力してください';
    } elseif (count($dates) !== 3) { // datesの配列が3つかどうかで形式を判定
    $errors['establishment_date'] = '設立日を正しい形式で入力してください';
    } elseif (!checkdate($dates['1'], $dates['2'], $dates['0'])) { // 存在する日付かどうかの判定
    $errors['establishment_date'] = '設立日を正しい日付で入力して下さい';
    }

    HTMLとPHPファイルを分割

    HTMLファイルを分割したらincludeで読み込もう
  • include

    指定したファイルを読み込
    1. 読み込みが失敗しても処理が中断されない
    2. HTMLやテキストなどを読み込むときに使う
      1
      include 'somefile.php';
  • require_once

    指定したファイルを読み込む
    1. 読み込みが失敗したら処理が中断される
    2. 関数など重要な処理を読み込むときに使う
      1
      require_once 'somefile.php';

      HTMLに未定義の変数があるとき

      空の変数を用意しておき、エラーを回避する。
  • 例 : $errorsという変数がHTMLコード内にある時

    HTMLの読み込みより前に空の変数を宣言しておけばOK
1
2
3
4
5
<?php

$errors = [];

include 'views/new.php';

フォームの入力値を残す

フォームの入力でバリデーションエラーが出たら入力済みの値が消えてしまうが、値を保持させたい

inputタグのvalue属性を使う

input要素の値を指定する属性

  • テキスト入力欄などにおいては初期入力値を表す
    1
    <input type="text" id="name" name="name" value="<?php echo $company['name']?>">

    ラジオボタンの初期値checked属性

    checked属性をつけると初期値で選択された状態になる
    1
    2
    3
    <input type="radio" name="sex" id="sex1" value="男性"
    <?php echo (#user['sex'] === '男性')? 'checked' : '' ; ?>>
    <label for ="sex1">男性</label>
  • 3項演算子とif文
    1
    2
    3
    4
    5
    6
    7
    8
    9
    eco ($user['sec'] === '男性') ? 'checked' : '' ;

    // 以下の文と等価

    if ($user['sex'] === '男性') {
    echo 'checked';
    } else {
    echo '';
    }

    フォーム初回読み込み時にエラーが出る

    初回読み込み時には、変数が未定義のため、エラーとなる。

    回避のため、HTML読み込み前に変数を空で宣言しておく
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?php

    $review = [
    'title' =>'',
    'author' =>'',
    'status' =>'',
    'score' =>'',
    'summary' =>'',
    ];

    $errors = [];

    include 'views/new.php';