CodeIgniter导出MS Word文档:本地正常线上异常排查
本地XAMPP正常,线上服务器导出Word格式异常、图片丢失问题分析
问题背景
本地XAMPP环境下,CodeIgniter导出MS Word文档功能完全正常,但部署到线上服务器后,导出的Word文档格式混乱,且图片全部丢失。文本与图片数据均从数据库获取,相关代码如下:
- 正确/预期格式:文档排版规整,图片正常显示
- 错误/非预期格式:排版错乱,图片无法加载
相关代码
控制器代码
public function daily_newspaper_report() { $todayDate = ''; $startDate = $this->input->post('startDate'); $endDate = $this->input->post('endDate'); $response['data'] = $this->project_model->daily_newspaper_get($startDate, $endDate); if ($startDate == $endDate) { $todayDate = date_format(date_create($startDate), "d F Y"); } else { $todayDate = date_format(date_create($startDate), "d F Y") . ' to ' . date_format(date_create($endDate), "d F Y"); } $search_array = array("1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ":", ",", "to"); $replace_array = array("১", "২", "৩", "৪", "৫", "৬", "৭", "৮", "৯", "০", "জানুয়ারী", "ফেব্রুয়ারী", "মার্চ", "এপ্রিল", "মে", "জুন", "জুলাই", "আগষ্ট", "সেপ্টেম্বার", "অক্টোবার", "নভেম্বার", "ডিসেম্বার", ":", ",", "থেকে"); $response['publish_date'] = str_replace($search_array, $replace_array, $todayDate); $this->load->view('sadmin/daily_newspaper_report', $response); header("Content-Type: application/msword"); header("Content-disposition: attachment; filename=\"Articles on Agriculture & Allied Science_" . date_format(date_create($startDate), "d-M-Y") . " to " . date_format(date_create($endDate), "d-M-Y") . ".doc\""); }
模型代码
public function daily_newspaper_get($startDate, $endDate) { $sql = "SELECT documents.*, newspaper.newspaper_name AS 'newspaper', newspaper.logo FROM documents JOIN newspaper WHERE documents.newspaper_name=newspaper.id AND publish_date >= '$startDate' AND publish_date <= '$endDate' AND type_id = 7"; $query = $this->db->query($sql); return $query->result(); }
视图代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Daily Newspaper Report</title> <meta http-equiv=Content-Type content="text/html; charset=utf-8"> </head> <body style="font-size: 18.7px;"> <?php // Page Number EN - BN function Bengali_DTN($page_no) { $englDTN = array( "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "January", "February", "March", "April", "May", "June", "July", "August", "August", "September", "October", "November", "December", ":", ",", "to" ); $bangDTN = array( "১", "২", "৩", "৪", "৫", "৬", "৭", "৮", "৯", "০", "জানুয়ারী", "ফেব্রুয়ারী", "মার্চ", "এপ্রিল", "মে", "জুন", "জুলাই", "আগষ্ট", "সেপ্টেম্বার", "অক্টোবার", "নভেম্বার", "ডিসেম্বার", ":", ",", "থেকে" ); $converted = str_replace($englDTN, $bangDTN, $page_no); return $converted; } foreach ($data as $singleData) { ?> <h1 style="text-align: center"> <img height="50" width="150" src="<?php echo base_url() . $singleData->logo; ?>"></h1> <h4 style="text-align: center"><?php echo Bengali_DTN(date_format(date_create($singleData->publish_date), "d F Y")); ?>, পৃষ্ঠা-<?php $page_no = $singleData->accession_num; echo Bengali_DTN($page_no); ?></h4> <h1><b><?php echo $singleData->title; ?></b></h1> <?php if ($this->project_model->newspaper_image_get($singleData->id)) { $variable = $this->project_model->newspaper_image_get($singleData->id); ?> <?php foreach ($variable as $value) { ?> <img width="300" height="200" src="<?php echo base_url() . $value->imagePath; ?>" alt=""> <?php } } if (stristr($singleData->article_details, '<img src=')) { ?> <div><?php echo str_replace('<img src=', '<img width="300" height="200" src=', $singleData->article_details); ?></div> <?php } else { ?> <div><?php echo $singleData->article_details; ?></div> <?php } } ?> <h3 style="text-align: center;">Designed and Developed by <span style="font-weight: bold">Computer & GIS Unit</span></h3> </body> </html>
问题原因分析
HTTP头输出顺序错误:控制器中先加载视图输出内容,再设置Word的HTTP头。HTTP头必须在任何内容输出前发送,否则服务器会自动发送默认
Content-Type,导致Word无法正确解析HTML为规范文档,引发排版混乱。图片路径与权限问题:
- 线上服务器
base_url配置与本地不一致,导致生成的图片绝对路径无效,Word无法加载外部图片; - 图片文件所在目录权限不足(如未设置为
755),服务器无法读取图片资源。
- 线上服务器
字符编码兼容性:线上服务器PHP默认字符编码可能与本地不同,导致孟加拉语等非ASCII字符渲染异常,间接影响排版。
SQL注入风险:模型中直接拼接用户输入的日期参数到SQL语句,线上环境可能因特殊字符或安全策略导致查询结果异常,影响输出内容。
解决方案
1. 修正HTTP头输出顺序
将HTTP头设置移到视图加载之前,确保头信息优先发送:
public function daily_newspaper_report() { // ... 原有数据处理逻辑 ... // 先设置Word相关HTTP头 header("Content-Type: application/msword"); header("Content-disposition: attachment; filename=\"Articles on Agriculture & Allied Science_" . date_format(date_create($startDate), "d-M-Y") . " to " . date_format(date_create($endDate), "d-M-Y") . ".doc\""); // 再加载视图输出内容 $this->load->view('sadmin/daily_newspaper_report', $response); }
2. 修复图片路径与权限
- 检查
application/config/config.php中的base_url,确保线上环境指向正确域名/IP:$config['base_url'] = 'https://your-domain.com/'; - 将图片目录权限设为
755,文件权限设为644,确保服务器可读取。
3. 统一字符编码
- 在视图
<head>中明确编码:<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - 线上服务器
.htaccess添加编码配置:AddDefaultCharset UTF-8
4. 修复SQL注入漏洞
使用CodeIgniter查询构造器替代直接拼接SQL:
public function daily_newspaper_get($startDate, $endDate) { $this->db->select('documents.*, newspaper.newspaper_name AS newspaper, newspaper.logo'); $this->db->from('documents'); $this->db->join('newspaper', 'documents.newspaper_name = newspaper.id'); $this->db->where('publish_date >=', $startDate); $this->db->where('publish_date <=', $endDate); $this->db->where('type_id', 7); return $this->db->get()->result(); }
内容的提问来源于stack exchange,提问作者ZeroToOne
相关产品推荐
相关产品推荐

