Developer

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

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

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

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

対象のスキルレベル

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

構築環境

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

登録処理実装

検索処理が実装されましたが、データが入ってない為、何も表示されていません。
まずは、登録処理を軽く実装して、表示されるかを確認します。
ここでは、エラーチェックなど考慮しません。(※データが入り次第実装しますよー)

登録処理追加(抜粋)
[php highlight=”6-29″] <?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
switch($request[‘action’]){
case ‘create’:
// 登録処理
$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]

※参考 mysqli_stmt::bind_param
※参考 Null 合体演算子

まず、$_POSTの内容をローカル変数へ代入します。
※これは後から使うことになるので、今はグローバルからローカルへ入れるくらいに思っていてください。

この時に、「??」Null合体演算子を利用して、値が入っていない場合は、空文字を代入しておきます。
※これもあとから説明致します。

もう一つ、登録と削除の処理があるので、actionという引数を渡しています。
※これはHTMLにあとで追加します。

ローカル変数へ代入出来たら、actionごとに処理分けします。
今回は登録と削除を分けることになるのですが、初期表示の場合は、何も入らないので、空文字となり、処理は通りません。
場合分けがはっきりしている場合は、switch文を利用すると見やすくなります。

登録用のSQLを作成するのですが、値の部分は「?」を利用します。
?は、プレースホルダといいます。参考を読むと分かりますが、SQLインジェクション対応です。
※参考 PHPでプレースホルダを使ったフォーム作成

プリペアドステートメントを作成(オープン)します。
少し前までは、プレペアドステートメントを利用する場合は、PDOを利用していましたが、mysqliクラスで利用可能になりましたので、こちらを利用します。
※参考 安全なSQLの呼び出し方

プレースホルダ(?)に、bind_param関数を呼び出して、値を設定します。
ちょっと使い方が慣れるまで「ん?」と思うかも知れません。
PHPのリファレンスを参照すると以下のように書かれています。

public mysqli_stmt::bind_param ( string $types , mixed &$var , mixed &…$vars ) : bool

括弧のところが引継ぎ変数です。
1番目は、string $types と書かれており、ここは、引数の数(プレースホルダの数)分、型を羅列します。
今回は、2つのプレースホルダがありますので、型は2つ並べます。文字列なので、sが二つになります(ss)。

型指定文字 説明
i 対応する変数の型は integer です。
d 対応する変数の型は double です。
s 対応する変数の型は string です。
b 対応する変数の型は string です。

2番目の引数は、mixed &$var と書かれていますが、バインドする変数を入れていきます。
mixed 型の変数 $var なのですが、PHPは動的型付き言語なので、データ型がないと思われている方が多いのですが、データ型はあります。
簡単に説明すると、なんでも型みたいなものです。
※参考 mixed 型
※参考 union 型

&の記号を付けるのをよく見ますが、値の前につけると参照渡しになります。
いろんな場面で、参照渡しを使っていきますが、まずは参照渡しという言葉を覚えておくと良いと思います。
※参考 【PHP超入門】参照(リファレンス)の代入について

3番目の引数は、mixed &…$var となっております。データ型は mixed なのですが、&の後に、…と見慣れない記号がついています。
実際は、カンマ区切りでバインドするパラメータを羅列しているだけなのですが、2この引数と、10この引数をこの定義で受け付けることができます。
ちなみにこれ、可変長引数リストを表しています。
※参考 可変長引数リスト

プレースホルダに値をバインドしたら、execute関数を利用してSQLを実行します。
実行したステートメントをクローズして、ローカル変数をクリアして処理は終了です。

ローカル変数をクリアする際に、contentのみクリアした場合は、登録画面で登録時に利用した名前を何度も利用することができます。
このローカル変数は、エラーチェックした際に、値が消えてしまう場合に利用するもので、エラーチェックがない場合は、特に必要もないものでした。
あとからエラーチェックを追加するのですが、このタイミングで、グローバル($_POST)からローカル変数($request)に代入して利用することに慣れてもらうためのものです。
上の説明では、あとで説明すると書かれていましたが、エラーチェックを入れるタイミングでもう一度説明致します。

HTMLに登録部分の内容を追加

