91精品久久香蕉国产线看观看_y111111国产精品久久婷婷_91精品在线观_日本一区二区三区在线播放

新聞
NEWS
網站想做在線預約功能?這段PHP代碼可以直接拿去改
  • 來源: 網站建設:www.www.1290blr.com
  • 時間:2026-06-18 10:45
  • 閱讀:192

在線預約系統是現代服務型網站常見的功能模塊,它允許訪客自助選擇時間、填寫需求并提交申請,從而替代傳統電話或人工登記流程。對于許多中小型項目而言,從頭開發一套完整的預約系統成本較高,而直接復用并改造一段穩定的PHP核心代碼,則是高效且經濟的方案。本文提供一套基礎的預約處理邏輯,涵蓋數據庫設計、表單提交、時段校驗、沖突檢測及結果返回等關鍵環節,并預留了充分的擴展接口,方便您根據實際業務場景進行調整。

一、功能定位與適用場景

本段代碼面向單資源、多時段的預約模型,例如:咨詢時段預約、工位使用申請、設備借用登記、課程試聽報名等。其核心能力包括:

  • 展示當前可預約的日期與時間片;

  • 限制每個時段的最大預約人數;

  • 防止同一用戶重復提交(基于Session或IP簡單限流);

  • 將預約記錄寫入數據庫,并返回成功或失敗的狀態信息;

  • 基礎的時間沖突判斷(例如:已滿時段不再接受新單)。

若您的業務涉及多資源并行(如多個房間、多位服務人員)、周期性規則(如每周一閉館)、或復雜的價格計算,本文末尾會給出改造方向,但主體代碼依然可作為底層邏輯的起點。

二、運行環境與準備工作

在部署代碼前,請確保服務器滿足以下最低要求:

  • PHP版本 ≥ 7.4(推薦8.0及以上,以支持更嚴格的類型聲明);

  • MySQL 5.7 或 MariaDB 10.3 以上,并開啟PDO擴展;

  • Web服務器(Apache/Nginx)正確配置URL重寫規則(非必須,但建議開啟);

  • 網站已建立全局數據庫連接對象($db),且字符集統一為utf8mb4。

您需要預先創建一張預約記錄表,推薦結構如下(可根據實際字段增減):

sql

復制

下載

CREATE?TABLE?`appointments`?(
??`id`?int(11)?NOT?NULL?AUTO_INCREMENT,
??`user_name`?varchar(50)?NOT?NULL,
??`user_phone`?varchar(20)?NOT?NULL,
??`user_email`?varchar(100)?DEFAULT?NULL,
??`appoint_date`?date?NOT?NULL,
??`appoint_time_slot`?tinyint(2)?NOT?NULL?COMMENT?'時段編號:1上午?2下午?3晚間等',
??`remark`?text?DEFAULT?NULL,
??`status`?tinyint(1)?DEFAULT?1?COMMENT?'1有效?0取消',
??`created_at`?datetime?NOT?NULL?DEFAULT?CURRENT_TIMESTAMP,
??`ip_address`?varchar(45)?DEFAULT?NULL,
??`session_id`?varchar(64)?DEFAULT?NULL,
??PRIMARY?KEY?(`id`),
??UNIQUE?KEY?`unique_booking`?(`appoint_date`,`appoint_time_slot`,`user_phone`),
??KEY?`idx_date_slot`?(`appoint_date`,`appoint_time_slot`))?ENGINE=InnoDB?DEFAULT?CHARSET=utf8mb4;

其中unique_booking唯一索引防止同一手機號在同一天同一時段重復預約,您也可以改為user_email或去掉該約束,改為業務層檢測。

同時,建議維護一個時段配置表(或直接寫在PHP常量中),便于前端下拉渲染:

sql

復制

下載

CREATE?TABLE?`time_slots`?(
??`slot_id`?tinyint(2)?NOT?NULL,
??`slot_name`?varchar(20)?NOT?NULL,
??`start_time`?time?NOT?NULL,
??`end_time`?time?NOT?NULL,
??`max_capacity`?smallint(4)?DEFAULT?5,
??`is_active`?tinyint(1)?DEFAULT?1,
??PRIMARY?KEY?(`slot_id`))?ENGINE=InnoDB?DEFAULT?CHARSET=utf8mb4;

初始化幾條示例數據:1-上午(09:00-12:00,容量5人),2-下午(14:00-17:00,容量5人),3-晚間(19:00-21:00,容量3人)。

三、核心PHP代碼結構(可直接復制修改)

