PHP实现CSV多列排序并保存,解决表头排序问题
修复CSV排序时表头被排序及array_shift报错问题
问题根源
- 原代码收集
$binNumber和$category数组时,把表头行也一并加入,导致array_multisort会将表头数据纳入排序逻辑——即便后续用array_shift移除了表头行,排序依据的数组已经包含无效的表头数据,最终排序结果出错。 array_shift报错的核心原因:如果CSV文件只有表头一行,$rows数组仅含表头元素,执行array_shift后虽不会直接报错,但如果表头行的$row[3]或$row[1]不存在(比如表头列数不足),会触发数组索引越界;若文件为空,$rows本身是空数组,array_shift直接抛出错误。
修复后的代码
function wp_all_export_after_export($export_id, $exportObj) { // 检查All Export设置中是否启用"安全模式" $is_secure_export = PMXE_Plugin::getInstance()->getOption('secure'); if (!$is_secure_export) { $filepath = get_attached_file($exportObj->attch_id); } else { $filepath = wp_all_export_get_absolute_path($exportObj->options['filepath']); } $handle = fopen($filepath, 'r') or die('无法读取文件'); $binNumber = array(); $category = array(); $rows = array(); $header = array(); // 先单独读取表头 if (($header = fgetcsv($handle, 0, ',')) === false) { fclose($handle); return; // 空文件直接终止操作 } // 仅读取数据行,同时收集排序用的字段 while (false !== ($row = fgetcsv($handle, 0, ','))) { // 确保行数据包含所需列,避免索引越界报错 if (isset($row[3], $row[1])) { $binNumber[] = $row[3]; $category[] = $row[1]; $rows[] = $row; } } fclose($handle); // 仅当存在数据行时执行排序 if (!empty($rows)) { array_multisort($binNumber, SORT_ASC, $category, SORT_ASC, $rows); } // 将表头放回数组开头 array_unshift($rows, $header); // 覆盖写入原文件 $file = fopen($filepath, "w"); foreach ($rows as $line) { fputcsv($file, $line); } fclose($file); } add_action('pmxe_after_export', 'wp_all_export_after_export', 10, 2);
修复说明
- 分离表头与数据行:先单独读取表头,再循环处理数据行,确保排序用的数组仅包含有效数据,彻底避免表头参与排序。
- 增加异常防护:检查表头读取状态、数据行是否存在,避免空数组操作引发的报错;同时判断数据行是否包含目标列,防止数组索引越界。
- 优化排序触发逻辑:仅当存在数据行时执行排序,减少不必要的性能消耗,避免对空数组执行排序操作产生警告。
内容的提问来源于stack exchange,提问作者Gaby Bitar
相关产品推荐
相关产品推荐