HTMLから離れてしまったので、変更前のform部分を見てみます。

変更前(抜粋)
[html highlight=””] <form>
<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" class="form-control" id="author" 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" class="form-control" id="content" rows="10" placeholder="内容を入力してください"></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]

ここから変更を入れていくのですが、以下のようになります。

変更後(抜粋)
[html highlight=”1,2,7,17″] <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"
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"
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]
  • form部分のaction属性を追加(action=”<?php echo $_SERVER[‘SCRIPT_NAME’] ?>”)
  • typeをhiddenで、name=action で 値にcreateを入れます。(登録と削除の処理分けをする為)
  • 値の初期値(value属性)に値を入れます。

※参考 定義済の変数
※参考 $_SERVER

定義済変数の$_SERVERを利用して、現在のプログラムを表示できます。
値に$_POSTを利用すると、指定されているキーがない場合はエラーが表示されたりします。
回避するために、ローカル変数($request)を利用しています。

例えば、name=authorという設定がある場合、POSTで送信されると $_POST[‘author’] で取得できます。
まずは、こういうのを書いていくことになるのですが、初期表示時は、当然値が入りません。キーもありません。なのでアクセスするとエラーとなります。
このエラーを回避するために、isset などの関数を駆使してコードを書くことになります。

連想配列のキーチェック
[php highlight=””] <?php
if(isset($_POST[‘author’])){
echo $_POST[‘author’];
}else{
echo ‘きーなし’;
}
?>
<form action="<?php echo $_SERVER[‘SCRIPT_NAME’] ?>" method="POST">
<input type="text" name="author">
<input type="submit">
</form>
[/php]

簡単なプログラムで検証してみます。このプログラムでは、初期表示時は、きーなしと表示されます。
入力項目に値を入れて、ボタンを押下すると、入力値が表示されます。

入力後に、値を消さずに残し続ける場合は、大抵以下のようなコードを書いてきます。

連想配列のキーチェック 値を保持
[php highlight=””] <?php
if(isset($_POST[‘author’])){
echo $_POST[‘author’];
}else{
echo ‘きーなし’;
}
?>
<form action="<?php echo $_SERVER[‘SCRIPT_NAME’] ?>" method="POST">
<input type="text" name="author" value="<?php echo $_POST[‘author’] ?>">
<input type="submit">
</form>
[/php]

実行すると初期表示時にエラーが出力されます。(Notice: Undefined index: author in C:\xampp\htdocs\pjin\board\key.php on line 9
値を入れてボタンを押下するとエラーが消えます。

これを回避するのに、ローカル変数を利用してみます。

連想配列のキーチェック ローカル変数利用
[php highlight=””] <?php
$request = [];
if(isset($_POST[‘author’])){
$request[‘author’] = $_POST[‘author’];
}else{
$request[‘author’] = ”;
}
?>
<form action="<?php echo $_SERVER[‘SCRIPT_NAME’] ?>" method="POST">
<input type="text" name="author" value="<?php echo $request[‘author’] ?>">
<input type="submit">
</form>
[/php]

ちょっと長いので、三項演算子を利用してみます。

連想配列のキーチェック 三項演算子利用
[php highlight=”3″] <?php
$request = [
‘author’ => isset($_POST[‘author’]) ? $_POST[‘author’] : ”
];
?>
<form action="<?php echo $_SERVER[‘SCRIPT_NAME’] ?>" method="POST">
<input type="text" name="author" value="<?php echo $request[‘author’] ?>">
<input type="submit">
</form>
[/php]

ちょっと長いので、??のnull合体演算子を利用してみます。

連想配列のキーチェック null合体演算子
[php highlight=”3″] <?php
$request = [
‘author’ => $_POST[‘author’] ?? ”
];
?>
<form action="<?php echo $_SERVER[‘SCRIPT_NAME’] ?>" method="POST">
<input type="text" name="author" value="<?php echo $request[‘author’] ?>">
<input type="submit">
</form>
[/php]

登録処理追加(抜粋)の7行目~11行目部分は、グローバルからローカル変数に値を入れています。
null合体演算子を利用してコードを短くしています。

魁!小野の塾