[英]Best practice for PHP/MySQL Appointment/Booking system
我需要一些人為我目前正在從事的美發師的PHP / MySQL約會系統爭取“最佳實踐”。 希望我們可以一起清理一些事情,以避免以后再做該系統。 我一直在尋找SO和Google的一些教程,最佳實踐等,但是沒有找到適合我需求的東西。
基本信息
每天有多個理發師,每個理發師都有自己的日程安排,其中包含與客戶的約會。 與美發師連接的表包含他/她一周中有空的時間。
表:人
+----+------+-------+-----------+
| id | name | email | available |
+----+------+-------+-----------+
| 1 | John | i@a.c | Y |
| 2 | Sara | c@i.a | N |
+----+------+-------+-----------+
表格:次( 此表格有一個主鍵,我在下面的時間表中省略了它 )
+-----------+-------------+-----------+-----------+
| people_id | day_of_week | start | end |
+-----------+-------------+-----------+-----------+
| 1 | 1 | 08:00 | 12:00 |
| 1 | 1 | 12:30 | 17:00 |
| 1 | 3 | 09:00 | 12:00 |
| 1 | 4 | 10:30 | 16:00 |
| 1 | 5 | 09:00 | 17:00 |
| 1 | 6 | 09:00 | 12:00 |
| 2 | 1 | 09:00 | 12:00 |
| 2 | 2 | 09:00 | 12:00 |
| 2 | 3 | 09:00 | 12:00 |
+-----------+-------------+-----------+-----------+
如您所見,人與時間之間存在一對多的關系(顯然,因為一周中有7天)。 但是除此之外,還有一個選項可以在一天的小時之間添加休息時間(請參見people_id = 1,day_of_week = 1:08:00-12:00和12:30-17:00)。
此外,還有一個名為“ hairdress_types”的表,該表包含一個人可以進行的各種約會(例如,染發,剪發,洗臉等)。 該表包含此約會花費的時間(以分鍾為單位)。
最后,我有一個非常簡單的表appointments
:
id, people_id, types_id, sex, fullname, telephone, emailaddress, date_start, date_end
日期開始和日期結束將是MySQL中完整的DATETIME字段,這使得使用MySQL查詢函數進行計算變得更加容易。
因此,按照我的設置方式,前端用戶會在字段中選擇一個日期,從而觸發ajax / jquery函數,該函數查找在所選日期可用的所有美發師。 然后,用戶指定發型師(這不是強制性的:用戶還可以選擇“任何”發型師選項)以及他/她想要進行的約會類型。
提交第一份表格后,可以使用以下信息:
使用此信息,我將從選擇的美發師中選擇可用的日期, 或者循環所有可用的美發師及其可用的日期。
這是我的思想崩潰的地方! 因為什么是檢查可用日期的最佳方法。 我認為最好的方法是:
SELECT * FROM appointments WHERE ((date_start >= $start AND date_start <= ($start+$time)) OR (date_end > $start AND date_end <= ($start+$time)) AND people_id = 1
) 我面臨的更大的問題是要點2:我對這個查詢的想法真的發瘋了,這是我需要查找匹配特定時間范圍的約會的完整查詢嗎?
感謝您的閱讀和思考! :-)
約翰-星期一-12:00-17:00。 預約:-12:00-12:30-14:30-15:30
用戶想要預約需要2個小時的約會,在上面的示例中,我將檢查:
因此,使用10/15分鍾的“時間塊”可能是一個更好的選擇。 進行檢查:
這將在12:30和14:30之間找到可用的位置。
我一直在寫一些紙上的東西(一張桌子,上面有約會和可能要使用的空白點)。 我想出了以下幾點。 在以下情況下無法預約:
將上面的內容與people_id
一起查詢到約會表中將導致沒有行(=自由點)或一個/多個行,在這種情況下將采用該點。
我猜找到空位的最好方法是在數據庫中查詢X分鍾的塊,起始間隔為10分鍾。 該解決方案的缺點是,我每小時每小時要查詢6個查詢,每個美發師大約要查詢48個查詢...關於如何減少該查詢數量的任何想法?
最后,我去了一個為數據庫中的開始日期和結束日期生成時間戳的系統。 在檢查時,我在開始時增加了1秒,在結束時減去了1秒,以免約會重疊。
我最終做了什么
顯然,我不確定這是否是最佳做法,但這確實對我有用。 用戶首先選擇自己的性別和當天的偏好。 這將發送一個AJAX請求,以獲取可用的人員和各種約會類型(例如染發,剪發等)。
選擇所有設置(性別,日期,人員和類型)后,我將通過一些簡單的驗證開始:檢查日期,檢查date(“ N”)是否不是7(星期日)。 如果一切正常,則開始更重要的事情:
1)從數據庫中獲取約會類型,包括該類型所花費的總時間(30分鍾,45分鍾等)2)獲取可用的個人(當天完整的人員列表,或者僅包含一個人)選擇一個),包括其可用時間
然后,人員(或一個人)從他們自己的開始時間開始循環播放。 此時,我有一組數據,其中包含:
$duration (of the appointment type)
$startTime (starting time of the person selected in the loop)
$endTime (= $startTime + $duration)
$personStart (= starting time of the person)
$personEnd (= end time of the person)
讓我們看一下這個演示數據:
$duration = 30 min
$startTime = 9.00h
$endTime = 9.30h
$personStart = 9.00h
$personEnd = 12.00h
我在這里做的是:
while( $endTime < $personEnd )
{
// Check the spot for availability
$startTime = $endTime;
$endTime = $startTime + $duration;
}
顯然,在這種情況下已經簡化了。 因為當我檢查可用性時,現貨不是免費的。 我將$ startTime設置為等於找到的最新約會,然后從循環中的那里開始。
例:
I check for a free spot at 9.00 but the spot is not free because there's an appointment from 9.00 till 10.00, then 10.00 is returned and $startTime is set to 10.00h instead of 9.30h. This is done to keep the number of queries to a minimum since there can be quiet a lot.
檢查可用性功能
// Check Availability
public static function checkAvailability($start, $end, $ape_id)
{
// add one second to the start to avoid results showing up on the full hour
$start += 1;
// remove one second from the end to avoid results showing up on the full hour
$end -= 1;
// $start and $end are timestamps
$getAppointments = PRegistry::getObject('db')->query("SELECT * FROM appointments WHERE
((
app_start BETWEEN '".date("Y-m-d H:i:s", $start)."' AND '".date("Y-m-d H:i:s", $end)."'
OR
app_end BETWEEN '".date("Y-m-d H:i:s", $start)."' AND '".date("Y-m-d H:i:s", $end)."'
)
OR
(
app_start < '".date("Y-m-d H:i:s", $start)."' AND app_end > '".date("Y-m-d H:i:s", $end)."'
))
AND
ape_id = ".PRegistry::getObject('db')->escape($ape_id));
if(PRegistry::getObject('db')->num_rows($getAppointments) == 0) {
return true;
} else {
$end = 0;
foreach(PRegistry::getObject('db')->fetch_array(MYSQLI_ASSOC, $getAppointments, false) as $app) {
if($app['app_end'] > $end) {
$end = $app['app_end'];
}
}
return $end;
}
}
由於我將約會存儲為“發件人:10.00,直到:11.00”,因此我必須確保檢查從11:00:01到11:59:59的地點,因為否則將在結果中顯示11:00的約會。
在函數的末尾,如果找到約會,我將循環結果並返回最新的末尾。 這是我上面提到的循環中的下一個起點。
希望這對任何人都有幫助。 就像信息一樣: ape_id
是與其鏈接的“約會人員”的ID。
使用MySQL關鍵字BETWEEN
。
SELECT * FROM mytable WHERE mydate BETWEEN start_date AND end_date;
如果要查看現在和一天之間是否有約會,可以執行以下操作:
$enddate = strtotime('+1 day', time());
SELECT * FROM mytable WHERE mydate BETWEEN NOW() AND {$enddate};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.