使用CodeIgniter4与PhpSpreadsheet导出Excel,主机环境报ParseError求助
问题分析与解决方案
错误原因
报错出现在PhpSpreadsheet的Spreadsheet.php第269行,语法错误提示意外的|,核心原因是运行环境的PHP版本与当前安装的PhpSpreadsheet版本不兼容:
|是PHP 8.0及以上才支持的联合类型语法,如果主机实际运行的PHP版本低于8.0,就会触发这个错误;- 若主机确实是PHP 8.1.31,大概率是安装了要求更高PHP版本(如8.2+)的PhpSpreadsheet新版本(如3.x系列),导致语法不兼容。
另外你提供的模型代码存在SQL注入风险,直接将变量拼接进SQL语句,后续需要修正(下文会给出优化方案)。
解决步骤
1. 验证主机实际PHP版本
先确认主机Web环境实际运行的PHP版本:
创建一个test.php文件,内容如下:
<?php echo phpversion(); ?>
上传到主机并访问,查看输出的版本号:
- 如果版本低于8.0:联系主机商升级PHP到8.1及以上,或者降级PhpSpreadsheet到支持PHP 7.x的版本(如
1.28.x系列); - 如果版本确实是8.1.31:降级PhpSpreadsheet到兼容8.1的版本。
2. 调整PhpSpreadsheet版本
打开项目根目录的composer.json,找到phpoffice/phpspreadsheet的版本配置:
- 如果当前是
^3.0(要求PHP 8.2+),修改为^2.0(支持PHP 8.1-8.3); - 如果是其他更高版本,同样调整为
^2.0。
执行命令更新依赖:
composer update phpoffice/phpspreadsheet --no-dev
更新完成后重新部署代码到主机。
3. 修复模型代码的SQL注入问题
当前模型代码直接拼接变量到SQL中,存在注入风险,修改为参数绑定的安全写法:
public function datapmk($tr = null, $thn = null) { $db = \Config\Database::connect(); $builder = $db->table($this->table); // 替换为你的实际表名 $builder->select("lingkungan_nama, COUNT(DISTINCT(urut_rumah)) rmh, SUM(CASE WHEN pmk_id = 1 AND jk = 1 AND triwulan_id LIKE ? AND tahun LIKE ? THEN 1 ELSE 0 END) AS L_tidak, SUM(CASE WHEN pmk_id = 1 AND jk = 2 AND triwulan_id LIKE ? AND tahun LIKE ? THEN 1 ELSE 0 END) AS P_tidak, SUM(CASE WHEN pmk_id = 1 AND triwulan_id LIKE ? AND tahun LIKE ? THEN 1 ELSE 0 END) AS JLH_tidak"); // 构造模糊查询参数 $likeTr = "%{$tr}%"; $likeThn = "%{$thn}%"; // 参数顺序要与SELECT语句中的?一一对应 $builder->setBindings([$likeTr, $likeThn, $likeTr, $likeThn, $likeTr, $likeThn]); $builder->groupBy('lingkungan_nama'); $builder->orderBy('lingkungan_nama', 'ASC'); return $builder->get()->getResultArray(); }
内容的提问来源于stack exchange,提问作者Franky Moedak
相关产品推荐
相关产品推荐