以下為預約提交處理的入口文件?booking_submit.php,采用面向過程風格但清晰分層,方便封裝為類。

php

復制

下載

<?php//?開啟會話用于簡單防刷if?(session_status()?===?PHP_SESSION_NONE)?{
????session_start();}//?引入數據庫連接(請根據實際路徑調整)require_once?__DIR__?.?'/db_connect.php';//?設置響應格式為JSON(適用于前后端分離或Ajax提交)header('Content-Type:?application/json;?charset=utf-8');//?僅接受POST請求if?($_SERVER['REQUEST_METHOD']?!==?'POST')?{
????http_response_code(405);
????echo?json_encode(['code'?=>?405,?'msg'?=>?'僅支持POST提交']);
????exit;}//?---?1.?獲取并過濾輸入?---$name?=?trim($_POST['user_name']????'');$phone?=?trim($_POST['user_phone']????'');$email?=?isset($_POST['user_email'])???trim($_POST['user_email'])?:?null;$date?=?$_POST['appoint_date']????'';$slotId?=?(int)($_POST['slot_id']????0);$remark?=?isset($_POST['remark'])???trim($_POST['remark'])?:?'';//?基礎驗證:必填項$errors?=?[];if?(mb_strlen($name)?<?2?||?mb_strlen($name)?>?30)?{
????$errors[]?=?'姓名請填寫2~30個字符';}if?(!preg_match('/^1[3-9]\d{9}$/',?$phone))?{??//?簡單手機號格式(可替換為更寬松規則)
????$errors[]?=?'手機號格式不正確';}if?($email?&&?!filter_var($email,?FILTER_VALIDATE_EMAIL))?{
????$errors[]?=?'郵箱格式無效';}if?(!preg_match('/^\d{4}-\d{2}-\d{2}$/',?$date))?{
????$errors[]?=?'日期格式錯誤,請使用YYYY-MM-DD';}if?($slotId?<?1)?{
????$errors[]?=?'請選擇有效的時段';}//?額外日期校驗:不能早于今天(允許當天,可根據業務修改)$today?=?date('Y-m-d');if?($date?<?$today)?{
????$errors[]?=?'預約日期不能早于今天';}//?可選:限制最大提前天數(例如30天)$maxDate?=?date('Y-m-d',?strtotime('+30?days'));if?($date?>?$maxDate)?{
????$errors[]?=?'僅支持未來30天內的預約';}if?(!empty($errors))?{
????echo?json_encode(['code'?=>?422,?'msg'?=>?'參數驗證失敗',?'detail'?=>?$errors]);
????exit;}//?---?2.?防刷與重復提交檢查(輕量級)?---$sessionId?=?session_id();$clientIp?=?$_SERVER['REMOTE_ADDR']????'0.0.0.0';//?同一會話或IP?10秒內只能提交一次(避免暴力點擊)$lockKey?=?'booking_lock_'?.?md5($sessionId?.?$clientIp);if?(isset($_SESSION[$lockKey])?&&?(time()?-?$_SESSION[$lockKey]?<?10))?{
????echo?json_encode(['code'?=>?429,?'msg'?=>?'提交過于頻繁,請稍后再試']);
????exit;}$_SESSION[$lockKey]?=?time();//?---?3.?事務內執行核心業務?---try?{
????$db->beginTransaction();

????//?3.1?查詢時段配置,獲取容量和有效性
????$slotStmt?=?$db->prepare("SELECT?slot_id,?max_capacity,?is_active?FROM?time_slots?WHERE?slot_id?=??");
????$slotStmt->execute([$slotId]);
????$slot?=?$slotStmt->fetch(PDO::FETCH_ASSOC);
????if?(!$slot?||?$slot['is_active']?!=?1)?{
????????throw?new?Exception('所選時段當前不可用');
????}
????$maxCap?=?(int)$slot['max_capacity'];

