React Native支付成功后cartItems无法插入MySQL数据库求助
React Native支付成功后无法将购物车数据提交到PHP后端
问题现象
支付成功后,前端通过POST请求携带cartItems数据,但PHP端接收不到有效数据:$_POST输出为空数组,提示cartItems未定义,var_dump显示该变量为null,导致foreach循环无法执行,最终购物车数据未能插入MySQL数据库。
PHP端错误输出
Array ( ) Warning: Undefined array key "cartItems" in C:\xampp\htdocs\api\insertOrders.php on line 14 Warning: Undefined variable $_cartItems in C:\xampp\htdocs\api\insertOrders.php on line 16 NULL Warning: foreach() argument must be of type array|object, null given in C:\xampp\htdocs\api\insertOrders.php on line 23 Cart items inserted successfully!
相关代码
React Native前端支付页面代码
import { StyleSheet, Text, View, Image, TouchableOpacity, TextInput, Alert, } from "react-native"; import React, { useRef, useState } from "react"; import { cartTotalPriceSelector } from "../redux/selectors"; import { useDispatch, useSelector } from "react-redux"; import { color } from "react-native-reanimated"; import colors from "../config/colors"; import { clear } from "../redux/features/cart/cartSlice"; import { Paystack, paystackProps } from "react-native-paystack-webview"; const PaymentScreen = () => { const paystackWebViewRef = useRef(paystackProps.PayStackRef); const totalPrice = useSelector(cartTotalPriceSelector); const userId = useSelector((state) => state.user.userId); const email = useSelector((state) => state.email.email); const cart = useSelector((state) => state.cart); const cartItems = cart.map((cartItem) => { return { userId: userId, bookId: cartItem.bookId, name: cartItem.name, quantity: cartItem.quantity, price: cartItem.price, }; }); console.log("myItem",{ cartItems }); const insertOrders = () => { const url = "http://192.168.11.102:80/api/insertOrders.php"; const requestOptions = { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ cartItems }), }; console.log("Before fetch request"); fetch(url, requestOptions) .then((response) => { console.log("Response received"); return response.json(); }) .then((result) => { console.log("Result:", result); }) .catch((error) => { console.error("Error:", error); }); }; return ( <View style={styles.container}> <Paystack paystackKey="*****************************************" billingEmail={email} amount={totalPrice} onCancel={(e) => {}} onSuccess={(res) => { Alert.alert("Payment successful"); console.log("myItem",{ cartItems }); insertOrders(); }} ref={paystackWebViewRef} /> <Image style={styles.image} source={require("../assets/payment.jpg")} /> <View style={styles.totalContainer}> <Text style={styles.totalText}>₦{totalPrice}</Text> <TouchableOpacity style={styles.checkoutButton} onPress={() => paystackWebViewRef.current.startTransaction()}> <Text style={styles.checkoutButtonText}>Pay Now</Text> </TouchableOpacity> </View> </View> ); }; export default PaymentScreen; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: "center", alignItems: "center", }, checkoutButton: { backgroundColor: colors.orange, paddingHorizontal: 20, paddingVertical: 10, borderRadius: 20, elevation: 3, }, checkoutButtonText: { fontSize: 16, fontWeight: "bold", color: "#FFFFFF", }, image: { width: 200, height: 200, resizeMode: "cover", marginRight: 10, borderRadius: 11, }, totalContainer: { margin: 10, borderColor: colors.lightOrange, borderWidth: 3, borderRadius: 10, padding: 20, justifyContent: "center", alignItems: "center", }, totalText: { fontSize: 18, fontWeight: "bold", }, emailInput: { height: 40, width: "100%", borderColor: colors.lightOrange, borderWidth: 2, borderRadius: 5, paddingHorizontal: 10, marginTop: 10, }, errorText: { color: "red", marginTop: 5, }, });
前端控制台输出
myItem {"cartItems": [{"bookId": 18, "name": "The diary of a nigerian christian girl", "price": "2000.00", "quantity": 5, "userId": 31}, {"bookId": 21, "name": "A Time to Love", "price": "1500.00", "quantity": 3, "userId": 31}]}
PHP后端代码(insertOrders.php)
<?php include 'connection.php'; // Prepare the SQL statement for inserting into orderProducts table $insertOrderProductsStmt = $mysqli->prepare("INSERT INTO orders (userId, bookId, name, quantity, price) VALUES (?, ?, ?, ?,?)"); // $jsonPayload = file_get_contents('php://input'); // $data = json_decode($jsonPayload, true); // Get the cart items from the request print_r($_POST); // if(isset($_POST['cartItems'])){ $cartItems = $_POST['cartItems']; echo $cartItems; var_dump($_cartItems); // Start the transaction $mysqli->begin_transaction(); try { // Iterate over each cart item and execute the insert statement foreach ($cartItems as $cartItem) { $userId = $cartItem['userId']; $bookId = $cartItem['bookId']; $name = $cartItem['name']; $quantity = $cartItem['quantity']; $price = $cartItem['quantity'] * $cartItem['price']; // Bind the parameters and execute the statement $insertOrderProductsStmt->bind_param("iisii", $userId, $bookId, $name, $quantity, $price); $insertOrderProductsStmt->execute(); } // Commit the transaction $mysqli->commit(); // Close the prepared statement $insertOrderProductsStmt->close(); // Send a success response echo "Cart items inserted successfully!"; } catch (Exception $e) { // Rollback the transaction if an error occurred $mysqli->rollback(); // Close the prepared statement $insertOrderProductsStmt->close(); // Send an error response echo "Error: " . $e->getMessage(); } // Close the database mysqliection $mysqli->close(); // } // else{ // echo "an error occured"; // } ?>
解决方案
核心问题
前端发送的是JSON格式请求体,但PHP默认仅解析application/x-www-form-urlencoded格式数据到$_POST,因此无法通过$_POST['cartItems']获取数据。同时原代码存在变量名笔误($_cartItems应为$cartItems)。
修复步骤
- 修改PHP代码,读取JSON请求体
取消注释原本被注释的JSON解析代码,替换$_POST读取逻辑,并修复变量笔误:
<?php include 'connection.php'; // Prepare the SQL statement for inserting into orderProducts table $insertOrderProductsStmt = $mysqli->prepare("INSERT INTO orders (userId, bookId, name, quantity, price) VALUES (?, ?, ?, ?,?)"); // 读取JSON请求体并解析 $jsonPayload = file_get_contents('php://input'); $data = json_decode($jsonPayload, true); // 检查数据是否存在 if(!isset($data['cartItems']) || empty($data['cartItems'])){ echo json_encode(["status" => "error", "message" => "cartItems数据不存在"]); $mysqli->close(); exit; } $cartItems = $data['cartItems']; // Start the transaction $mysqli->begin_transaction(); try { // Iterate over each cart item and execute the insert statement foreach ($cartItems as $cartItem) { $userId = $cartItem['userId']; $bookId = $cartItem['bookId']; $name = $cartItem['name']; $quantity = $cartItem['quantity']; // 将字符串类型的price转为数值计算 $price = $cartItem['quantity'] * (float)$cartItem['price']; // Bind the parameters and execute the statement $insertOrderProductsStmt->bind_param("iisii", $userId, $bookId, $name, $quantity, $price); $insertOrderProductsStmt->execute(); } // Commit the transaction $mysqli->commit(); // Close the prepared statement $insertOrderProductsStmt->close(); // 返回JSON格式响应,适配前端解析 echo json_encode(["status" => "success", "message" => "Cart items inserted successfully!"]); } catch (Exception $e) { // Rollback the transaction if an error occurred $mysqli->rollback(); // Close the prepared statement $insertOrderProductsStmt->close(); // 返回JSON格式错误响应 echo json_encode(["status" => "error", "message" => $e->getMessage()]); } // Close the database connection $mysqli->close(); ?>
- 前端优化(可选)
适配后端返回的JSON格式响应,处理成功/失败场景:
fetch(url, requestOptions) .then((response) => { console.log("Response received"); if(!response.ok){ throw new Error('网络请求失败'); } return response.json(); }) .then((result) => { console.log("Result:", result); if(result.status === "success"){ Alert.alert("提交成功", result.message); // 可在此处清空购物车 // dispatch(clear()); } else { Alert.alert("提交失败", result.message); } }) .catch((error) => { console.error("Error:", error); Alert.alert("提交失败", error.message); });
额外注意点
- 前端传递的
price是字符串类型,PHP计算时需转为数值类型,避免计算错误。 - 后端统一返回JSON格式响应,确保前端
response.json()解析时不会报错。
内容的提问来源于stack exchange,提问作者Esther Iyege
相关产品推荐
相关产品推荐

