Developer

魁!小野の塾 PHPで簡単なプログラムを作ってみようの巻 第8話
2021.01.01
Lv2

魁!小野の塾 PHPで簡単なプログラムを作ってみようの巻 第8話

PHPで簡単なプログラムを作ってみよう 第8話

初心者向け、PHPプログラム構築講座です。
初心者といっても、PHPの勉強を少し行い、LAMP環境が自分で構築できるレベルを対象とします。
まったくの初心者の場合は、わからない部分が出てくると思います。
できるだけ細かく説明は入れていきますが、説明がわからない場合は、PHPやMySQLの初心者講座をご覧ください。

対象のスキルレベル

  • LAMP環境の構築
  • PHP言語が読める
  • HTML, CSS, Javascriptが少しわかる
  • Bootstrapのドキュメントをみて、HTMLが書ける
  • CDNを理解している

構築環境

  • Windows10
  • XAMPP(PHP7.3.2, MariaDB 10.1.38)

Validation

エラーチェックを実装していきます。
処理部分と、エラーの表示部分を作成するのですが、エラーメッセージはalertとして上に表示。
エラーのある場所は、入力枠を赤くする方向です。入力枠にエラーを表示することはしません。

入力エラーの表示に関しては、魁!小野の塾 PHPで簡単なプログラムを作ってみようの巻 第4話をもう一度読み直してください。

エラーチェックは、登録時のみ実施します。今回は更新がないのと、削除の場合は存在チェックなど行うのですが、今回は行わない予定です。

エラーチェック追加(抜粋)
[php highlight=”14,17-34″] <?php
// db resource
$db = new mysqli(‘localhost’, ‘root’, ”, ‘pjin’);
$db->set_charset("utf8");

// $_POST -> $request
$request = [
‘author’ => $_POST[‘author’] ?? ”,
‘content’ => $_POST[‘content’] ?? ”,
‘action’ => $_POST[‘action’] ?? ”
];

// create
$errors = [];
switch($request[‘action’]){
case ‘create’:
// error check
if(empty($request[‘author’])){
$errors[‘author’][] = ‘名前を入力して下さい。’;
}
if(mb_strlen($request[‘author’]) > 128){
$errors[‘author’][] = ‘名前は128文字以内で入力して下さい。’;
}
if(empty($request[‘content’])){
$errors[‘content’][] = ‘内容を入力して下さい。’;
}
if(mb_strlen($request[‘content’]) > 65535){
$errors[‘content’][] = ‘名前は65,535文字以内で入力して下さい。’;
}

if(count($errors) > 0){
// エラーがあれば終了
break;
}

// 登録処理
$sql = "insert into board(author, content) values (?, ?)";
if($stmt = $db->prepare($sql)){
$stmt->bind_param("ss", $request[‘author’], $request[‘content’]);
$stmt->execute();
$stmt->close();
// 登録後に空にします。
$request = [
‘author’ => ”,
‘content’ => ”
];
}
break;
}

// 検索処理
$rs = [];
$sql = "select * from board order by id desc";
if($stmt = $db->prepare($sql)){
$stmt->execute();
$stmt->bind_result($id, $createdAt, $author, $content);
while($stmt->fetch()){
$rs[] = [
‘id’ => $id,
‘createdAt’ => $createdAt,
‘author’ => $author,
‘content’ => $content
];
}
$stmt->close();
}

// db resource close
$db->close();
?>
[/php]

※参考 empty
※参考 mb_strlen
※参考 マルチバイト文字列 関数

もうちょっといい方法があるような気もするのですが、かなり勢いで作っているので、あまり考えないようにしています。
まず、$errors というエラー内容を入れる配列を作成します。

エラーチェックは、必須チェックと文字数制限の2種類のみ実施します。
実際は、半角、全角のみのチェックなど色々と入れるのですが、データの種類も数字や日付がないので、簡単なエラーチェックだけ実装しています。

必須チェックは、empty関数を利用して行います。
※参考 PHP isset, empty, is_null の違い早見表

参考サイトを見てみると、empty関数では、0を未入力として判断します。実際半角0を入力するケースは想定していないので、この仕様で良しとします。

文字数チェックは、マルチバイト関数で、文字数をカウントします。
MySQLもvarcharで指定している長さは文字数となりますので、長さでチェックします。
textは65,535文字を登録することが可能です。文字数がこの長さを超える場合は、mediumtext やlongtext という型もあります。文字数がやばいことに。。

$errorsの内容は2次元配列になっています。1次元目は、連想配列なので、author又はcontentになり、それぞれの項目に対して、0,1とエラーを入れることができます。
実際のところは、入っていない又は文字数制限超えのどちらかしか入りませんが。。。

プログラムから$errorsの内容を表してみると以下の表になります。

author [0] 未入力
author [1] 文字数制限
content [0] 未入力
content [1] 文字数制限

ただ、2次元配列として内容を表すと以下のようになります。

[0] [1]
author 未入力 文字数制限
content 未入力 文字数制限

なぜ2次元配列にしているかというと、項目毎(author, content)にエラーがあるかをチェックできるようにしたいからです。
配列は空で初期化しているので、どこかのエラーチェックにひっかかると、1次元目の項目が追加されます。これで、$errorsの配列の要素数が0よりも大きくなれば、エラーが発生していることが分かります。

HTML部分の修正

エラー部分は、alertで出力し、各項目を赤枠で表示するようにします。

エラーチェック追加(抜粋)
[html highlight=”3-14,23,31″] <main class="container">

<?php if(count($errors) > 0){ ?>
<div class="alert alert-danger" role="alert">
<h4 class="alert-heading"><i class="fas fa-exclamation-triangle"></i> エラー</h4>
<ul>
<?php foreach($errors as $err){ ?>
<?php foreach($err as $e){ ?>
<li><?php echo htmlentities($e) ?></li>
<?php } ?>
<?php } ?>
</ul>
</div>
<?php } ?>

<form action="<?php echo $_SERVER[‘SCRIPT_NAME’] ?>" method="POST">
<input type="hidden" name="action" value="create">
<div class="form-group row">
<label for="author" class="col-sm-2 col-form-label">名前</label>
<div class="col-sm-10">
<input type="text" name="author" id="author"
value="<?php echo $request[‘author’] ?>"
class="form-control<?php if(isset($errors[‘author’])){ echo ‘ is-invalid’;} ?>"
placeholder="名前" autofocus>
</div>
</div>
<div class="form-group row">
<label for="content" class="col-sm-2 col-form-label">内容</label>
<div class="col-sm-10">
<textarea name="content" id="content"
class="form-control<?php if(isset($errors[‘content’])){ echo ‘ is-invalid’;} ?>"
rows="10" placeholder="内容を入力してください"><?php echo $request[‘content’] ?></textarea>
</div>
</div>
<div class="form-group row">
<div class="offset-sm-2 col-sm-10">
<button type="submit" class="btn btn-primary"><i class="fas fa-paper-plane"></i> 送信</button>
</div>
</div>
</form>
[/html]

3行目~14行目までが、alert部分の表記になります。(class=”alert alert-danger”)
$errorsの配列数が0よりも大きい(エラーがある場合)に表示するようにします。

$errorsは2次元配列になっているため、内容を出力する場合は、ループをネスト(入れ子)にします。
7、8行目が foreach をネストして、内容を表示する部分になります。

23行目、31行目は、入力枠部分を赤く表示するために、エラーがある場合に class を付加しています。(is-invalid)
is-invalid をクラスに追加すると、赤枠に、is-valid をクラスに追加すると緑枠になります。

魁!小野の塾