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

MySQL序列化数据导出CSV问题:unserialize函数失效求助

解决MySQL导出CSV时序列化字段解析失败问题

我能正常将MySQL数据导出为CSV,但fine_type列存储的是序列化数据,导出后仍显示序列化格式,尝试用PHP的unserialize()函数解析却没生效。

原CSV导出代码

<?php 
// Load the database configuration file 
include 'connect.php';
//$h=$_REQUEST['inspector_name'];
//$emp_numberd=$_REQUEST['datepicker'];


// Filter the excel data 
function filterData(&$str){ 
    $str = preg_replace("/\t/", "\\t", $str); 
    $str = preg_replace("/\r?\n/", "\\n", $str); 
    if(strstr($str, '\"')) $str = '\"' . str_replace('\"', '\"\"', $str) . '\"'; 
} 
 
// Excel file name for download 
$fileName = "members-data_" . date('d-m-Y') . ".xls"; 
 
// Column names 
$fields = array('اسم المحل','.الرخصة','اسم المفتش','Fine Date','Fine Details','المستفيد الحقيقي'); 
 
// Display column names as first row 
$excelData = implode("\t", array_values($fields)) . "\n"; 
 
// Fetch records from database 
$query = $link->query("SELECT  * FROM fine_controls WHERE str_to_date(fine_date, '%d-%m-%Y') between str_to_date('01-11-2022', '%d-%m-%Y') and str_to_date('10-03-2023', '%d-%m-%Y') order by id desc"); 

if($query->num_rows > 0){ 
    // Output each row of the data 
    while($row = $query->fetch_assoc()){
        
        $status = ($row['statuse'] == 1)?'Active':'Inactive'; 
        $lineData = array($row['shopname'],$row['license'],$row['inspector_name'],$row['fine_date'],$row['fine_type'],$row['beneficiary']); 
        array_walk($lineData, 'filterData'); 
        $excelData .= implode("\t", array_values($lineData)) . "\n"; 
    } 
}else{ 
    $excelData .= 'No records found...'. "\n"; 
} 
 
// Headers for download 
header("Content-Type: application/vnd.ms-excel"); 
header("Content-Disposition: attachment; filename=\"$fileName\""); 
 print chr(255) . chr(254).mb_convert_encoding($excelData, 'UTF-16LE', 'UTF-8');
// Render excel data 
//echo $excelData; 
 
exit;
?>

已尝试的修改代码

if($query->num_rows > 0){ 
        // Output each row of the data 
        while($row = $query->fetch_assoc()){
 $data=unserialize($row['fine_type']);
            
            $status = ($row['statuse'] == 1)?'Active':'Inactive'; 
            $lineData = array($row['shopname'],$row['license'],$row['inspector_name'],$data,$row['fine_type'],$row['beneficiary']); 
            array_walk($lineData, 'filterData'); 
            $excelData .= implode("\t", array_values($lineData)) . "\n"; 
        } 
    }else{ 
        $excelData .= 'No records found...'. "\n"; 
    } 

问题排查与修复方案

1. 验证序列化数据有效性

先单独测试数据库中取出的fine_type值是否能被解析:

// 从数据库取一条记录的fine_type值
$testData = '数据库中的序列化字符串';
var_dump(unserialize($testData));

如果返回false,说明数据已损坏(比如存储时被截断、编码转换错误),需要修复数据库中的数据,或者在解析失败时保留原数据。

2. 处理编码不一致问题

如果序列化数据包含非ASCII字符(如阿拉伯语),可能因为数据库编码与PHP环境编码不一致导致解析失败,尝试转码后再解析:

// 假设数据库编码是UTF-8,根据实际情况调整
$serializedData = mb_convert_encoding($row['fine_type'], 'UTF-8', 'UTF-8');
$data = unserialize($serializedData);

3. 转换解析结果为可读格式

unserialize()返回的可能是数组或对象,直接放入CSV会显示为Array或Object,需要转为字符串:

  • 数组转为逗号分隔的字符串:implode(', ', $data)
  • 对象转为JSON字符串(保留结构):json_encode($data, JSON_UNESCAPED_UNICODE)
  • 解析失败时保留原数据:$data = $data === false ? $row['fine_type'] : $data

4. 修复后的完整循环代码

if($query->num_rows > 0){ 
    while($row = $query->fetch_assoc()){
        // 解析序列化字段
        $fineType = $row['fine_type'];
        $decodedData = unserialize($fineType);
        
        // 处理解析结果
        if($decodedData === false){
            // 解析失败,保留原序列化字符串
            $displayData = $fineType;
        } elseif(is_array($decodedData)){
            // 数组转为逗号分隔的可读字符串
            $displayData = implode(', ', $decodedData);
        } elseif(is_object($decodedData)){
            // 对象转为JSON字符串(避免显示为Object)
            $displayData = json_encode($decodedData, JSON_UNESCAPED_UNICODE);
        } else {
            // 其他类型直接转为字符串
            $displayData = strval($decodedData);
        }
        
        $lineData = array(
            $row['shopname'],
            $row['license'],
            $row['inspector_name'],
            $row['fine_date'],
            $displayData,
            $row['beneficiary']
        ); 
        array_walk($lineData, 'filterData'); 
        $excelData .= implode("\t", array_values($lineData)) . "\n"; 
    } 
}else{ 
    $excelData .= 'No records found...'. "\n"; 
}

内容的提问来源于stack exchange,提问作者Mazhar Iqbal Rana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 02:07:19