PHP解析过滤后CSV数据不显示 英国手机号校验代码报错求助
英国手机号校验工具报错排查
我需要实现英国手机号有效性校验、归属运营商识别功能,校验完成后将结果按指定列导出为CSV文件,代码依赖splitbrain/php-cli PHP库。运行时出现如下错误:
我初步判断是代码布局问题导致报错,但无法定位具体问题点,完整代码如下:
<?php require 'C:\UniServerZ\www\bayne_07_09_2021-3\php-cli-master\autoload.php'; use splitbrain\phpcli\CLI; use splitbrain\phpcli\Options; use libphonenumber\PhoneNumberUtil; use libphonenumber\PhoneNumberToCarrierMapper; use libphonenumber\PhoneNumberType; use libphonenumber\NumberParseException; class mobileValidator extends CLI { // 覆盖默认日志级别 protected $logdefault = 'info'; // 注册选项和参数 protected function setup(Options $options) { $options->setHelp('该脚本从文件或直接传入参数获取手机号列表,校验是否为有效的英国手机号码'); $options->registerOption('file', '存储待校验手机号列表的文件路径', 'f', 'filename'); $options->registerOption('numbers', '直接传入的待校验手机号列表,多个号码用英文逗号分隔', 'n', 'numbers'); } /** * 主程序 * 运行时已完成参数解析 * @param Options $options * @return void */ protected function main(Options $options) { if (!$options->getOpt('file') && !$options->getOpt('numbers')) { $this->error('未传入待校验的文件或手机号,无法继续运行'); exit(); } $this->notice('校验流程已启动'); // 获取参数 $opNum = $options->getOpt('numbers'); $file = $options->getOpt('file'); $numbersFromOp = array(); $numbersFromFile = array(); // 设置英国国家代码 $countryCode = 44; // 设置区域代码:英国本土、根西岛、泽西岛、马恩岛 $regionCodes = array('GB', 'GG', 'JE', 'IM'); // 初始化校验依赖工具 $phoneUtil = PhoneNumberUtil::getInstance(); $carrierMapper = PhoneNumberToCarrierMapper::getInstance(); $phoneNumberType = PhoneNumberType::MOBILE; // 处理直接传入的手机号 if ($opNum) { $numbersFromOp = explode(',', $opNum); } // 处理文件中读取的手机号 if ($file) { if(file_exists($file)) { $numbersFromFile = file($file); } else { $this->warning("未找到指定文件 ".$file); if(!$opNum){ $this->critical('未找到指定文件且未传入手机号,无法继续运行'); exit(); } } } // 合并所有待校验手机号 $phoneNumbers = array_merge($numbersFromFile, $numbersFromOp); // 执行手机号校验 $validator = new validator($phoneNumbers, $phoneUtil, $carrierMapper, $phoneNumberType, $countryCode, $regionCodes); $results = $validator->validateNumbers(); // 导出结果为CSV文件 $this->generateCSV($results); $this->success('校验流程已完成'); } /** * 生成CSV文件 * 简单的CSV导出方法 * @param array $results * @return void */ protected function generateCSV(array $results){ // 创建写入文件 $fp = fopen('output/phone_numbers_'. date('d-M-Y-H-i').'.csv' , 'wb'); $headerRow = array ('手机号', '运营商', '校验状态'); $i = 0; foreach( $results as $fields ){ if( $i === 0 ){ fputcsv($fp, $headerRow ); // 首行写入表头 } fputcsv($fp, $fields); // 写入数据行 $i++; } fclose($fp); } /** * 重写日志方法 * 新增错误日志记录 * @param string $level * @param string $message * @param array $context */ public function log($level, $message, array $context = array()) { // 检查是否需要记录该级别日志 if (!isset($this->loglevel[$level])) return; /** @var string $prefix */ /** @var string $color */ /** @var resource $channel */ list($prefix, $color, $channel) = $this->loglevel[$level]; if (!$this->colors->isEnabled()) $prefix = ''; $message = $this->interpolate($message, $context); error_log($message); $this->colors->ptln($prefix . $message, $color, $channel); } } // 执行脚本 $cli = new mobileValidator(); $cli->run(); class validator { private $phoneNumbers; private $phoneUtil; private $carrierMapper; private $phoneNumberType; private $countryCode; private $regionCodes; private const VALID = '有效'; private const INVALID = '无效'; function __construct( array $phoneNumbers, PhoneNumberUtil $phoneUtil, PhoneNumberToCarrierMapper $carrierMapper, $phoneNumberType, $countryCode, $regionCodes) { $this->phoneNumbers = $phoneNumbers; $this->phoneUtil = $phoneUtil; $this->carrierMapper = $carrierMapper; $this->phoneNumberType = $phoneNumberType; $this->countryCode = $countryCode; $this->regionCodes = $regionCodes; } /** * 返回校验结果 * 遍历所有手机号校验是否为英国(含海峡群岛)有效手机号 * 返回结果数组格式:[手机号, 运营商, 校验状态] * @return array $results */ public function validateNumbers(){ $results = array(); // 遍历所有待校验手机号 foreach ($this->phoneNumbers as $phoneNumber) { $number = trim($phoneNumber); try { $phoneNumberObject = $this->phoneUtil->parse($number, 'GB'); } catch (NumberParseException $e) { $results[] = array($number,'', self::INVALID); error_log($e); continue; } // 获取国家代码和区域代码 $countryCode = $phoneNumberObject->getCountryCode(); $regionCode = $this->phoneUtil->getRegionCodeForNumber($phoneNumberObject); $valid = false; // 国家代码匹配、区域代码在指定范围内的号码才进行有效性校验 if($countryCode === $this->countryCode && in_array($regionCode, $this->regionCodes)){ $valid = $this->phoneUtil->isValidNumber($phoneNumberObject); } $type = $this->phoneUtil->getNumberType($phoneNumberObject); $carrier = ''; $validMobile = self::INVALID; // 号码有效且类型为手机号的,尝试获取运营商信息 if ($valid && $type === $this->phoneNumberType) { $carrier = $this->carrierMapper->getNameForNumber($phoneNumberObject, 'en'); if ($carrier === '') { $carrier = '未知'; } $validMobile = self::VALID; } // 写入结果数组 $results[] = array($number,$carrier, $validMobile); } return $results; } } ?>
内容的提问来源于stack exchange,提问作者Nathan Bayne
相关产品推荐
相关产品推荐

