You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
    }
}

额外优化点

  1. 性能提升:用SQL聚合函数SUM()直接计算交易统计,替代循环遍历所有交易记录,减少数据库查询次数和内存占用。
  2. 数据过滤:跳过无有效信息、无交易记录的客户,避免发送无效SMS。
  3. 容错处理:对可能为空的字段(如name/phone)设置默认值,避免字符串拼接时出现异常。
  4. 修复笔误:移除了SMS请求中重复的手机号配置。

内容的提问来源于stack exchange,提问作者notdeveloper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 15:40:04