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

PHP+AJAX实现MySQL数据导入进度条不递增问题求助

问题解决:进度条无法逐步更新的修复方案

问题根源

  1. PHP会话阻塞:actionImport执行时会持有PHP会话锁,导致后续的actionCheckImport请求被阻塞,直到导入脚本完全执行完毕,前端无法实时获取进度。
  2. 导入记录未标记状态:导入完成后未更新TblNilaiTemp的status_sync字段,重复执行会导入相同数据,且进度统计逻辑不准确。
  3. 前端提示逻辑错误:每次检查进度都显示成功提示,不符合实际流程。

修改步骤

1. 后端actionImport修改

核心解决会话阻塞问题,同时优化导入逻辑:

public function actionImport()
{
    // 释放会话锁,允许其他请求正常访问
    session_write_close();
    
    // 开启实时输出缓冲(用于调试,可选)
    ob_implicit_flush(true);
    ob_end_flush();

    $model = TblNilaiTempEx::find()
        ->select([
            'tbl_nilai_temp.id as id_nilai_temp',
            'tbl_nilai_temp.tbl_krs_id',
            'tbl_nilai_temp.nilai_tugas',
            'tbl_nilai_temp.nilai_praktek',
            'tbl_nilai_temp.nilai_uts',
            'tbl_nilai_temp.nilai_uas',
            'tbl_nilai_temp.nilai_total',
            'tbl_nilai_temp.nilai_huruf',
            'tbl_nilai_temp.file_template_id'
        ])
        ->from('tbl_nilai_temp')
        ->leftJoin('tbl_krs','tbl_krs.id=tbl_nilai_temp.tbl_krs_id')
        ->leftJoin('tbl_jadwal','tbl_jadwal.id=tbl_krs.tbl_jadwal_id')
        ->leftJoin('tbl_matakuliah','tbl_matakuliah.id=tbl_jadwal.tbl_matakuliah_id')
        ->leftJoin('tbl_kurikulum','tbl_kurikulum.id=tbl_matakuliah.tbl_kurikulum_id')
        ->leftJoin('tbl_program_studi','tbl_program_studi.id=tbl_kurikulum.tbl_program_studi_id')
        ->andWhere('tbl_matakuliah.tbl_matakuliah_jenis_id in (2,3,4,5,6) and tbl_nilai_temp.status_sync=0')
        ->asArray()
        ->limit(5)
        ->all();

    foreach($model as $modelNilaiTemp) {
        $modelNilai = new TblNilaiEx;
        $modelNilai->tbl_krs_id = $modelNilaiTemp['tbl_krs_id'];
        $modelNilai->nilai_tugas = $modelNilaiTemp['nilai_tugas'];
        $modelNilai->nilai_praktek = $modelNilaiTemp['nilai_praktek'];
        $modelNilai->nilai_uts = $modelNilaiTemp['nilai_uts'];
        $modelNilai->nilai_uas = $modelNilaiTemp['nilai_uas'];
        $modelNilai->nilai_total = $modelNilaiTemp['nilai_total'];
        $modelNilai->nilai_huruf = $modelNilaiTemp['nilai_huruf'];
        $modelNilai->file_template_id = $modelNilaiTemp['file_template_id'];
        $modelNilai->tbl_nilai_rumus_id = 1;
        $modelNilai->status_eks = 4;
        $modelNilai->created_by = 1;
        $modelNilai->tbl_nilai_temp_id = $modelNilaiTemp['id_nilai_temp'];

        $result = $modelNilai->save();
        
        // 标记原记录为已同步,避免重复导入
        if ($result) {
            $nilaiTemp = TblNilaiTempEx::findOne($modelNilaiTemp['id_nilai_temp']);
            if ($nilaiTemp) {
                $nilaiTemp->status_sync = 1;
                $nilaiTemp->save(false); // 跳过验证提升效率
            }
            echo "success\n";
        } else {
            echo "Fail\n";
        }
        
        // 强制刷新输出缓冲
        flush();
        ob_flush();
        
        sleep(2); // 测试用,实际环境可移除
    }
}

2. 后端actionCheckImport修改

改为查询已同步的记录数,返回规范JSON格式:

public function actionCheckImport()
{
    // 统计已完成同步的记录数
    $count = TblNilaiTempEx::find()
        ->andWhere('status_sync=1')
        ->count();
    
    // 返回JSON响应
    Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    return ['count' => $count];
}

3. 前端JS修改

适配JSON响应,优化进度提示逻辑:

<?php
    $js = <<<JS
    
    var clear_timer;
    $('.sync-form').submit(function(event) {
        $('#message').html('');
        event.preventDefault();
        event.stopImmediatePropagation();
        
        // 总数据数建议从后端接口动态获取,此处暂用硬编码
        var total_data = 5;
        $('#total_data').text(total_data);
        
        clear_timer = setInterval(function() {
            check_imported_data(total_data);
        }, 1000);
        
        $.ajax({
            url:"/sync-nilai-ta/import",
            method:"POST",
            data: new FormData(this),
            contentType:false,
            cache:false,
            processData:false,
            beforeSend:function(){
                $('#sync-button').attr('disabled','disabled');
                $('#sync-button').val('Synchronizing');
            },
            complete:function(){
                $('#sync-button').val('Sync');
                $('#sync-button').removeAttr('disabled');
            }
        });
    });
    
    function check_imported_data(total_data)
    {
        $.ajax({
            url:"/sync-nilai-ta/check-import",
            dataType:"json",
            success:function(response)
            {
                var imported_count = response.count;
                var width = Math.round((imported_count / total_data) * 100);
                
                $('#process_data').text(imported_count);
                $('.progress-bar').css('width', width + '%').attr('aria-valuenow', width);
                
                // 仅当全部完成时显示成功提示
                if(imported_count >= total_data ) {
                    clearInterval(clear_timer);
                    $('#message').html('<div class="alert alert-success">Data Successfully Imported</div>');
                }
            }
        });
    }
   
JS;
$this->registerJs($js);
?>

关键说明

  • 会话锁释放:session_write_close()是解决进度阻塞的核心,它会释放PHP会话锁,让后续的进度检查请求能正常执行。
  • 状态标记:更新status_sync字段既避免重复导入,也让进度统计更准确。
  • 前端逻辑优化:修正提示时机,适配JSON响应格式,确保进度条逐步递增更新。

内容的提问来源于stack exchange,提问作者eniac05

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:55:18