CodeIgniter中Cannot access offset of type string错误的Webhook求助
CodeIgniter中Paystack Webhook TypeError问题解决
问题概述
处理Paystack支付Webhook时触发TypeError,错误信息:Cannot access offset of type string on string,错误位于PaystackWebhook.php第25行,需要提取JSON数据中data->authorization->receiver_bank_account_number字段。
错误信息
An uncaught Exception was encountered Type: TypeError Message: Cannot access offset of type string on string Filename: /home2/usefastp/public_html/app.usefastpay.ng/application/controllers/PaystackWebhook.php Line Number: 25
原代码
$data = @file_get_contents("php://input"); $event = json_decode($data, true); $result = array_change_key_case($event, CASE_LOWER); $e = ''; $dataarray = []; foreach ($event as $key => $value) { $dataarray[$key] = $value; $e = addslashes($value['id'][0]); }
接收的JSON数据
{ "event": "charge.success", "data": { "id": 3589405365, "domain": "live", "status": "success", "reference": "000013240229232839000039349865", "amount": 10000, "message": null, "gateway_response": "Approved", "paid_at": "2024-02-29T22:29:49.000Z", "created_at": "2024-02-29T22:29:49.000Z", "channel": "dedicated_nuban", "currency": "NGN", "ip_address": null, "metadata": { "receiver_account_number": "9311879633", "receiver_bank": "Wema Bank", "custom_fields": [ { "display_name": "Receiver Account", "variable_name": "receiver_account_number", "value": "9311879633" }, { "display_name": "Receiver Bank", "variable_name": "receiver_bank", "value": "Wema Bank" } ] }, "fees_breakdown": { "amount": "100", "formula": null, "type": "paystack" }, "log": null, "fees": 100, "fees_split": null, "authorization": { "authorization_code": "AUTH_pxt202a52t", "bin": "024XXX", "last4": "X758", "exp_month": "01", "exp_year": "2024", "channel": "dedicated_nuban", "card_type": "transfer", "bank": "Guaranty Trust Bank", "country_code": "NG", "brand": "Managed Account", "reusable": false, "signature": null, "account_name": null, "sender_country": "NG", "sender_bank": "Guaranty Trust Bank", "sender_bank_account_number": "XXXXXX9758", "sender_name": "NOSAKHARE ATEKHA ENDURANCE", "narration": "0241459758/9311879633/ICEBERGSYNERG/N", "receiver_bank_account_number": "9311879633", "receiver_bank": "Wema Bank" }, "customer": { "id": 160371778, "first_name": "Nosakhare", "last_name": "Nosakhare", "email": "zionnite@gmail.com", "customer_code": "CUS_kt7u83b7vi2ispc", "phone": "0908343", "metadata": {}, "risk_action": "default", "international_format_phone": null }, "plan": {}, "subaccount": {}, "split": {}, "order_id": null, "paidAt": "2024-02-29T22:29:49.000Z", "requested_amount": 10000, "pos_transaction_data": null, "source": null } }
问题原因
第25行$e = addslashes($value['id'][0]);存在两个核心问题:
foreach ($event as $key => $value)遍历的是JSON顶级键值对,第一个键是event,对应的值是字符串charge.success,此时尝试访问$value['id']相当于对字符串使用数组偏移,直接触发TypeError。- 原代码的遍历逻辑完全冗余,
$event已经是解析后的关联数组,无需重新存入dataarray。
修复方案
直接解析JSON后针对性提取目标字段,同时增加合法性校验避免意外错误:
// 获取Webhook输入,移除@错误屏蔽便于排查问题 $data = file_get_contents("php://input"); if (!$data) { http_response_code(400); exit("Invalid request"); } // 解析JSON为关联数组,校验解析结果 $event = json_decode($data, true); if (json_last_error() !== JSON_ERROR_NONE) { http_response_code(400); exit("Invalid JSON data"); } // 仅处理charge.success事件(可根据业务需求调整) if ($event['event'] !== 'charge.success') { http_response_code(200); exit("Event not handled"); } // 提取目标字段,同时检查层级是否存在 $receiverAccount = null; if (isset($event['data']['authorization']['receiver_bank_account_number'])) { $receiverAccount = addslashes($event['data']['authorization']['receiver_bank_account_number']); } // 后续业务逻辑:如存入数据库、触发通知等 // ...
说明
- 移除
@错误屏蔽,便于排查输入为空或JSON解析失败的问题。 - 增加JSON解析合法性校验,避免后续操作依赖无效数组。
- 直接通过数组层级访问目标字段,删除冗余遍历逻辑。
- 用
isset()检查字段是否存在,防止因字段缺失触发新错误。
内容的提问来源于stack exchange,提问作者Zionnite
相关产品推荐
相关产品推荐

