Developer

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

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

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

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

対象のスキルレベル

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

構築環境

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

HTMLからPHPへ変換

お待たせ致しました。やっと本題のPHPでプログラミングを始めたいと思います。
まずは、index.htmlの拡張子をindex.phpへ変更するところから始めます。

変更したら、XAMPPを起動し、「http://localhost/board/index.php」へアクセスします。
※XAMPPのインストールフォルダー直下に「htdocs」があり(公開ディレクトリと言います)、そこに「board」フォルダーを作成していることが前提です。

アクセスして表示出来れば、PHPのプログラム完成です!!(素晴らしい!!)って言うと、大体の人に怒られるので、自粛しようといつも思います。。。

データベース接続

まずはデータベースへのアクセス部分から作成しようと思います。

index.phpの先頭へ、データベースへのアクセス記述を書いていきます。

ホスト localhost
ユーザ root
パスワード (なし)
データベース名 pjin
データベース接続(抜粋)
[php] <?php
// db resource
$db = new mysqli(‘localhost’, ‘root’, ”, ‘pjin’);
$db->set_charset("utf8");

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

※参考 mysqli::__construct
※参考 mysqli::set_charset
※参考 mysqli::close

手続き型とオブジェクト指向型がありますが、今回はオブジェクト指向型を利用します。
手続き型は古くからある書き方で、引数が多くなります。(一つだけですけど)

データベースへのコネクション(接続)は開いたら閉じましょう!
ファイルのポインタなど、リソースを開いたら、必ず閉じましょう!
大事なことなので、もう一度言います。開いたら、閉じる!!

また文字コードも設定しておきましょう!
※「SET NAMES utf8」をクエリとして発行する方法は、推奨されていません。
※参考 文字セット

参考の中に書かれている、文字コード設定での大事なことを抜粋します。

注意: UTF-8 でありがちなミス
MySQL の文字セット名はハイフンを含まないので、MySQL で UTF-8 を表す文字セットは “utf8″ が正解です。”utf-8″ ではないので、”utf-8” と指定しても文字セットは変わりません。

検索処理実装

データは入っていないのですが、検索処理から実装していきます。
シナリオとしては、データベースからの戻りを配列に入れて、配列からHTMLを出力という流れで行きたいと思います。

まずは検索部分の実装です。

検索部分実装(抜粋)
[php highlight=”7-21″] <?php
// db resource
$db = new mysqli(‘localhost’, ‘root’, ”, ‘pjin’);
$db->set_charset("utf8");

// 検索処理
$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::prepare
※参考 mysqli_stmt::execute
※参考 mysqli_stmt::bind_result
※参考 mysqli_stmt::fetch
※参考 mysqli_stmt::close

まず、$rsを初期化しておきます。
これは、結果を保存する用の配列です。ResultSet(結果セット)なので、$rsにしています。

SQLを定義しますが、今回はboardテーブルを参照するだけです。
登録したデータの降順で表示したい(最新が一番上にしたい)ので、idを降順(desc)で指定しています。

prepare関数を利用していますが、SQLインジェクション対応です。
元々は、あらかじめコンパイルしたSQLに対して、値を変えるだけで実行するというバッチ処理に利用していたのですが、インジェクション対応にもなるので、利用するようになりました。
通常のquery関数など利用する際は、パラメータをサニタイジングする必用がありますので、ご注意を!

execute関数でSQLを実行します。

結果を取得する場合は、データをバインド(束縛)する変数を定義したあと、fetchします。
bind_result関数を利用し、結果をそれぞれの変数へバインドします。

whileで結果をフェッチして、ループ内でバインドした変数を連想配列へ設定し、$rsへ追加します。
配列の追加部分が、$rs[] = 連想配列 となっておりますが、これで追加できます。関数を使ってもできますが、簡単に記述できるところがPHPの良いところです!

最後に$stmt(ステートメント)を閉じて終了です。

検索処理 表示部分実装

続いて、Card部分のHTMLをforeachで囲い、表示部分を作成していきます。

検索結果表示部分実装(抜粋)
[html highlight=””] <?php foreach($rs as $row){ ?>
<div class="card">
<div class="card-header">
<div class="row">
<div class="col-sm-6">
<strong><?php echo htmlentities($row[‘author’]) ?></strong>
</div>
<div class="col-sm-6 text-right">
<small><?php echo date(‘Y-m-d H:i:s ‘, strtotime($row[‘createdAt’])) ?></small>
</div>
</div>
</div>
<div class="card-body">
<p class="float-right">
<button type="submit" class="btn btn-outline-danger btn-sm">
<i class="far fa-trash-alt"></i> 削除
</button>
</p>
<p class="card-text">
<?php echo nl2br(htmlentities($row[‘content’])) ?>
</p>
</div>
</div>

<div class="mt-3"></div>
<?php } ?>
[/html]

XSS対応は忘れずに実行しましょう。
今回は、htmlentities を利用してHTMLタグなどに利用する記号をエスケープします。

※参考 PHPのhtmlentities()とhtmlspecialchars()の違いと適切なエンティティ変換

作成日時部分は、strtotime を利用して、文字列からUNIXエポック(Unixタイムスタンプ)に変換後、date を利用して書式化(フォーマット)しています。

内容は、改行が入りますので、nl2br を利用して、改行(br)を入れていきます。

魁!小野の塾