React Native与PHP图片上传处理及[object Object]报错排查
Alright, let's fix this image upload issue you're facing. The [object Object] error happens because you're trying to pass a FormData object directly as a URL query parameter—this is not how multipart form data works. Here's how to correct both your React Native and PHP code step by step:
When you append the img FormData object to your URL string, JavaScript converts the object to its default string representation: [object Object]. Worse, FormData is designed to be sent in the body of a POST request, not as part of the URL. Mixing URL parameters with FormData also breaks the multipart form data structure PHP expects to parse.
We'll move all parameters (text fields + image) into a single FormData instance and send it properly via POST:
// Initialize FormData const formData = new FormData(); // Add all text fields to FormData formData.append('f', 'createComplaint'); formData.append('otp_code', this.props.OTPInputText); formData.append('cp_phone_no', this.props.phno); formData.append('cp_relationship', this.props.Relationship); formData.append('cp_name', this.props.Name); formData.append('cp_email_id', this.props.email); formData.append('cp_address', this.props.address); formData.append('cp_complaint_type', this.props.complianttype); formData.append('cp_district', this.props.location); formData.append('cp_compliant_details', this.props.summary); formData.append('cp_resp_name', this.props.RName); formData.append('cp_resp_phone_no', this.props.Rphno); formData.append('cp_resp_email_id', this.props.Remail); formData.append('cd_name', this.state.CName); formData.append('cd_gender', this.state.cGender); formData.append('cd_age', this.state.cAge); formData.append('cd_indentification', this.state.cIDMark); // Add the image (match the field name to what PHP expects: 'cd_photo') formData.append('cd_photo', { filename: `child_photo_${Date.now()}.jpg`, // Unique filename to avoid conflicts uri: this.state.image.uri, type: 'image/jpeg', }); // Send the POST request fetch('your-action-url-here', { method: 'POST', // Note: Don't manually set Content-Type here! RN auto-generates the correct multipart boundary body: formData, }) .then(response => response.json()) .then(result => { console.log('Upload successful:', result); // Handle success logic here }) .catch(error => { console.error('Upload failed:', error); // Handle error logic here });
Key fixes here:
- All parameters live in FormData (no more messy URL string concatenation)
- Image field name matches
cd_photo(to align with your PHP code) - Removed manual
Content-Typeheader—React Native automatically adds the correct multipart boundary, which is critical for PHP to parse the form data.
Update your PHP to properly read FormData fields and handle file uploads, plus add error handling for robustness:
<?php // Only accept POST requests if ($_SERVER['REQUEST_METHOD'] !== 'POST') { echo json_encode(['status' => 'error', 'message' => 'Only POST requests are allowed']); exit; } // Access text fields from FormData (example values, adjust as needed) $otpCode = $_POST['otp_code'] ?? ''; $complainantName = $_POST['cp_name'] ?? ''; // Handle the uploaded image if (isset($_FILES['cd_photo']) && $_FILES['cd_photo']['error'] === UPLOAD_ERR_OK) { $uploadedFile = $_FILES['cd_photo']; $fileExtension = pathinfo($uploadedFile['name'], PATHINFO_EXTENSION); // Generate a unique filename to prevent overwrites $uniqueFilename = date('Ymdhis') . rand(0, 999) . '.' . strtolower($fileExtension); $uploadDirectory = '../child_photos/'; $fullUploadPath = $uploadDirectory . $uniqueFilename; // Create directory if it doesn't exist if (!is_dir($uploadDirectory)) { mkdir($uploadDirectory, 0755, true); } // Move the temp file to the final location if (move_uploaded_file($uploadedFile['tmp_name'], $fullUploadPath)) { echo json_encode([ 'status' => 'success', 'photo_filename' => $uniqueFilename, 'message' => 'Image uploaded successfully' ]); } else { echo json_encode(['status' => 'error', 'message' => 'Failed to move uploaded file']); } } else { // Handle file upload errors $errorMessage = match($_FILES['cd_photo']['error'] ?? 0) { UPLOAD_ERR_INI_SIZE => 'File exceeds PHP.ini size limit', UPLOAD_ERR_FORM_SIZE => 'File exceeds form size limit', UPLOAD_ERR_PARTIAL => 'File was only partially uploaded', UPLOAD_ERR_NO_FILE => 'No file was selected', default => 'Unknown upload error' }; echo json_encode(['status' => 'error', 'message' => $errorMessage]); } ?>
Improvements here:
- Checks for valid POST requests first
- Uses
$_POSTto access text fields from FormData - Adds directory creation logic (prevents failures if the
child_photosfolder doesn't exist) - Explicit error handling for different upload failure scenarios
- Returns JSON responses for easier parsing in React Native
- RN Image URI Handling: Android uses
content://URIs while iOS usesfile://. React Native's FormData usually handles this automatically, but if you run into issues, consider using a library likereact-native-fsto convert URIs to absolute file paths. - PHP Directory Permissions: Ensure the
../child_photos/directory has write permissions (set to755or775—avoid777for security). - File Validation: Add checks for allowed file types (e.g., jpg/png) and maximum file size to prevent malicious uploads:
$allowedExtensions = ['jpg', 'jpeg', 'png']; if (!in_array(strtolower($fileExtension), $allowedExtensions)) { echo json_encode(['status' => 'error', 'message' => 'Only JPG/PNG files are allowed']); exit; } $maxFileSize = 2 * 1024 * 1024; // 2MB limit if ($uploadedFile['size'] > $maxFileSize) { echo json_encode(['status' => 'error', 'message' => 'File size cannot exceed 2MB']); exit; }
内容的提问来源于stack exchange,提问作者Rsklanu

