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';'
共通の関数などをライブラリのファイルにまとめる
複数のファイルで共通する関数などをまとめたライブラリを作り、実行するファイルから読み込んで使用する
- libフォルダ(ライブラリ置き場)を実行ファイルの階層に作る
- libフォルダに関数をまとめるファイルを作る(例
mysqli.php
) - 実行するファイルから読み込む
ライブラリのファイル
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
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
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で受け取った情報をデータベースに登録する
- HTTPメソッドがPOSTだったら
- POSTされた会社情報を変数に格納する
- バリデーションする
- データベースに接続する
- データベースにデータを登録する
- データベースとの接続を切断する
HTTPメソッドがPOSTだったら
1 | if ($_SERVER['REQUEST_METHOD'] === 'POST'){ |
POSTされた会社情報を変数に格納する
1 | $company = [ |
バリデーションする
あとで
データベースに接続する
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
20function 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
指定したファイルを読み込- 読み込みが失敗しても処理が中断されない
- HTMLやテキストなどを読み込むときに使う
1
include 'somefile.php';
require_once
指定したファイルを読み込む
- 例 : $errorsという変数がHTMLコード内にある時
HTMLの読み込みより前に空の変数を宣言しておけばOK
1 |
|
フォームの入力値を残す
フォームの入力でバリデーションエラーが出たら入力済みの値が消えてしまうが、値を保持させたい
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
9eco ($user['sec'] === '男性') ? 'checked' : '' ;
// 以下の文と等価
if ($user['sex'] === '男性') {
echo 'checked';
} else {
echo '';
}フォーム初回読み込み時にエラーが出る
初回読み込み時には、変数が未定義のため、エラーとなる。
回避のため、HTML読み込み前に変数を空で宣言しておく1
2
3
4
5
6
7
8
9
10
11
12
13
$review = [
'title' =>'',
'author' =>'',
'status' =>'',
'score' =>'',
'summary' =>'',
];
$errors = [];
include 'views/new.php';