????//?3.2?統計該日期+時段已有的有效預約數
????$countStmt?=?$db->prepare("SELECT?COUNT(*)?AS?booked?FROM?appointments?
???????????????????????????????WHERE?appoint_date?=???AND?appoint_time_slot?=???AND?status?=?1");
????$countStmt->execute([$date,?$slotId]);
????$row?=?$countStmt->fetch(PDO::FETCH_ASSOC);
????$bookedCount?=?(int)$row['booked'];

????if?($bookedCount?>=?$maxCap)?{
????????throw?new?Exception('該時段預約已滿,請選擇其他時間');
????}

????//?3.3?可選:同一手機號當天同時段是否已存在(與唯一索引互補,返回友好提示)
????$dupStmt?=?$db->prepare("SELECT?id?FROM?appointments?WHERE?appoint_date?=???AND?appoint_time_slot?=???AND?user_phone?=???AND?status?=?1");
????$dupStmt->execute([$date,?$slotId,?$phone]);
????if?($dupStmt->fetch())?{
????????throw?new?Exception('您已在該時段預約,請勿重復提交');
????}

????//?3.4?插入預約記錄
????$insertSql?=?"INSERT?INTO?appointments?
??????????????????(user_name,?user_phone,?user_email,?appoint_date,?appoint_time_slot,?remark,?ip_address,?session_id)?
??????????????????VALUES?(?,??,??,??,??,??,??,??)";
????$insertStmt?=?$db->prepare($insertSql);
????$result?=?$insertStmt->execute([
????????$name,
????????$phone,
????????$email,
????????$date,
????????$slotId,
????????$remark,
????????$clientIp,
????????$sessionId
????]);

????if?(!$result?||?$insertStmt->rowCount()?<?1)?{
????????throw?new?Exception('數據寫入失敗,請重試');
????}

????//?提交事務
????$db->commit();

????//?返回成功信息(包含預約ID,便于后續查詢)
????$newId?=?$db->lastInsertId();
????echo?json_encode([
????????'code'?=>?200,
????????'msg'?=>?'預約成功!',
????????'data'?=>?['appointment_id'?=>?$newId,?'date'?=>?$date,?'slot'?=>?$slotId]
????]);}?catch?(Exception?$e)?{
????$db->rollBack();
????//?記錄錯誤日志(建議寫入文件,不暴露給前端)
????error_log('[Booking?Error]?'?.?$e->getMessage()?.?'?|?IP:?'?.?$clientIp);
????echo?json_encode(['code'?=>?500,?'msg'?=>?$e->getMessage()]);
????exit;}

四、前端調用示例與數據獲取

在實際項目中,您需要配套一個前端預約表單頁面,通過Ajax將數據提交至上述接口。最簡單的HTML+JS片段如下(省略樣式):

html

復制

下載

運行

<form?id="bookingForm">
??<input?type="text"?name="user_name"?placeholder="您的姓名"?required>
??<input?type="tel"?name="user_phone"?placeholder="手機號"?required>
??<input?type="email"?name="user_email"?placeholder="郵箱(選填)">
??<input?type="date"?name="appoint_date"?min="<?=?date('Y-m-d')??>"?max="<?=?date('Y-m-d',?strtotime('+30?days'))??>">
??<select?name="slot_id">
????<option?value="1">上午?09:00-12:00</option>
????<option?value="2">下午?14:00-17:00</option>
????<option?value="3">晚間?19:00-21:00</option>
??</select>
??<textarea?name="remark"?placeholder="備注需求"></textarea>
??<button?type="submit">提交預約</button></form><script>document.getElementById('bookingForm').addEventListener('submit',?async?function(e)?{
??e.preventDefault();
??const?formData?=?new?FormData(this);
??const?resp?=?await?fetch('/booking_submit.php',?{?method:?'POST',?body:?formData?});
??const?result?=?await?resp.json();
??if?(result.code?===?200)?{
????alert(result.msg?+?'?預約編號:'?+?result.data.appointment_id);
??}?else?{
????alert('錯誤:'?+?(result.detail???result.detail.join('\n')?:?result.msg));
??}
});</script>

同時,您可能還需要提供可預約時段查詢接口(例如:根據日期返回剩余名額),避免用戶反復提交后才發現已滿。該接口只需復用上述統計邏輯,以GET方式返回JSON,此處不再贅述。

