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
相关产品推荐
相关产品推荐

