Laravel生成客户日交易XML报表发送SMS时的数组转字符串错误
问题分析与解决方案
错误根源
你代码里的核心问题是做了无意义的数组→XML→数组转换:先把生成的$report数组转为XML,接着又解析回数组。这个过程中,当遇到空值(比如第二个客户的name/phone为空)时,SimpleXML可能会将空节点解析为数组类型,导致后续字符串拼接时触发「数组转字符串」错误。而且这一步完全没必要——你已经有了结构化的$report数组,直接用它循环发送SMS即可。
修复后的代码
public function dailyReport() { // 获取所有客户 $customers = DB::table('customers')->get(); // 生成客户日报表数组 $report = []; foreach ($customers as $customer) { // 用SQL聚合函数直接计算统计值,替代循环遍历,提升性能 $transactionStats = DB::table('transactions') ->where('customer_id', $customer->id) ->whereDate('created_at', Carbon::today()) ->selectRaw('SUM(amount) as sales, SUM(`return`) as returns, SUM(collect) as collections') ->first(); $sales = $transactionStats->sales ?? 0; $returns = $transactionStats->returns ?? 0; $collections = $transactionStats->collections ?? 0; // 过滤掉无有效信息、无交易的客户,避免发送无效SMS if (empty($customer->name) && empty($customer->phone) && $sales == 0 && $returns == 0 && $collections == 0) { continue; } $customerReport = [ 'name' => $customer->name ?? '客户', 'phone' => $customer->phone ?? '', 'sales' => $sales, 'returns' => $returns, 'collections' => $collections, 'total' => $sales - $returns - $collections, ]; $report[] = $customerReport; } // 直接遍历原始$report数组发送SMS,跳过冗余的XML转换步骤 foreach ($report as $record) { // 跳过无手机号的记录,避免发送失败 if (empty($record['phone'])) { continue; } $message = "Hello, {$record['name']} \n" . "日期: " . Carbon::today()->toDateString() . "\n今日消费: {$record['sales']} USD" . "\n今日退款: {$record['returns']} USD" . "\n今日付款: {$record['collections']} USD" . "\n当前余额: {$record['total']} USD" . "\n感谢您的使用!"; $xmlData = [ 'username' => env('GSM_USERNAME'), 'password' => env('GSM_PASSWORD'), 'header' => 'header', 'validity' => 2880, 'message' => [ 'gsm' => [ 'no' => $record['phone'], // 移除重复的手机号配置 ], 'msg' => [ '@cdata' => $message, ], ], ]; $options = ['rootElementName' => 'sms']; $xml = ArrayToXml::convert($xmlData, $options); $response = $this->sendSMS($xml); echo $response; } }
额外优化点
- 性能提升:用SQL聚合函数
SUM()直接计算交易统计,替代循环遍历所有交易记录,减少数据库查询次数和内存占用。 - 数据过滤:跳过无有效信息、无交易记录的客户,避免发送无效SMS。
- 容错处理:对可能为空的字段(如
name/phone)设置默认值,避免字符串拼接时出现异常。 - 修复笔误:移除了SMS请求中重复的手机号配置。
内容的提问来源于stack exchange,提问作者notdeveloper
相关产品推荐
相关产品推荐

