Laravel 5.8存款功能报错:Response内容需为字符串或实现__toString()
问题排查与解决方案:Laravel 5.8存款功能触发Response内容类型错误
问题描述
在Laravel 5.8开发的系统中执行客户存款操作时频繁触发错误,此前功能正常。错误指向文件:C:\xampp\htdocs\mysystem\vendor\symfony\http-foundation\Response.php
错误核心代码片段:
public function setContent($content) { if (null !== $content && !\is_string($content) && !is_numeric($content) && !\is_callable([$content, '__toString'])) { throw new \UnexpectedValueException(sprintf('The Response content must be a string or object implementing __toString(), "%s" given.', \gettype($content))); } $this->content = (string) $content; return $this; }
错误原因分析
- 响应类型不合法:
saveDeposit方法中,当短信API请求失败时直接返回urlBuilder的结果。而curl_exec在请求失败时会返回布尔值false,Laravel无法将布尔值作为响应内容返回,触发Symfony的Response内容类型校验错误。 - 模型字段未初始化:
DepositTransaction的sms_notification_status是必填字符串字段,但代码仅在短信发送成功时赋值,失败时未设置会导致数据库报错。 - 金额类型未校验:请求参数
amount仅做了必填校验,未限制为数值类型,可能引发非数值运算问题。
解决方案
- 给
curl请求添加错误处理,确保urlBuilder始终返回字符串。 - 调整响应逻辑,使用Laravel标准响应格式(重定向+提示信息)替代直接返回API结果。
- 初始化模型必填字段,避免数据库报错。
- 加强请求参数校验,确保金额为数值类型。
代码修正示例
1. 修改urlBuilder方法(添加curl错误处理)
private function urlBuilder($number, $amount){ $username = ""; $password = ""; $from = ""; $to = $this->getPhoneNumber($number); $message = $this->getMessage($amount); $baseurl = "https://isms.wigalsolutions.com/ismsweb/sendmsg/"; $params = "username=".$username."&password=".$password."&from=".$from."&to=".$to."&message=".$message; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $baseurl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS,$params); $response = curl_exec($ch); // 处理curl请求失败的情况,确保返回字符串 if(curl_errno($ch)){ $response = "请求错误: " . curl_error($ch); } curl_close($ch); return $response; }
2. 修改saveDeposit方法(完善响应与模型逻辑)
public function saveDeposit(Request $request){ $this->validate($request,[ 'customer_id' => 'required|exists:customers', 'amount' => 'required|numeric' // 强制校验金额为数值类型 ]); $customer = Customer::where('customer_id',$request->input('customer_id'))->first(); $amount = (float)$request->input('amount'); // 转换为浮点型确保运算安全 $deposit_trans = new DepositTransaction(); $deposit_trans->customer_id = $customer->id; $deposit_trans->agent_id = Auth::user()->id; $deposit_trans->amount = $amount; $deposit_trans->sms_notification_status = "FAILED"; // 默认初始化字段 // 调用短信API $response = $this->urlBuilder($customer->phone_number, $amount); if(strpos($response, 'SUCCESS') !== false){ $deposit_trans->sms_notification_status = "SENT"; } $deposit_trans->save(); // 无论短信是否成功,都保存交易记录 // 更新客户余额 $customer->total_savings = $customer->total_savings + $amount; $customer->save(); // 更新临时存款记录 $agentName = Auth::user()->firstname.' '.Auth::user()->surname; $temp_deposit_sum_record = TemporaryDailyDeposit::where('agent', $agentName)->first(); if(!$temp_deposit_sum_record){ $temp_deposit_sum_record = new TemporaryDailyDeposit(); $temp_deposit_sum_record->agent = $agentName; $temp_deposit_sum_record->total_amount_recieved = $amount; }else{ $temp_deposit_sum_record->total_amount_recieved += $amount; } $temp_deposit_sum_record->save(); // 返回Laravel标准响应 if(strpos($response, 'SUCCESS') === false){ return redirect()->back()->with('error', '存款已完成,但短信通知发送失败:'.$response); } return redirect('/home')->with('success', '存款及短信通知均已完成'); }
内容的提问来源于stack exchange,提问作者pak Anyas
相关产品推荐
相关产品推荐

