Storing Image with PHP

  1. Front-End (Client-Side):

    • I have a web application, built using JavaScript and a front-end framework: React.

    • Users have the ability to choose a profile picture file through a file input field on the website.

  2. Uploading Profile Picture (Client to Server):

    • I am sending the selected profile picture file from the client-side to a server-side script using a POST request.

    • The client-side code constructs a FormData object and appends the selected file and relevant data (e.g., username) to it.

  3. Server-Side Script (PHP):

    • On the server, I have a PHP script (storePFP.php) that handles the incoming POST request.

    • The PHP script processes the received data, including the username and the profile picture file, using the $_FILES and file_get_contents('php://input') methods.

    • The server script checks if the user exists in the database and, if found, generates a unique filename for the profile picture, moves the uploaded file to a designated directory, and records the picture details in the database.

  4. Debugging and Logging:

    • I’ve implemented error logging and debugging statements in my PHP script to log information such as received JSON data, headers, files, and query results.

    • I was checking for potential issues, such as invalid request data, undefined variables, or database query failures.

  5. Issues and Questions:

    • I’ve encountered some issues related to undefined variables ($uploadDirectory, $result) and database query results not being as expected.

    • I’ve explored and provided debug information through error logs.

  6. Alternative Storage:

    • I’m considering whether it’s possible to store the profile pictures on another public API.
const handleProfilePictureUpload = async (e) => {
    e.preventDefault();
    const fileInput = document.querySelector('#fileInput');
    const file = fileInput.files[0];

    // Check if a file was selected
    if (!file) {
      setMessage('Please select a profile picture to upload.');
      return;
    }

    // Check if the file type is supported (gif, png, or jpg)
    const allowedFileTypes = ['image/gif', 'image/png', 'image/jpeg', 'image/jpg'];
    if (!allowedFileTypes.includes(file.type)) {
      setMessage('Invalid file type. Please select a GIF, PNG, JPG or JPEG image.');
      return;
    }

    // Set the URL of the API endpoint
    const url = 'http://localhost:80/storePFP.php';

    try {
      // Create a FormData object to send the file
      const formData = new FormData();
      formData.append('username', user.username);
      formData.append('profilePicture', file);
      console.log(formData.get('profilePicture'));

      // Call the API to upload the profile picture
      const response = await fetch(url, {
        method: 'POST',
        body: formData,
        
      });
    
      const data = await response.json();
      console.log(data);

      // Check if the response is successful
      if (response.ok) {
        // Set the message based on the response data
        setMessage(data.message);
      } else {
        // Set the error message from the response
        setMessage(data.message || 'An error occurred while uploading the profile picture.');
      }
    } catch (error) {
      // Log and display a generic error message if an exception occurs during the API call
      console.error('Error uploading profile picture:', error);
      setMessage('An error occurred while uploading the profile picture.');
    }
  };

// HTML returned code
    <form onSubmit={handleProfilePictureUpload}>
      <label>
        Select Profile Picture:
        <input
          type="file"
          accept="image/gif, image/png, image/jpeg, image/jpg"
          id="fileInput"
          name="ProfilePicture"
        />
      </label>
      <button type="submit">Upload</button>
    </form>
<?php
header("Access-Control-Allow-Origin: http://localhost:3000");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Allow-Headers: Content-Type");
$json_data = file_get_contents('php://input');
$data = json_decode($json_data, true);

$conn = new mysqli($servername, $username, $password, $dbname);

if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

$uploadDirectory = __DIR__ . "/profile_pictures/";


if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (isset($data['username']) && isset($_FILES['profilePicture'])) {
        $username = $data['username'];
        $profilePicture = $_FILES['profilePicture'];
        
        // Check if the user exists
        $stmt = $conn->prepare("SELECT * FROM users WHERE username = ?");
    

        $stmt->bind_param("s", $username);
        $stmt->execute();
        $result = $stmt->get_result();
        

        if ($result->num_rows > 0) {
            // Generate a unique filename for the profile picture
            $filename = uniqid() . '_' . $profilePicture['name'];
            $destination = $uploadDirectory . $filename;

            // Move the uploaded file to the specified destination
            if (move_uploaded_file($profilePicture['tmp_name'], $destination)) {
                // Insert the picture details into the "pictures" table
                $insertStmt = $conn->prepare("INSERT INTO profile_pictures (filename, filetype, userid) VALUES (?, ?, ?)");
                $filetype = pathinfo($destination, PATHINFO_EXTENSION);
                $userid = $result->fetch_assoc()['id'];
                $insertStmt->bind_param("ssi", $filename, $filetype, $userid);
                $insertStmt->execute();

                if ($insertStmt->affected_rows > 0) {
                    $response = [
                        'success' => true,
                        'message' => 'Profile picture uploaded and saved successfully',
                    ];
                } else {
                    // Delete the uploaded file if the database insertion fails
                    unlink($destination);

                    $response = [
                        'success' => false,
                        'message' => 'Failed to save profile picture',
                    ];
                }

                $insertStmt->close();
            } 
        } 
    } else {
        $response = [
            'success' => false,
            'message' => 'Invalid request data',
        ];
    }
} else {
    $response = [
        'success' => false,
        'message' => 'Invalid request method',
    ];
}

$conn->close();
header('Content-Type: application/json');
echo json_encode($response);
?>

{“success”:false,”message”:”Invalid request data”}

Yes, I checked if the paths (destinationPath) are correct
From the log “Invalid request data i get that the else case “

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (isset($data['username']) && isset($_FILES['profilePicture'])) {

ELSE:
occured

the console.log(formData) returned:

1.
File

  1. lastModified: 1703941829454

  2. lastModifiedDate: Sat Dec 30 2023 14:10:29 GMT+0100 (Mitteleuropäische Normalzeit) {}

  3. name: “361273270047920240_1595864818.jpg”

  4. size: 7197

  5. type: “image/jpeg”

  6. webkitRelativePath: “”

  7. [[Prototype]]: File