๐ ํผ์ ๋งค์ฅ ์จ๋ผ์ธ ์ฃผ๋ฌธ ํ๋ซํผ - ์ค์๊ฐ ์ฃผ๋ฌธ ์ ์ & ํ ํ ์ปค์คํฐ๋ง์ด์ง
pizza-shop-online-ordering
๋ฌธ์ ์ค๋ช
ํ๋ก์ ํธ ๊ฐ์
์๊ท๋ชจ ํผ์ ๋งค์ฅ์ ์ํ ์จ๋ผ์ธ ์ฃผ๋ฌธ ์ ์ ์์คํ ์ ๋ง๋ญ๋๋ค. ๊ณ ๊ฐ์ด ๋ฉ๋ด๋ฅผ ํ์ํ๊ณ , ํผ์ ํฌ๊ธฐ์ ํ ํ์ ์ ํํ๋ฉฐ, ์ฃผ๋ฌธ์๋ฅผ ์์ฑํ์ฌ ์ ์ถํ๋ฉด ๋งค์ฅ ์ฃผ์ธ์ด ์ฃผ๋ฌธ ๋ชฉ๋ก์ ํ์ธํ๊ณ ์ํ๋ฅผ ์ ๋ฐ์ดํธํ ์ ์์ต๋๋ค.
ํ์ ๊ธฐ๋ฅ
- ๋ฉ๋ด ํ์ด์ง: ํผ์ ์ข ๋ฅ(๋ง๋ฅด๊ฒ๋ฆฌํ, ํํผ๋ก๋, ์ฝค๋น๋ค์ด์ ๋ฑ) ๋ชฉ๋ก ํ์, ๊ฐ ํผ์๋ณ ์ค๋ช ยท๊ฐ๊ฒฉยท์ฌ์ง ํฌํจ
- ์ฃผ๋ฌธ ํผ: ๊ณ ๊ฐ์ด ํผ์ ํฌ๊ธฐ(Small/Medium/Large) ์ ํ, ์ถ๊ฐ ํ ํ(์ฌ๋ฆฌ๋ธ, ๋ฒ์ฏ, ๋ฒ ์ด์ปจ ๋ฑ) ์ ํ(์ฒดํฌ๋ฐ์ค), ์๋ ์ ๋ ฅ, ๋ฐฐ๋ฌ ์ฃผ์ยท์ฐ๋ฝ์ฒ ์ ๋ ฅ
- ์ฃผ๋ฌธ ์ ์ฅ: ์ฃผ๋ฌธ ์ ๋ณด๋ฅผ SQLite DB์ ์ ์ฅ(orders ํ ์ด๋ธ: id, customer_name, phone, address, pizza_type, size, toppings(JSON ๋๋ ์ผํ ๊ตฌ๋ถ), quantity, total_price, status, created_at)
- ์ฃผ๋ฌธ ๋ชฉ๋ก ํ์ด์ง(๊ด๋ฆฌ์์ฉ): ์ ์๋ ์ฃผ๋ฌธ์ ์๊ฐ ์์ผ๋ก ํ์, ๊ฐ ์ฃผ๋ฌธ์ ์ํ(์ ์/์ค๋น์ค/๋ฐฐ๋ฌ์ค/์๋ฃ) ํ์ ๋ฐ ์ํ ๋ณ๊ฒฝ ๋ฒํผ
- ์ฃผ๋ฌธ ์์ธ ํ์ด์ง: ๊ฐ๋ณ ์ฃผ๋ฌธ ๋ด์ญ ์์ธ ํ์ธ(๊ณ ๊ฐ ์ ๋ณด, ์ฃผ๋ฌธ ๋ด์ฉ, ์ด ๊ธ์ก, ์ฃผ๋ฌธ ์๊ฐ)
- ๋ฐ์ํ ๋์์ธ: ๋ชจ๋ฐ์ผ์์๋ ํธ๋ฆฌํ๊ฒ ์ฃผ๋ฌธํ ์ ์๋๋ก Tailwind CSS ๋๋ ์์ CSS๋ก ๋ฐ์ํ ๋ ์ด์์ ๊ตฌํ
- ์ ๋ ฅ ๊ฒ์ฆ: ๊ณ ๊ฐ ์ด๋ฆ, ์ ํ๋ฒํธ, ์ฃผ์ ํ์ ์ ๋ ฅ, ์ ํ๋ฒํธ ํ์ ๊ฒ์ฆ(์ ๊ท์), XSS ๋ฐฉ์ด๋ฅผ ์ํ ์ถ๋ ฅ ์ด์ค์ผ์ดํ
- CSRF ๋ฐฉ์ด: ์ฃผ๋ฌธ ํผ์ CSRF ํ ํฐ ์ถ๊ฐํ์ฌ ์์กฐ ์์ฒญ ๋ฐฉ์ด
์ ํ ์ถ๊ฐ ๊ธฐ๋ฅ(๋ณด๋์ค)
- ์ฃผ๋ฌธ ๊ฒ์ ๊ธฐ๋ฅ: ๊ณ ๊ฐ ์ด๋ฆ์ด๋ ์ ํ๋ฒํธ๋ก ์ฃผ๋ฌธ ๊ฒ์
- ์ฃผ๋ฌธ ํ์ด์ง๋ค์ด์ : ์ฃผ๋ฌธ ๋ชฉ๋ก์ด ๋ง์ ๋ ํ์ด์ง ๋จ์๋ก ํ์
- ์ฃผ๋ฌธ ์๋ฃ ์๋ฆผ: ์ฃผ๋ฌธ ์๋ฃ ์ ๊ฐ๋จํ ์๋ฆผ ๋ฉ์์ง ํ์(JavaScript)
- ์ฃผ๋ฌธ ํต๊ณ: ์ค๋/์ด๋ฒ ์ฃผ ์ฃผ๋ฌธ ๊ฑด์, ์ด ๋งค์ถ ๊ฐ๋จ ์ง๊ณ
- ์ด๋ฏธ์ง ์ ๋ก๋: ๊ด๋ฆฌ์๊ฐ ๋ฉ๋ด ์ด๋ฏธ์ง๋ฅผ ์ ๋ก๋ํ ์ ์๋ ๊ฐ๋จํ ํผ ์ถ๊ฐ
๊ธฐ์ ์คํ
- ๋ฐฑ์๋: PHP 8.3+ (Vanilla PHP, ํ๋ ์์ํฌ ์์)
- ๋ฐ์ดํฐ๋ฒ ์ด์ค: SQLite (PDO ์ฌ์ฉ)
- ํ๋ก ํธ์๋: HTML5, CSS3 (Tailwind CDN ๊ถ์ฅ), JavaScript (๋ฐ๋๋ผ ๋๋ ๊ฐ๋จํ Alpine.js)
- ์๋ฒ: PHP ๋ด์ฅ ์๋ฒ (
php -S localhost:8000)
ํ๋ก์ ํธ ๊ตฌ์กฐ ์์
pizza-shop-online-ordering/
โโโ index.php # ๋ฉ์ธ ํ์ด์ง(๋ฉ๋ด ๋ชฉ๋ก)
โโโ order.php # ์ฃผ๋ฌธ ํผ ํ์ด์ง
โโโ process_order.php # ์ฃผ๋ฌธ ์ฒ๋ฆฌ ๋ก์ง
โโโ admin.php # ๊ด๋ฆฌ์ ์ฃผ๋ฌธ ๋ชฉ๋ก
โโโ update_status.php # ์ฃผ๋ฌธ ์ํ ์
๋ฐ์ดํธ ์ฒ๋ฆฌ
โโโ order_detail.php # ์ฃผ๋ฌธ ์์ธ ํ์ด์ง
โโโ db.php # DB ์ฐ๊ฒฐ ๋ฐ ์ด๊ธฐํ
โโโ functions.php # ๊ณตํต ํจ์(escape, CSRF ํ ํฐ ์์ฑ/๊ฒ์ฆ ๋ฑ)
โโโ styles.css # ์ปค์คํ
์คํ์ผ
โโโ pizza.db # SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ์ผ
ํ์ต ๋ชฉํ
- PHP์์ ํผ ๋ฐ์ดํฐ ์ฒ๋ฆฌ(POST) ๋ฐ ๊ฒ์ฆ
- PDO๋ฅผ ํ์ฉํ SQLite CRUD ์์
- ์ธ์ ๊ธฐ๋ฐ CSRF ํ ํฐ ๊ตฌํ
- ๊ด๋ฆฌ์์ ๊ณ ๊ฐ ํ๋ฉด ๋ถ๋ฆฌ ์ค๊ณ
- ์ค์ฉ์ ์ธ ๋น์ฆ๋์ค ๋ก์ง ๊ตฌํ(๊ฐ๊ฒฉ ๊ณ์ฐ, ์ํ ๊ด๋ฆฌ)
์ ์ฝ ์กฐ๊ฑด
- โข PHP 8.3 ์ด์ ์ฌ์ฉ (Laravel, Symfony ๋ฑ ํ๋ ์์ํฌ ๊ธ์ง)
- โข SQLite + PDO๋ก ๋ฐ์ดํฐ ์ ์ฅ (MySQL ์ฌ์ฉ ๊ธ์ง)
- โข Composer ํจํค์ง ์ฌ์ฉ ๊ธ์ง (์์ PHP ์ฝ๋๋ก๋ง ๊ตฌํ)
- โข ํ๋ก ํธ์๋๋ HTML/CSS/JavaScript๋ง ์ฌ์ฉ (React, Vue ๋ฑ ๊ธ์ง)
- โข ๋น๋ ๋๊ตฌ(Webpack, Vite ๋ฑ) ์ฌ์ฉ ๊ธ์ง
- โข PHP ๋ด์ฅ ์๋ฒ๋ก ์คํ ๊ฐ๋ฅํด์ผ ํจ (`php -S localhost:8000`)
- โข ๋ชจ๋ ์ฌ์ฉ์ ์ ๋ ฅ์ htmlspecialchars()๋ก ์ด์ค์ผ์ดํ
- โข SQL ์ธ์ ์ ๋ฐฉ์ง๋ฅผ ์ํด prepared statement ์ฌ์ฉ
- โข CSRF ํ ํฐ์ ์ธ์ ์ ์ ์ฅํ๊ณ ํผ ์ ์ถ ์ ๊ฒ์ฆ
- โข ํ์ผ ์ ๋ก๋ ์ ํ์ฅ์ ๊ฒ์ฆ ๋ฐ ์์ ํ ๊ฒฝ๋ก์ ์ ์ฅ
ํ๋กฌํํธ ๋ ์ํผ
์๋ ํ๋กฌํํธ๋ฅผ ์์๋๋ก AI์๊ฒ ๋ณด๋ด๋ฉด ๋ฉ๋๋ค. ๋ณต์ฌ ๋ฒํผ์ ๋๋ฌ ๋ฐ๋ก ์ฌ์ฉํ์ธ์.
mkdir pizza-shop-online-ordering && cd pizza-shop-online-ordering
์ด ํด๋์์ ํ๋ก์ ํธ๋ฅผ ์์ํฉ๋๋ค.
ํผ์ ๋งค์ฅ ์จ๋ผ์ธ ์ฃผ๋ฌธ ํ๋ซํผ์ ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค์ด์ฃผ์ธ์.
**์๊ตฌ์ฌํญ:**
1. `db.php` ํ์ผ ์์ฑ:
- PDO๋ฅผ ์ฌ์ฉํ์ฌ SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค(`pizza.db`) ์ฐ๊ฒฐ
- `orders` ํ
์ด๋ธ ์๋ ์์ฑ (์์ผ๋ฉด):
- id (INTEGER PRIMARY KEY AUTOINCREMENT)
- customer_name (TEXT NOT NULL)
- phone (TEXT NOT NULL)
- address (TEXT NOT NULL)
- pizza_type (TEXT NOT NULL)
- size (TEXT NOT NULL)
- toppings (TEXT) -- JSON ํ์ ๋๋ ์ผํ ๊ตฌ๋ถ ๋ฌธ์์ด
- quantity (INTEGER NOT NULL)
- total_price (INTEGER NOT NULL)
- status (TEXT DEFAULT 'pending') -- pending/preparing/delivering/completed
- created_at (TEXT DEFAULT CURRENT_TIMESTAMP)
2. `functions.php` ํ์ผ ์์ฑ:
- `escape($str)`: htmlspecialchars() ๋ํผ ํจ์
- `generate_csrf_token()`: ์ธ์
์ CSRF ํ ํฐ ์์ฑ ๋ฐ ๋ฐํ
- `verify_csrf_token($token)`: ์ธ์
์ ํ ํฐ๊ณผ ๋น๊ตํ์ฌ ๊ฒ์ฆ
- `calculate_price($pizza_type, $size, $toppings, $quantity)`: ๊ฐ๊ฒฉ ๊ณ์ฐ ๋ก์ง
- ํผ์ ๊ธฐ๋ณธ ๊ฐ๊ฒฉ: ๋ง๋ฅด๊ฒ๋ฆฌํ 10000์, ํํผ๋ก๋ 12000์, ์ฝค๋น๋ค์ด์
14000์
- ํฌ๊ธฐ๋ณ ๋ฐฐ์จ: Small 1.0, Medium 1.3, Large 1.6
- ํ ํ ์ถ๊ฐ: ๊ฐ ํ ํ๋น 1000์
- ์ด ๊ฐ๊ฒฉ = (๊ธฐ๋ณธ ๊ฐ๊ฒฉ ร ํฌ๊ธฐ ๋ฐฐ์จ + ํ ํ ๊ฐ์ ร 1000์) ร ์๋
3. `index.php` ํ์ผ ์์ฑ:
- ๋ฉ๋ด ํ์ด์ง: ํผ์ ์ข
๋ฅ ๋ชฉ๋ก ํ์ (๋ง๋ฅด๊ฒ๋ฆฌํ, ํํผ๋ก๋, ์ฝค๋น๋ค์ด์
)
- ๊ฐ ํผ์๋ณ๋ก ์ด๋ฆ, ์ค๋ช
, ๊ธฐ๋ณธ ๊ฐ๊ฒฉ ํ์
- "์ฃผ๋ฌธํ๊ธฐ" ๋ฒํผ ํด๋ฆญ ์ `order.php?pizza=๋ง๋ฅด๊ฒ๋ฆฌํ` ํ์์ผ๋ก ์ด๋
- Tailwind CSS CDN ์ฌ์ฉํ์ฌ ๊น๋ํ ์นด๋ ๋ ์ด์์ ๊ตฌํ
4. PHP ๋ด์ฅ ์๋ฒ๋ก ์คํ ๊ฐ๋ฅํ๋๋ก ์ค์
**์ถ๋ ฅ ์์:**
- `db.php`์์ DB ์ฐ๊ฒฐ ์ฑ๊ณต ๋ฉ์์ง ๋๋ ํ
์ด๋ธ ์์ฑ ํ์ธ
- `index.php`๋ฅผ ๋ธ๋ผ์ฐ์ ์์ ์ด๋ฉด ํผ์ ๋ฉ๋ด ์นด๋ 3๊ฐ๊ฐ ๊น๋ํ๊ฒ ํ์
- ๊ฐ ์นด๋์ "์ฃผ๋ฌธํ๊ธฐ" ๋ฒํผ ํฌํจ
**์ฐธ๊ณ :**
- ์ธ์
์์์ ๊ฐ PHP ํ์ผ ์๋จ์์ `session_start()` ํธ์ถ
- ์๋ฌ ํ์๋ฅผ ์ํด ๊ฐ๋ฐ ์ค์๋ `error_reporting(E_ALL); ini_set('display_errors', 1);` ์ถ๊ฐ
๊ธฐ๋ ๊ฒฐ๊ณผ: ํ๋ก์ ํธ ํด๋๊ฐ ์์ฑ๋๊ณ , db.php๋ก SQLite ๋ฐ์ดํฐ๋ฒ ์ด์ค์ orders ํ ์ด๋ธ์ด ์๋ ์์ฑ๋ฉ๋๋ค. functions.php์ ๊ณตํต ํจ์๋ค์ด ์ ์๋๊ณ , index.php์์ ํผ์ ๋ฉ๋ด 3์ข ์ด ์นด๋ ํํ๋ก ํ์๋ฉ๋๋ค. ๊ฐ ์นด๋์๋ ํผ์ ์ด๋ฆ, ์ค๋ช , ๊ธฐ๋ณธ ๊ฐ๊ฒฉ, '์ฃผ๋ฌธํ๊ธฐ' ๋ฒํผ์ด ํฌํจ๋๋ฉฐ, Tailwind CSS๋ก ์คํ์ผ๋ง๋์ด ๊น๋ํ ๋ ์ด์์์ ๋ณด์ฌ์ค๋๋ค.
์ฃผ๋ฌธ ํผ ํ์ด์ง(`order.php`)๋ฅผ ๋ง๋ค์ด์ฃผ์ธ์. **์๊ตฌ์ฌํญ:** 1. GET ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ๋ `pizza` ๊ฐ์ ๋ฐ์ ํด๋น ํผ์ ์ด๋ฆ์ ํผ์ ์๋ ์ ๋ ฅ 2. ์ฃผ๋ฌธ ํผ ๊ตฌ์ฑ: - ํผ์ ์ข ๋ฅ: ์ ํ๋ ํผ์ ์ด๋ฆ ํ์ (์ฝ๊ธฐ ์ ์ฉ ๋๋ hidden input) - ํฌ๊ธฐ ์ ํ: ๋ผ๋์ค ๋ฒํผ (Small/Medium/Large) - ์ถ๊ฐ ํ ํ: ์ฒดํฌ๋ฐ์ค (์ฌ๋ฆฌ๋ธ, ๋ฒ์ฏ, ๋ฒ ์ด์ปจ, ๊ณ ์ถ, ํ์ธ์ ํ, ์น์ฆ ์ถ๊ฐ ๋ฑ 5~6๊ฐ) - ์๋: ์ซ์ ์ ๋ ฅ (๊ธฐ๋ณธ๊ฐ 1, ์ต์ 1) - ๊ณ ๊ฐ ์ด๋ฆ: ํ ์คํธ ์ ๋ ฅ (ํ์) - ์ ํ๋ฒํธ: ํ ์คํธ ์ ๋ ฅ (ํ์, placeholder: 010-1234-5678) - ๋ฐฐ๋ฌ ์ฃผ์: ํ ์คํธ ์ ๋ ฅ (ํ์) - CSRF ํ ํฐ: hidden input์ผ๋ก ํฌํจ - "์ฃผ๋ฌธํ๊ธฐ" ๋ฒํผ 3. ํผ ์ ์ถ ์ `process_order.php`๋ก POST ์ ์ก 4. JavaScript๋ก ์ค์๊ฐ ๊ฐ๊ฒฉ ๊ณ์ฐ ํ์: - ํฌ๊ธฐ, ํ ํ, ์๋ ๋ณ๊ฒฝ ์ ์์ ์ด ๊ฐ๊ฒฉ์ ํ๋ฉด์ ํ์ - `calculate_price()` ํจ์๋ฅผ JavaScript๋ก๋ ๊ตฌํ (๋๋ AJAX๋ก PHP ํจ์ ํธ์ถ) 5. ๋ฐ์ํ ๋์์ธ: ๋ชจ๋ฐ์ผ์์๋ ์ ๋ ฅํ๊ธฐ ํธํ๋๋ก ํผ ๋ ์ด์์ ์ต์ ํ **์ถ๋ ฅ ์์:** - `order.php?pizza=๋ง๋ฅด๊ฒ๋ฆฌํ`๋ก ์ ์ํ๋ฉด ์ฃผ๋ฌธ ํผ์ด ํ์ - ํผ์ ์ด๋ฆ์ด "๋ง๋ฅด๊ฒ๋ฆฌํ"๋ก ์๋ ์ค์ - ํฌ๊ธฐ, ํ ํ, ์๋ ๋ณ๊ฒฝ ์ ํ๋จ์ "์์ ๊ฐ๊ฒฉ: 15,000์" ํํ๋ก ์ค์๊ฐ ์ ๋ฐ์ดํธ - ๋ชจ๋ ํ๋๊ฐ ๊น๋ํ๊ฒ ์ ๋ ฌ๋๊ณ ๋ชจ๋ฐ์ผ์์๋ ์ ๋ณด์
๊ธฐ๋ ๊ฒฐ๊ณผ: order.php ํ์ด์ง๊ฐ ์์ฑ๋์ด GET ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ๋ ํผ์ ์ข ๋ฅ๋ฅผ ๋ฐ์ ํผ์ ํ์ํฉ๋๋ค. ๊ณ ๊ฐ์ ํฌ๊ธฐ(๋ผ๋์ค), ํ ํ(์ฒดํฌ๋ฐ์ค), ์๋์ ์ ํํ๊ณ ์ด๋ฆ/์ ํ๋ฒํธ/์ฃผ์๋ฅผ ์ ๋ ฅํ ์ ์์ต๋๋ค. JavaScript๋ก ์ค์๊ฐ ๊ฐ๊ฒฉ ๊ณ์ฐ์ด ๊ตฌํ๋์ด, ์ต์ ๋ณ๊ฒฝ ์ ์์ ์ด ๊ฐ๊ฒฉ์ด ํ๋ฉด์ ์ฆ์ ์ ๋ฐ์ดํธ๋ฉ๋๋ค. CSRF ํ ํฐ์ด hidden input์ผ๋ก ํฌํจ๋๋ฉฐ, ํผ์ process_order.php๋ก POST ์ ์ก๋ฉ๋๋ค.
์ฃผ๋ฌธ ์ฒ๋ฆฌ ๋ก์ง(`process_order.php`)์ ๊ตฌํํด์ฃผ์ธ์.
**์๊ตฌ์ฌํญ:**
1. POST ๋ฐ์ดํฐ ๊ฒ์ฆ:
- CSRF ํ ํฐ ๊ฒ์ฆ (`verify_csrf_token()` ์ฌ์ฉ)
- ๋ชจ๋ ํ์ ํ๋(customer_name, phone, address, pizza_type, size, quantity) ์กด์ฌ ํ์ธ
- ์ ํ๋ฒํธ ํ์ ๊ฒ์ฆ (์ ๊ท์: `/^010-\d{4}-\d{4}$/`)
- ์๋์ด 1 ์ด์์ธ์ง ํ์ธ
2. ํ ํ ๋ฐ์ดํฐ ์ฒ๋ฆฌ:
- ์ฒดํฌ๋ฐ์ค ๋ฐฐ์ด์ JSON ๋ฌธ์์ด๋ก ๋ณํํ์ฌ ์ ์ฅ (`json_encode()`)
3. ๊ฐ๊ฒฉ ๊ณ์ฐ:
- `calculate_price()` ํจ์ ํธ์ถํ์ฌ ์ด ๊ฐ๊ฒฉ ์ฐ์ถ
4. DB์ ์ฃผ๋ฌธ ์ ์ฅ:
- PDO prepared statement ์ฌ์ฉํ์ฌ orders ํ
์ด๋ธ์ INSERT
- status๋ ๊ธฐ๋ณธ๊ฐ 'pending'์ผ๋ก ์ค์
5. ์ ์ฅ ์ฑ๊ณต ์:
- ์ธ์
์ ์ฑ๊ณต ๋ฉ์์ง ์ ์ฅ (`$_SESSION['success'] = '์ฃผ๋ฌธ์ด ์ ์๋์์ต๋๋ค!'`)
- `index.php`๋ก ๋ฆฌ๋ค์ด๋ ํธ
6. ์คํจ ์:
- ์ธ์
์ ์๋ฌ ๋ฉ์์ง ์ ์ฅ
- `order.php`๋ก ๋ฆฌ๋ค์ด๋ ํธ (์
๋ ฅ๊ฐ ์ ์ง๋ฅผ ์ํด GET ํ๋ผ๋ฏธํฐ ํฌํจ)
**์ถ๋ ฅ ์์:**
- ์ฃผ๋ฌธ ์ฑ๊ณต ์: `index.php`๋ก ๋ฆฌ๋ค์ด๋ ํธ๋๋ฉฐ ์๋จ์ "์ฃผ๋ฌธ์ด ์ ์๋์์ต๋๋ค!" ๋ฉ์์ง ํ์
- ๊ฒ์ฆ ์คํจ ์: `order.php`๋ก ๋์๊ฐ๋ฉฐ "์ ํ๋ฒํธ ํ์์ด ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค" ๋ฑ์ ์๋ฌ ๋ฉ์์ง ํ์
- DB์ ์ฃผ๋ฌธ ๋ฐ์ดํฐ๊ฐ ์ ์ ์ ์ฅ๋จ (SQLite ํ์ผ ํ์ธ ๊ฐ๋ฅ)
๊ธฐ๋ ๊ฒฐ๊ณผ: process_order.php๊ฐ ์์ฑ๋์ด POST ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ฆํ๊ณ ์ฒ๋ฆฌํฉ๋๋ค. CSRF ํ ํฐ ๋ฐ ํ์ ํ๋๋ฅผ ๊ฒ์ฆํ๊ณ , ์ ํ๋ฒํธ ํ์์ ์ ๊ท์์ผ๋ก ์ฒดํฌํฉ๋๋ค. ํ ํ ๋ฐฐ์ด์ JSON ๋ฌธ์์ด๋ก ๋ณํ๋์ด DB์ ์ ์ฅ๋๋ฉฐ, calculate_price() ํจ์๋ก ์ด ๊ฐ๊ฒฉ์ด ๊ณ์ฐ๋ฉ๋๋ค. ์ฃผ๋ฌธ์ด ์ฑ๊ณต์ ์ผ๋ก ์ ์ฅ๋๋ฉด ์ธ์ ๋ฉ์์ง์ ํจ๊ป index.php๋ก ๋ฆฌ๋ค์ด๋ ํธํ๊ณ , ์คํจ ์ ์๋ฌ ๋ฉ์์ง์ ํจ๊ป order.php๋ก ๋์๊ฐ๋๋ค.
๊ด๋ฆฌ์ ์ฃผ๋ฌธ ๋ชฉ๋ก ํ์ด์ง(`admin.php`)๋ฅผ ๋ง๋ค์ด์ฃผ์ธ์. **์๊ตฌ์ฌํญ:** 1. DB์์ ๋ชจ๋ ์ฃผ๋ฌธ ์กฐํ: - orders ํ ์ด๋ธ์์ ์ต์ ์ฃผ๋ฌธ๋ถํฐ ์ ๋ ฌ (ORDER BY created_at DESC) - ์ฃผ๋ฌธ ID, ๊ณ ๊ฐ ์ด๋ฆ, ์ ํ๋ฒํธ, ํผ์ ์ข ๋ฅ, ํฌ๊ธฐ, ์๋, ์ด ๊ฐ๊ฒฉ, ์ํ, ์ฃผ๋ฌธ ์๊ฐ ํ์ 2. ํ ์ด๋ธ ํํ๋ก ์ฃผ๋ฌธ ๋ชฉ๋ก ํ์: - ๊ฐ ํ์ ์ฃผ๋ฌธ ์ ๋ณด ํ์ - ์ํ๋ณ๋ก ๋ฐฐ๊ฒฝ์ ๋ค๋ฅด๊ฒ ํ์ (pending: ๋ ธ๋, preparing: ํ๋, delivering: ์ด๋ก, completed: ํ์) - ๊ฐ ํ์ "์์ธ๋ณด๊ธฐ" ๋งํฌ (`order_detail.php?id=์ฃผ๋ฌธID`) - ๊ฐ ํ์ ์ํ ๋ณ๊ฒฝ ๋ฒํผ 4๊ฐ (์ ์/์ค๋น์ค/๋ฐฐ๋ฌ์ค/์๋ฃ) 3. ์ํ ๋ณ๊ฒฝ ๋ฒํผ: - ํด๋ฆญ ์ `update_status.php?id=์ฃผ๋ฌธID&status=์์ํ`๋ก ์ด๋ - CSRF ํ ํฐ ํฌํจ (GET ํ๋ผ๋ฏธํฐ ๋๋ ํผ POST) 4. ์ฃผ๋ฌธ์ด ์์ ๊ฒฝ์ฐ "์์ง ์ฃผ๋ฌธ์ด ์์ต๋๋ค" ๋ฉ์์ง ํ์ 5. ๊ฐ๋จํ ํต๊ณ ํ์ (์ ํ): - ์ค๋ ์ฃผ๋ฌธ ๊ฑด์, ์ด ๋งค์ถ (์ํ๊ฐ completed์ธ ์ฃผ๋ฌธ ํฉ๊ณ) **์ถ๋ ฅ ์์:** - `admin.php` ์ ์ ์ ์ฃผ๋ฌธ ๋ชฉ๋ก์ด ํ ์ด๋ธ ํํ๋ก ํ์ - ๊ฐ ์ฃผ๋ฌธ์ ์ํ๊ฐ ์์์ผ๋ก ๊ตฌ๋ถ๋์ด ํ๋์ ํ์ ๊ฐ๋ฅ - "์์ธ๋ณด๊ธฐ" ๋ฒํผ ํด๋ฆญ ์ ํด๋น ์ฃผ๋ฌธ์ ์์ธ ํ์ด์ง๋ก ์ด๋ - ์ํ ๋ณ๊ฒฝ ๋ฒํผ ํด๋ฆญ ์ ์ฆ์ ์ํ ์ ๋ฐ์ดํธ
๊ธฐ๋ ๊ฒฐ๊ณผ: admin.php ํ์ด์ง๊ฐ ์์ฑ๋์ด DB์์ ๋ชจ๋ ์ฃผ๋ฌธ์ ์ต์ ์์ผ๋ก ์กฐํํ๊ณ ํ ์ด๋ธ ํํ๋ก ํ์ํฉ๋๋ค. ๊ฐ ์ฃผ๋ฌธ์ ์ํ(pending/preparing/delivering/completed)์ ๋ฐ๋ผ ํ ๋ฐฐ๊ฒฝ์์ด ๋ค๋ฅด๊ฒ ํ์๋์ด ์๊ฐ์ ์ผ๋ก ๊ตฌ๋ถ๋ฉ๋๋ค. ๊ฐ ํ์๋ '์์ธ๋ณด๊ธฐ' ๋งํฌ์ ์ํ ๋ณ๊ฒฝ ๋ฒํผ 4๊ฐ๊ฐ ํฌํจ๋๋ฉฐ, ๋ฒํผ ํด๋ฆญ ์ update_status.php๋ก ์ด๋ํฉ๋๋ค. ์ฃผ๋ฌธ์ด ์์ผ๋ฉด ์๋ด ๋ฉ์์ง๊ฐ ํ์๋ฉ๋๋ค.
์ฃผ๋ฌธ ์ํ ์ ๋ฐ์ดํธ ์ฒ๋ฆฌ(`update_status.php`)์ ์ฃผ๋ฌธ ์์ธ ํ์ด์ง(`order_detail.php`)๋ฅผ ๊ตฌํํด์ฃผ์ธ์. **1. update_status.php ์๊ตฌ์ฌํญ:** - GET ํ๋ผ๋ฏธํฐ๋ก `id`(์ฃผ๋ฌธ ID)์ `status`(์ ์ํ) ๋ฐ๊ธฐ - CSRF ํ ํฐ ๊ฒ์ฆ (GET ๋ฐฉ์์ด๋ฏ๋ก Referer ์ฒดํฌ ๋๋ POST๋ก ๋ณ๊ฒฝ ๊ถ์ฅ) - status ๊ฐ์ด ์ ํจํ์ง ํ์ธ (pending, preparing, delivering, completed ์ค ํ๋) - PDO prepared statement๋ก ํด๋น ์ฃผ๋ฌธ์ status ํ๋ ์ ๋ฐ์ดํธ - ์ ๋ฐ์ดํธ ์ฑ๊ณต ์ ์ธ์ ๋ฉ์์ง ์ ์ฅ ํ `admin.php`๋ก ๋ฆฌ๋ค์ด๋ ํธ - ์คํจ ์ ์๋ฌ ๋ฉ์์ง์ ํจ๊ป ๋ฆฌ๋ค์ด๋ ํธ **2. order_detail.php ์๊ตฌ์ฌํญ:** - GET ํ๋ผ๋ฏธํฐ๋ก `id`(์ฃผ๋ฌธ ID) ๋ฐ๊ธฐ - DB์์ ํด๋น ์ฃผ๋ฌธ ์ ๋ณด ์กฐํ - ์ฃผ๋ฌธ ์์ธ ์ ๋ณด ํ์: - ์ฃผ๋ฌธ ๋ฒํธ, ์ฃผ๋ฌธ ์๊ฐ - ๊ณ ๊ฐ ์ ๋ณด: ์ด๋ฆ, ์ ํ๋ฒํธ, ๋ฐฐ๋ฌ ์ฃผ์ - ์ฃผ๋ฌธ ๋ด์ฉ: ํผ์ ์ข ๋ฅ, ํฌ๊ธฐ, ์๋ - ์ถ๊ฐ ํ ํ: JSON ๋์ฝ๋ฉํ์ฌ ๋ฆฌ์คํธ ํํ๋ก ํ์ - ์ด ๊ฐ๊ฒฉ - ํ์ฌ ์ํ (๋ฐฐ์ง ํํ๋ก ํ์) - "๋ชฉ๋ก์ผ๋ก ๋์๊ฐ๊ธฐ" ๋ฒํผ (`admin.php`๋ก ์ด๋) - ๋ฐ์ํ ๋์์ธ์ผ๋ก ๋ชจ๋ฐ์ผ์์๋ ๋ณด๊ธฐ ์ข๊ฒ **์ถ๋ ฅ ์์:** - `update_status.php?id=1&status=preparing` ํธ์ถ ์ ์ฃผ๋ฌธ 1๋ฒ์ ์ํ๊ฐ 'preparing'์ผ๋ก ๋ณ๊ฒฝ๋๊ณ admin.php๋ก ๋ฆฌ๋ค์ด๋ ํธ - `order_detail.php?id=1` ์ ์ ์ ์ฃผ๋ฌธ 1๋ฒ์ ๋ชจ๋ ์ ๋ณด๊ฐ ๊น๋ํ๊ฒ ํ์ - ํ ํ ๋ชฉ๋ก์ด "์ฌ๋ฆฌ๋ธ, ๋ฒ์ฏ, ๋ฒ ์ด์ปจ" ํํ๋ก ํ์ - ์ํ๊ฐ ๋ฐฐ์ง(badge) ์คํ์ผ๋ก ๊ฐ์กฐ ํ์
๊ธฐ๋ ๊ฒฐ๊ณผ: update_status.php๊ฐ ์์ฑ๋์ด GET ํ๋ผ๋ฏธํฐ๋ก ์ฃผ๋ฌธ ID์ ์ ์ํ๋ฅผ ๋ฐ์ ๊ฒ์ฆํ ๋ค DB๋ฅผ ์ ๋ฐ์ดํธํฉ๋๋ค. ์ํ ๊ฐ์ด ์ ํจํ์ง ํ์ธํ๊ณ PDO prepared statement๋ก ์์ ํ๊ฒ ์ ๋ฐ์ดํธํฉ๋๋ค. order_detail.php๋ ์ฃผ๋ฌธ ID๋ก ์์ธ ์ ๋ณด๋ฅผ ์กฐํํ์ฌ ๊ณ ๊ฐ ์ ๋ณด, ์ฃผ๋ฌธ ๋ด์ฉ, ํ ํ ๋ชฉ๋ก(JSON ๋์ฝ๋ฉ), ์ด ๊ฐ๊ฒฉ, ํ์ฌ ์ํ๋ฅผ ํ์ํฉ๋๋ค. ํ ํ์ ์ผํ๋ก ๊ตฌ๋ถ๋ ๋ฆฌ์คํธ๋ก ๋ณด๊ธฐ ์ข๊ฒ ์ถ๋ ฅ๋๋ฉฐ, ์ํ๋ ๋ฐฐ์ง ํํ๋ก ๊ฐ์กฐ๋ฉ๋๋ค.
ํ๋ก์ ํธ๋ฅผ ์์ฑํ๊ณ ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํด์ฃผ์ธ์. **์๊ตฌ์ฌํญ:** 1. `index.php`์ ์ธ์ ๋ฉ์์ง ํ์: - ์ฃผ๋ฌธ ์ฑ๊ณต/์คํจ ๋ฉ์์ง๋ฅผ ์๋จ์ ํ์ (์๋ฆผ ๋ฐ์ค ํํ) - ๋ฉ์์ง ํ์ ํ ์ธ์ ์์ ์ ๊ฑฐ (ํ ๋ฒ๋ง ํ์) 2. ์๋ฌ ์ฒ๋ฆฌ ๊ฐํ: - ์กด์ฌํ์ง ์๋ ์ฃผ๋ฌธ ID ์ ๊ทผ ์ 404 ๋ฉ์์ง ํ์ - DB ์ฐ๊ฒฐ ์คํจ ์ ์ฌ์ฉ์ ์นํ์ ์๋ฌ ๋ฉ์์ง 3. ๋ณด์ ๊ฐํ: - ๋ชจ๋ ์ถ๋ ฅ์ `escape()` ํจ์ ์ ์ฉ ํ์ธ - SQL ์ธ์ ์ ๋ฐฉ์ง๋ฅผ ์ํด ๋ชจ๋ ์ฟผ๋ฆฌ๊ฐ prepared statement์ธ์ง ํ์ธ - CSRF ํ ํฐ์ด ๋ชจ๋ ํผ์ ํฌํจ๋์๋์ง ํ์ธ 4. ์คํ์ผ ๊ฐ์ : - `styles.css` ํ์ผ ์์ฑ (๋๋ Tailwind ์ปค์คํฐ๋ง์ด์ง) - ๋ฒํผ ํธ๋ฒ ํจ๊ณผ, ์นด๋ ๊ทธ๋ฆผ์, ์ ๋๋ฉ์ด์ ๋ฑ ์ถ๊ฐ - ๋ชจ๋ฐ์ผ ๋ฐ์ํ ์ต์ข ์ ๊ฒ 5. README.md ์์ฑ: - ํ๋ก์ ํธ ์ค๋ช - ์คํ ๋ฐฉ๋ฒ (`php -S localhost:8000`) - ์ฃผ์ ๊ธฐ๋ฅ ๋ชฉ๋ก - ์คํฌ๋ฆฐ์ท (์ ํ) 6. ํ ์คํธ: - ์ฃผ๋ฌธ ์์ฑ, ๋ชฉ๋ก ์กฐํ, ์ํ ๋ณ๊ฒฝ, ์์ธ ๋ณด๊ธฐ ์ ์ฒด ํ๋ก์ฐ ํ ์คํธ - ๋ค์ํ ์ ๋ ฅ๊ฐ์ผ๋ก ๊ฒ์ฆ ๋ก์ง ํ ์คํธ (๋น ๊ฐ, ์๋ชป๋ ํ์ ๋ฑ) **์ถ๋ ฅ ์์:** - ์ฃผ๋ฌธ ์ฑ๊ณต ํ index.php ์๋จ์ ์ด๋ก์ ์๋ฆผ ๋ฐ์ค๋ก "์ฃผ๋ฌธ์ด ์ ์๋์์ต๋๋ค!" ํ์ - ์กด์ฌํ์ง ์๋ ์ฃผ๋ฌธ ID๋ก ์ ๊ทผ ์ "์ฃผ๋ฌธ์ ์ฐพ์ ์ ์์ต๋๋ค" ๋ฉ์์ง ํ์ - ๋ชจ๋ ํ์ด์ง๊ฐ ๊น๋ํ๊ณ ์ผ๊ด๋ ๋์์ธ์ผ๋ก ํต์ผ - README.md์ ํ๋ก์ ํธ ์ค๋ช ๊ณผ ์คํ ๋ฐฉ๋ฒ ๋ช ์ - ์ ์ฒด ๊ธฐ๋ฅ์ด ์ ์ ๋์ํ๋ฉฐ ๋ณด์ ์ทจ์ฝ์ ์์
๊ธฐ๋ ๊ฒฐ๊ณผ: ํ๋ก์ ํธ๊ฐ ์์ฑ๋์ด ๋ชจ๋ ๊ธฐ๋ฅ์ด ์ ์ ๋์ํฉ๋๋ค. index.php์ ์ธ์ ๋ฉ์์ง๊ฐ ์๋ฆผ ๋ฐ์ค๋ก ํ์๋๊ณ , ์๋ฌ ์ฒ๋ฆฌ๊ฐ ๊ฐํ๋์ด ์กด์ฌํ์ง ์๋ ์ฃผ๋ฌธ ์ ๊ทผ ์ ์๋ด ๋ฉ์์ง๊ฐ ๋ํ๋ฉ๋๋ค. ๋ชจ๋ ์ถ๋ ฅ์ด escape()๋ก ๋ณดํธ๋๊ณ , SQL ์ฟผ๋ฆฌ๋ prepared statement๋ก ์์ฑ๋์์ผ๋ฉฐ, CSRF ํ ํฐ์ด ๋ชจ๋ ํผ์ ํฌํจ๋์์ต๋๋ค. styles.css๋ก ๋ฒํผ ํธ๋ฒ ํจ๊ณผ์ ์นด๋ ๊ทธ๋ฆผ์๊ฐ ์ถ๊ฐ๋์ด UI๊ฐ ๊ฐ์ ๋๊ณ , README.md์ ํ๋ก์ ํธ ์ค๋ช ๊ณผ ์คํ ๋ฐฉ๋ฒ์ด ๋ฌธ์ํ๋ฉ๋๋ค. ์ ์ฒด ํ๋ก์ฐ ํ ์คํธ๋ฅผ ํตํด ์์ ์ฑ์ด ๊ฒ์ฆ๋ฉ๋๋ค.
์ ์ถ๋ ์ํ (0)
๋ก๊ทธ์ธ ํ ์ ์ถ์์ง ์ ์ถ๋ ์ํ์ด ์์ต๋๋ค. ์ฒซ ๋ฒ์งธ ๋์ ์๊ฐ ๋์ด๋ณด์ธ์!