最近、ChatGPTでいろいろと遊んでいるのですが、プログラミングもできると知り、PHPで簡易な御朱印データベースを作ってもらいました。
仕様の提案・整理からプログラミングまで、ほぼすべてをChatGPTにお任せしています。
たまに仕様にないものを盛り込んできたり、仕様に入っている機能が抜けていたりすることに悩まされましたが、指示し直したり、たたき台をこちらから提示したり、手動で修正したりして解決しました。
しかし、ここまでのレベルのことができるとは、AI恐るべし。
なお、このデータベースは文字通り簡易でセキュリティよわよわなので、一般公開はしていません。

ちなみに、これもChatGPT製です。
御朱印データベースシステム - 要求仕様書
1. システム概要
御朱印データベースシステムは、御朱印の情報をデータベースに登録・管理できるWebアプリケーションである。 PHPとSQLiteを使用し、スマートフォン対応のレスポンシブデザインを採用する。
画像のアップロード・管理機能を備え、安全なデータ操作を行うためのセキュリティ対策を実施する。</p><h2>2. システム要件</h2><h3>2.1 ハードウェア要件</h3><ul><li>サーバー: PHP 7.4以上、SQLite 3.0以上が動作する環境</li><li>クライアント: HTML5/CSS3対応のWebブラウザ(Google Chrome, Firefox, Edge, Safari)</li></ul><h3>2.2 ソフトウェア要件</h3><ul><li>OS: Linux / Windows / macOS</li><li>Webサーバー: Apache / Nginx(PHPが動作する環境)</li><li>開発言語: PHP(バックエンド), HTML/CSS(フロントエンド)</li><li>データベース: SQLite(<q>goshuin.db</q>)</li><li>セキュリティ: SQLインジェクション対策(PDO)、XSS対策、ファイルアップロードのバリデーション</li></ul><h2>3. 機能要件</h2><h3>3.1 ユーザー機能</h3><table><tr><th>機能</th><th>説明</th><th>詳細</th></tr><tr><td>御朱印の登録</td><td>御朱印情報をデータベースに登録</td><td>フォーム入力、画像アップロード</td></tr><tr><td>御朱印の編集</td><td>既存の御朱印情報を変更</td><td>画像変更時は古い画像を削除</td></tr><tr><td>御朱印の削除</td><td>御朱印情報を削除</td><td>画像も削除</td></tr><tr><td>御朱印の検索</td><td>キーワードで検索</td><td>タグ・寺社名・住所を対象</td></tr><tr><td>御朱印の一覧表示</td><td>登録データを一覧で表示</td><td>カード形式、サムネイル付き</td></tr><tr><td>画像アップロード</td><td>御朱印の画像をアップロード</td><td>JPEG/PNGのみ、サイズ調整</td></tr></table><h3>3.2 データ管理</h3><table><tr><th>機能</th><th>説明</th><th>備考</th></tr><tr><td>データベース作成</td><td><code>goshuin.db</code> を自動生成</td><td>初回起動時に作成</td></tr><tr><td>データバリデーション</td><td>不正データの排除</td><td>入力チェック、XSS対策</td></tr><tr><td>画像リサイズ</td><td>画像の高さを200pxに統一</td><td>幅は自動調整</td></tr></table><h2>4. データベース設計</h2>
<h3>4.1 データベース構造</h3><h4>goshuinテーブル</h4><table><tr><th>フィールド名</th><th>型</th><th>制約</th><th>説明</th></tr><tr><td>id</td><td>INTEGER</td><td>PRIMARY KEY AUTOINCREMENT</td><td>ユニークID</td></tr><tr><td>jisya_name</td><td>TEXT</td><td>NOT NULL</td><td>寺社名</td></tr><tr><td>type</td><td>TEXT</td><td>NOT NULL</td><td>種別(神社 / 寺院 / その他)</td></tr><tr><td>visit_date</td><td>TEXT</td><td>NOT NULL</td><td>訪問日(YYYY-MM-DD)</td></tr><tr><td>address</td><td>TEXT</td><td>NULL</td><td>住所</td></tr><tr><td>content</td><td>TEXT</td><td>NULL</td><td>記述内容</td></tr><tr><td>book_name</td><td>TEXT</td><td>NULL</td><td>御朱印帳名</td></tr><tr><td>tags</td><td>TEXT</td><td>NULL</td><td>タグ(カンマ区切り)</td></tr><tr><td>memo</td><td>TEXT</td><td>NULL</td><td>メモ</td></tr><tr><td>image</td><td>TEXT</td><td>NULL</td><td>画像パス</td></tr></table><h2>5. セキュリティ要件</h2><table><tr><th>項目</th><th>内容</th></tr><tr><td>SQLインジェクション対策</td><td><code>PDO::prepare()</code> を使用</td></tr><tr><td>XSS対策</td><td><code>htmlspecialchars()</code> でエスケープ処理</td></tr><tr><td>CSRF対策</td><td>フォームにCSRFトークンを埋め込み</td></tr><tr><td>画像アップロード制限</td><td>MIMEタイプを <code>image/jpeg, image/png</code> に制限</td></tr><tr><td>ファイル名のランダム化</td><td><code>uniqid()</code> でランダム名を生成</td></tr><tr><td>ディレクトリトラバーサル対策</td><td><code>basename()</code> を使用し、パスを制限</td></tr><tr><td>古い画像の削除</td><td>新しい画像をアップロード時に <code>unlink()</code> で削除</td></tr></table><h2>6. UI/UX設計</h2><h3>6.1 デザイン仕様</h3><ul><li>レスポンシブ対応(スマホ・タブレット・PC対応)</li><li>カード形式の一覧表示(画像付きのタイルレイアウト)</li><li>フォーム入力は必須項目に <code>required</code> を使用</li></ul><h3>6.2 スタイル仕様(抜粋)</h3><p><code>css
body {
font-family: Arial, sans-serif;
margin: 20px;
text-align: center;
}
.form-container {
width: 100%;
max-width: 600px;
margin: 0 auto;
text-align: left;
}
button {
background-color: #4CAF50;
color: white;
font-size: 16px;
border: none;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
</code>
</p><h2>7. システムフロー</h2><h3>7.1 登録フロー</h3><ol><li>ユーザーが入力フォームに御朱印情報を入力 </li><li>画像をアップロード(バリデーション) </li><li>データベースに保存 </li><li>一覧画面にリダイレクト </li></ol><h3>7.2 編集フロー</h3><ol><li>ユーザーが <code>edit.php?id=XX</code> を開く</li><li>既存の情報を取得し、フォームに表示</li><li>変更後に保存ボタンを押す</li><li>画像が変更された場合、古い画像を削除</li><li>データベースを更新</li></ol><h2>8. 例外処理</h2><table><tr><th>事象</th><th>対応</th></tr><tr><td>必須項目が未入力</td><td>エラーメッセージ表示</td></tr><tr><td>画像アップロード失敗</td><td>エラーメッセージ表示</td></tr><tr><td>データベース接続エラー</td><td><code>try-catch</code> で例外処理</td></tr></table>