PHP实现FullCalendar加载数据库数据:数据不显示问题排查
问题:FullCalendar无法展示从数据库加载的日程数据
我通过FullCalendar API从数据库加载日程数据,已通过数组传递数据,控制台能看到数据,但日历上无法展示。以下是我的PHP后端及前端JavaScript代码,帮忙排查问题:
PHP后端代码
function get_schecdule($id2) { $sql = "SELECT * FROM `schedule` where `id`='0' or `id`='$id2'"; $result = myQuery($sql) or die("Query Failed."); $row = myFetchArray($result); $schedule_list = $row['schedule_list']; $events = json_decode($schedule_list, true); $arr = []; foreach ($events as $event) { $type = $event['type']; $id1 = $event['id']; if ($type === 'asset') { $sql_assets = "SELECT * FROM `assets` WHERE `assets_id`='$id1'"; $result_assets = myQuery($sql_assets); $row_assets = myFetchArray($result_assets); $name = $row_assets['name']; } elseif ($type === 'playlist') { $sql_playlists = "SELECT * FROM `playlist` WHERE `id`='$id1'"; $result_playlists = myQuery($sql_playlists); $row_playlists = myFetchArray($result_playlists); $name = $row_playlists['playlist_name']; } $start = str_replace(' ', 'T', $event['start_datetime']); $end = str_replace(' ', 'T', $event['end_datetime']); $r = ' { "title": "' . $name . '", "start": "' . $start . '", "end": "' . $end . '" } '; array_push($arr, $r); } return json_encode($arr); }
前端JavaScript代码
window.addEventListener('load', function() { calendar.destroy() start_load() let searchParams = new URLSearchParams(window.location.search); let id = searchParams.get('edit') $.ajax({ url: 'get_schecdule.php', method: 'POST', data: { id: id }, success: function(resp) { if (resp) { resp = JSON.parse(resp) var evt = []; if (resp.length > 0) { Object.keys(resp).map(k => { var obj = {}; obj['title'] = resp[k].title obj['start'] = resp[k].start obj['end'] = resp[k].end; evt.push(obj) }) console.log(evt) } calendar = new FullCalendar.Calendar(calendarEl, { headerToolbar: { left: 'prev,next today', center: 'title', right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth' }, initialDate: '<?php echo date('Y-m-d') ?>', weekNumbers: true, navLinks: true, editable: false, selectable: true, nowIndicator: true, dayMaxEvents: true, select: function(info) { var text = info.startStr.replace("T", " "); var text2 = info.endStr.replace("T", " "); document.getElementById("start-date").value = text.replace("+05:00", " "); document.getElementById("end-date").value = text2.replace("+05:00", " "); $('#exampleModal1').modal('show'); }, events: evt, eventClick: function(e, el) { var data = e.event.extendedProps; alert(data.data_id); uni_modal('View Schedule Details', 'view_schedule.php?id=' + data.data_id, 'mid-large') } }); }
问题排查与修复方案
1. PHP后端核心错误
你在循环中通过拼接字符串生成JSON片段,再将这些字符串存入数组后json_encode,最终返回的是字符串数组而非对象数组。前端解析后每个元素是字符串,无法直接作为FullCalendar的事件对象使用。
修正后的PHP代码:
function get_schecdule($id2) { $sql = "SELECT * FROM `schedule` where `id`='0' or `id`='$id2'"; $result = myQuery($sql) or die("Query Failed."); $row = myFetchArray($result); $schedule_list = $row['schedule_list']; $events = json_decode($schedule_list, true); $arr = []; foreach ($events as $event) { $type = $event['type']; $id1 = $event['id']; $name = ''; if ($type === 'asset') { $sql_assets = "SELECT * FROM `assets` WHERE `assets_id`='$id1'"; $result_assets = myQuery($sql_assets); $row_assets = myFetchArray($result_assets); $name = $row_assets['name']; } elseif ($type === 'playlist') { $sql_playlists = "SELECT * FROM `playlist` WHERE `id`='$id1'"; $result_playlists = myQuery($sql_playlists); $row_playlists = myFetchArray($result_playlists); $name = $row_playlists['playlist_name']; } $start = str_replace(' ', 'T', $event['start_datetime']); $end = str_replace(' ', 'T', $event['end_datetime']); // 直接生成关联数组,而非拼接JSON字符串 $r = [ "title" => $name, "start" => $start, "end" => $end ]; array_push($arr, $r); } return json_encode($arr); }
2. 前端核心错误
创建FullCalendar实例后,没有调用calendar.render()方法,导致日历无法渲染;同时对返回数据的处理冗余,且initialDate的PHP写法在纯JS环境中无法解析。
修正后的前端代码:
window.addEventListener('load', function() { if (calendar) calendar.destroy(); // 先判断calendar是否存在,避免报错 start_load(); let searchParams = new URLSearchParams(window.location.search); let id = searchParams.get('edit'); $.ajax({ url: 'get_schecdule.php', method: 'POST', data: { id: id }, success: function(resp) { if (!resp) return; let evt = JSON.parse(resp); calendar = new FullCalendar.Calendar(calendarEl, { headerToolbar: { left: 'prev,next today', center: 'title', right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth' }, initialDate: new Date().toISOString().split('T')[0], // 用JS直接获取当前日期 weekNumbers: true, navLinks: true, editable: false, selectable: true, nowIndicator: true, dayMaxEvents: true, select: function(info) { var text = info.startStr.replace("T", " "); var text2 = info.endStr.replace("T", " "); document.getElementById("start-date").value = text.replace("+05:00", " "); document.getElementById("end-date").value = text2.replace("+05:00", " "); $('#exampleModal1').modal('show'); }, events: evt, eventClick: function(e) { // 当前事件对象没有data_id属性,如需使用需在PHP后端添加到事件数组中 // var data = e.event.extendedProps; // alert(data.data_id); // uni_modal('View Schedule Details', 'view_schedule.php?id=' + data.data_id, 'mid-large') } }); // 关键:调用render方法渲染日历 calendar.render(); }, error: function(xhr) { console.error('获取日程数据失败:', xhr.responseText); end_load(); }, complete: function() { end_load(); } }); });
3. 其他优化点
- 添加AJAX错误处理与加载状态结束逻辑,提升代码健壮性
- 简化前端对返回数据的处理,后端返回的直接是可用的事件数组,无需重新循环包装
- 修正
eventClick的参数冗余问题
内容的提问来源于stack exchange,提问作者Yahya Imran
相关产品推荐
相关产品推荐

