You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 12:55:15