五、改造與擴展方向(針對復雜業務)

  1. 多資源并行預約
    在預約表中增加?resource_id?字段,并在統計容量時增加?AND resource_id = ??條件。前端需先選擇資源,再選時段。

  2. 周期性規則(如每周二、四開放)
    可在時段配置表中增加?weekday_mask(如二進制位表示周幾),在提交前校驗當前日期是否滿足規則。

  3. 支付或押金關聯
    在插入記錄后,可調用第三方支付接口生成預支付訂單,并將訂單號存入?payment_txn?字段,狀態改為“待支付”,支付成功后再變更為“有效”。

  4. 管理后臺審核
    增加?status?枚舉值(待審核、已確認、已取消),并在提交后發送郵件/短信通知管理員。此段代碼目前僅支持“有效/取消”兩種狀態,可按需擴充。

  5. 郵件或短信提醒
    在事務提交成功后,異步調用消息隊列或直接發送(注意性能),提醒用戶預約詳情。

  6. 時區與節假日處理
    若面向多時區用戶,統一存儲UTC時間,并在展示時轉換。節假日可維護一張閉館日期表,在驗證時排除。

  7. 防止并發超賣
    雖然使用了事務和唯一索引,但在極高并發下(如秒殺類預約),建議增加?SELECT ... FOR UPDATE?行鎖,或使用Redis原子遞減庫存。本代碼適用于中小流量(每分鐘幾十次提交)。

  8. 日志與監控
    在?catch?塊中,除了?error_log,可接入更完善的日志庫,記錄請求參數和堆棧,便于排查。

六、安全加固建議(必須執行)

  • SQL注入防護:本代碼已使用PDO預處理,但仍需確保所有動態字段均通過參數綁定,尤其注意?order by?或?表名?等無法綁定的位置。

  • XSS過濾:輸出到前端的用戶數據(如姓名、備注)需進行?htmlspecialchars?轉義,本接口返回JSON,前端渲染時需自行防范。

  • CSRF防護:建議在表單中植入一次性令牌(Token),并在服務端校驗。

  • 敏感數據脫敏:日志中不應記錄完整手機號或郵箱,可部分掩碼。

  • 限制請求頻率:除Session鎖外,建議在Nginx或防火墻層設置IP限流(例如每分鐘10次)。

  • HTTPS強制:全程使用加密傳輸,避免中間人截獲預約信息。

七、部署與測試要點

  1. 將代碼放置于網站目錄,確保?db_connect.php?正確配置數據庫賬號密碼。

  2. 使用測試工具(如Postman)模擬POST請求,驗證正常提交、重復提交、滿額、日期越界等場景。

  3. 觀察數據庫記錄,檢查字符集是否亂碼,時區是否一致。

  4. 開啟PHP錯誤日志,但關閉?display_errors,避免暴露路徑信息。

  5. 若使用緩存或CDN,注意動態接口不應被緩存(添加?Cache-Control: no-cache?響應頭)。

八、維護與迭代記錄

建議將本代碼納入版本管理,并在每次修改時記錄變更日志。例如,當您調整時段容量或新增字段時,同步更新數據表結構腳本。對于預約狀態的更新(如管理員取消),可另寫?booking_update.php,僅允許授權身份訪問。

結語

上述代碼提供了一套可運行、可修改的預約功能雛形,覆蓋了從數據驗證到事務寫入的完整鏈路。您完全可以根據自己的業務規則,替換驗證正則、調整容量邏輯、增加額外字段,或將其重構為面向對象的類結構。關鍵在于理解每一段代碼的職責,并依照實際需求進行裁剪。切記在修改后,對邊界條件進行充分測試,確保線上運行的穩定性。希望這段代碼能成為您構建在線預約系統的堅實基礎,讓您將更多精力投入到個性化體驗與運營優化之中。

分享 SHARE
在線咨詢
聯系電話

13463989299

主站蜘蛛池模板: 久久美女福利视频| 91精品在线播放| 国产精品日韩三级| 亚洲一区中文字幕| 国产精品网红直播| 久久精品国产视频| 青青久久av北条麻妃黑人| 91久久精品国产| 99国产视频在线| 蜜臀久久99精品久久久酒店新书| 亚洲精品蜜桃久久久久久| 国产不卡一区二区在线播放| 国产精品一区二区在线观看| 欧美中文字幕在线视频| 亚洲一二区在线| 亚洲一区二区免费| 亚洲一区二区三区免费观看| 亚洲欧洲精品一区| 在线视频不卡一区二区三区| 91国产丝袜在线放| 91成人国产在线观看| 91久久久久久久久久| 91精品视频在线看| 中文字幕在线亚洲精品| 亚洲精品女av网站| 日本视频一区二区在线观看| 日本精品一区二区三区视频| 日产精品高清视频免费| 日本一区视频在线观看| 欧美激情极品视频| 久久久在线视频| 狠狠色综合网站久久久久久久| 韩国国内大量揄拍精品视频| 国产精品亚洲综合天堂夜夜| www婷婷av久久久影片| 97精品视频在线| 色综合久久久久无码专区| 日本在线观看天堂男亚洲| 久久精品欧美| 国产精品国产亚洲伊人久久| 91精品国产亚洲|