前回、登録ページと一覧ページのHTMLに共通する箇所を共通化させました。
その際、HTMLをベタ打ちで書いていた箇所をPHPでデータベースからデータを取得し、一覧表示できるようにしました。
テーブルにデータがない状態を再現する方法とXSS(クロスサイトスクリプティング)対策についても学びました。
↓作成したページ
1. データベースからデータを取得
mysqli_query()
でmysqli_result
オブジェクトを取得し、
mysqli_fetch_assoc()
でmysqli_result
オブジェクトから、フィールド名(カラム名)を引数とする連想配列として取り出す
shinya-tech.com
2. HTMLでデータを表示
foreach文を使用し、ループ処理を行う。
3. データがない場合
if文を用いて条件分岐を行う。
なお、データがない状態を作るためにTRUNCATE TABLE文
を使う。
TRUNCATE TABLE文
はMySQLで特定のテーブルの全データを削除するときに用いる。
TRUNCATE TABLE <全データを削除したいテーブル名>; # 例えば、reviewsテーブルを削除したい場合は、 TRUNCATE TABLE reviews;
4. XSS対策
XSSとは
XSS(クロスサイトスクリプティング)とは、ユーザの入力データを表示する箇所のHTML生成の実装に不備があると発生する脆弱性のこと。
JavaScriptのコード(<script>…</script>
)を入力された場合、XSS対策をしていないと、スクリプトが実行されてしまう。
例えば、Cookie情報を抜き出すスクリプトが実行されると、Cookie情報からなりすましログインをされてしまう。
結論、ユーザの入力内容を表示する箇所ではXSS対策が必須。
XSS対策の方法
htmlspecialchars()を使って、HTML特殊記号をエスケープする。
htmlspecialcars($string, $flags, $encoding)
* $string : 変換する文字列
* $flags : 処理の仕方を指定するフラグ
* $encoding : 文字を変換する時に使用するエンコーディング
ユーザが入力してデータベースに保存された<script>...</script>
をエスケープするなら
htmlspecialchars('<script>...</script>', ENT_QUOTES, 'UTF-8')
書いたコード
index.php
<?php require_once __DIR__ . '/lib/escape.php'; require_once __DIR__ . '/lib/mysqli.php'; function listReviews($link) { $reviews = []; $sql = 'SELECT title, author, status, score, summary FROM reviews'; $results = mysqli_query($link, $sql); while ($review = mysqli_fetch_assoc($results)) { $reviews[] = $review; } mysqli_free_result($results); return $reviews; } $link = dbConnect(); $reviews = listReviews($link); // layout.php内の変数に渡す $title = '読書ログの一覧'; $content = __DIR__ . '/views/index.php'; // layout.phpを取り込む include __DIR__ . '/views/layout.php';
views/index.php
<a href="new.php">読書ログを登録する</a> <main> <?php if (count($reviews) > 0) : ?> <?php foreach ($reviews as $review) : ?> <section> <h2> <?php echo escape($review['title']); ?> </h2> <div> <?php echo escape($review['author']); ?> / <?php echo escape($review['status']); ?> / <?php echo escape($review['score']); ?>点 </div> <p> <?php echo nl2br(escape($review['summary'])); ?> </p> </section> <?php endforeach; ?> <?php else : ?> <p>読書情報が登録されていません。</p> <?php endif; ?> </main>
lib/escape.php
<?php function escape($string) { return htmlspecialchars($string, ENT_QUOTES, 'UTF-8'); }