PHP解析CSV文件时如何抛出自定义CsvParserException异常?
解决自定义
CsvParserException替换通用Exception的问题 首先,你需要先创建自己的自定义异常类,它必须继承PHP内置的Exception类,这样才能保留异常的核心功能(比如获取错误消息、发生错误的行号等)。
步骤1:定义CsvParserException类
在同一个app命名空间下添加这个类,你可以根据需求扩展它的功能,哪怕是空类也能正常工作,因为已经继承了Exception的所有特性:
<?php namespace app; class CsvParserException extends \Exception { // 这里可以添加CSV解析相关的自定义方法/属性,比如错误类型标记 // 不需要额外功能的话,空类完全够用 }
步骤2:修改CsvParser类的异常抛出逻辑
接下来,把代码中所有抛出\Exception的地方替换成自定义的CsvParserException,同时我帮你优化了验证逻辑——原来的for循环会重复验证同一行的字段多次,现在调整为每一行只验证一次,性能更优:
<?php namespace app; class CsvParser{ public function parse() { $row = 1; $flag = true; // 处理文件无法打开的情况,也抛出自定义异常 if (($handle = fopen("file.csv", "r")) === FALSE) { throw new CsvParserException("无法打开文件:file.csv"); } while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { $num = count($data); echo "<p> $num fields in line $row: <br /></p>"; echo $num; $row++; if($flag) { $flag = false; continue; } // 跳过首行 // 验证ID字段(第1列,索引0) if (!isset($data[0]) || !is_numeric($data[0])) { throw new CsvParserException("第{$row}行ID无效:必须是数字类型"); } // 验证第2列(索引1)字符串 if (!isset($data[1]) || !is_string($data[1])) { throw new CsvParserException("第{$row}行第2列无效:必须是字符串类型"); } // 验证第3列(索引2)字符串 if (!isset($data[2]) || !is_string($data[2])) { throw new CsvParserException("第{$row}行第3列无效:必须是字符串类型"); } // 验证日期字段(第4列,索引3) $date = strtotime($data[3] ?? ''); if ($date === false) { throw new CsvParserException("第{$row}行第4列日期无效:{$data[3]} 不是合法日期格式"); } // 验证第5列(索引4)的数字列表 if (!isset($data[4])) { throw new CsvParserException("第{$row}行第5列缺失:需要用|分隔的数字列表"); } $splitData = explode('|', $data[4]); foreach($splitData as $index => $value) { $trimmedValue = trim($value); if (!is_numeric($trimmedValue)) { throw new CsvParserException("第{$row}行第5列第{$index}项无效:'{$value}' 不是合法数字"); } } } fclose($handle); } }
步骤3:捕获并处理自定义异常
当你调用parse方法时,可以精准捕获CSV解析相关的错误,和其他类型的异常区分处理:
<?php use app\CsvParser; use app\CsvParserException; try { $parser = new CsvParser(); $parser->parse(); } catch (CsvParserException $e) { echo "CSV解析错误:" . $e->getMessage() . "(错误发生在代码第" . $e->getLine() . "行)"; } catch (\Exception $e) { // 处理非CSV解析相关的意外错误 echo "未知错误:" . $e->getMessage(); }
额外提示
- 自定义异常继承
Exception后,自动拥有getMessage()、getLine()、getFile()等调试方法,能帮你快速定位问题。 - 我在异常消息里加入了行号、列位置等具体信息,比通用提示更实用,方便你快速找到CSV文件中的损坏数据。
内容的提问来源于stack exchange,提问作者Ebenezer Anand Arapally
相关产品推荐
相关产品推荐

