0

I have Apache and mySQL running, there doesn't appear to be any errors as I've checked all the logs; my aim here is to send an email to a specific address whenever there is a new form entry

Im inexperienced with backend and PHP so I'm not too sure where im going wrong, any help would be appreciated

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $firstName = $_POST['firstName'];
    $lastName = $_POST['lastName'];
    $email = $_POST['email'];
    $checkbox = implode(', ', $_POST['checkbox']);
    $message = $_POST['message'];

    // Send email with form data
    $to = 'busanta29@gmail.com';
    $subject = 'New Contact Form Submission';
    $body = "Name: $firstName $lastName\nEmail: $email\nCheckbox: $checkbox\nMessage: $message";
    $headers = "From: $email";

    if (mail($to, $subject, $body, $headers)) {
        echo 'Message sent successfully';
    } else {
        echo 'Error sending message';
    }
}
?>

I saved this file in my htdocs folder of my XAMPP installation folder as suggested

I inputted the php file into my react project as such:

axios.post('http://localhost/mihcontactform.php', formData)
            .then(response => {
                console.log(response);
            })
            .catch(error => {
                console.log(error);
            });

I am trying to test this (I created a dummy php file with echo Hello World and it showed up so there isnt any config issues) but a white blank page just shows up when I try to access localhost/mihcontactform.php

For reference, this is what im getting the data from, a form I created in javascript:

import { useState } from 'react';
import axios from 'axios';

function ContactForm() {
    const [formData, setFormData] = useState({
        firstName: '',
        lastName: '',
        email: '',
        checkbox: [],
        message: ''
    });

    const handleFormSubmit = (e) => {
        e.preventDefault();
        const form = e.target;
        const formData = new FormData(form);

        axios.post('http://localhost/mihcontactform.php', formData)
            .then(response => {
                console.log(response);
            })
            .catch(error => {
                console.log(error);
            });
    }

    const handleInputChange = (e) => {
        if (e.target.type === 'checkbox') {
            let checkboxValues = formData.checkbox.slice();
            if (e.target.checked) {
                checkboxValues.push(e.target.value);
            } else {
                checkboxValues.splice(checkboxValues.indexOf(e.target.value), 1);
            }
            setFormData({
                ...formData,
                checkbox: checkboxValues,
            });
        } else {
            setFormData({
                ...formData,
                [e.target.name]: e.target.value,
            });
        }
    };

    return (
        <form onSubmit={handleFormSubmit} method='POST' action='mihcontactform.php'>
            <label>
                First Name:
                <input type='text' name='firstName' value={formData.firstName} onChange={handleInputChange} required/>
            </label>

            <label>
                Last Name:
                <input type='text' name='lastName' value={formData.lastName} onChange={handleInputChange} required/>
            </label>

            <label>
                Email:
                <input type='email' name='email' value={formData.email} onChange={handleInputChange} required/>
            </label>

            <label>
                What services are you contacting us about?
                <input type='checkbox' name='checkbox[]' value='A' onChange={handleInputChange} required/> A
                <input type='checkbox' name='checkbox[]' value='B' onChange={handleInputChange} required/> B
                <input type='checkbox' name='checkbox[]' value='C' onChange={handleInputChange} required/> C
                <input type='checkbox' name='checkbox[]' value='D' onChange={handleInputChange} required/> D
            </label>

            <label>
                Message:
                <textarea name='message' value={formData.message} onChange={handleInputChange} required></textarea>
            </label>

            <button type='submit'>Submit</button>
        </form>
    );  
} 

These are the errors I get when I use $_GET instead of $_POST

enter image description here

ADyson
  • 57,178
  • 14
  • 51
  • 63
Santa
  • 41
  • 4
  • 1
    Perhaps the REQUEST_METHOD isn't POST as your code assumes? You can test this by adding an `else { echo "That was not a POST request."; }` at the end of your code. If that message doesn't show up you can look in your PHP log file for error messages. – KIKO Software Apr 24 '23 at 10:00
  • the echo statement (that was not a post request) popped up, so it seems to be configured correctly, do you have any recs on how to move further now? – Santa Apr 24 '23 at 10:16
  • _"the echo statement (that was not a post request) popped up, so it seems to be configured correctly"_ - what are you saying now, that the debug statement showed it was _not_ a POST request? Then how would that be "configured correctly" then, for what you are trying to achieve here? – CBroe Apr 24 '23 at 10:32
  • Next step would be to check the content of `$_SERVER['REQUEST_METHOD']`. Perhaps it isn't exactly `POST`? – KIKO Software Apr 24 '23 at 10:45
  • I added my javascript file for reference, the error message shows – Santa Apr 24 '23 at 13:09
  • What did console.log(response) output? – ADyson Apr 24 '23 at 13:32
  • @KIKOSoftware I tried $_GET but it didn't work, im only proficient in front end so this is really confusing me, I really dont have a clue whats going wrong, error logs aren't showing anything either – Santa Apr 25 '23 at 02:29
  • Those errors appear to be showing when you load the page directly into your browser. Those are not the results of the axios request. Any results from the axios request will show in the Console, as a result of your `console.log` commands. Have you looked at those yet, as I suggested above? Remember that ajax/axios requests are entirely separate to any other requests your browser sends, and that any variables you send in each request are not preserved across different requests. And remember also that axios requests are asynchronous background requests and don't automatically update your page. – ADyson Apr 25 '23 at 07:21
  • I've uploaded a new question that is more detailed about this if any of you all are willing to have a look https://stackoverflow.com/questions/76099409/im-attempting-to-use-php-to-extract-formdata-from-my-js-file-in-my-project-to-th – Santa Apr 25 '23 at 09:07
  • Don't post duplicate questions please. If you have more info, please [edit] this one. Thanks – ADyson Apr 25 '23 at 09:08
  • Also you need to respond to [my comment above](https://stackoverflow.com/questions/76090638/trying-to-test-my-php-file-on-my-local-host-but-a-blank-white-page-just-appears?noredirect=1#comment134205879_76090638) please, which I strongly suspect is the source of your issue. – ADyson Apr 25 '23 at 09:13
  • @ADyson sorry about duplicating the question, my bad. Will have a look on that now and see if that's the root of my issue, thank you for taking the time to respond – Santa Apr 25 '23 at 12:40
  • No problem. Start by opening your browser's developer tools on the page where your HTML form is, then submit the form and look at what it shows in the Console - you should see a log entry containing the response from PHP (as a result of the `console.log(response);` command in your JS code). The Network tool can also be useful to look at when working with AJAX (and other) requests - it will show you all requests sent from the page, what data was sent in each request, and what data came back from the remote server as the response. – ADyson Apr 25 '23 at 12:42
  • @ADyson Yeah so im not sure what this means since im not backend proficient in the slightest but its saying I 'Axios Error, message: network error' in the console; also says my contactform.php from origin localhost:3000 has been blocked by CORS policy – Santa Apr 26 '23 at 05:41
  • Ok. So it looks like your react app runs on port 3000, and your PHP app runs on the standard port 80. Even if they are on the same host, the difference in ports means that any AJAX requests sent between them are considered as "cross-origin" requests. Basically they are treated as entirely separate websites and applications. For security reasons, such requests are restricted by rules in the browser to prevent accidental data theft etc. – ADyson Apr 26 '23 at 08:22
  • The solution to this is to have your PHP application respond to requests with the correct headers which indicate to the browser that requests to that application from the localhost:3000 domain are acceptable. You can read more about it here: [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) including the concepts, how it works and what you need to do to enable cross-origin requests in your application. It's a common issue, so it's worth learning about it in detail. – ADyson Apr 26 '23 at 08:24
  • You can also get PHP-specific advice regarding CORS in places like [Cross-Origin Request Headers(CORS) with PHP headers](https://stackoverflow.com/questions/8719276/cross-origin-request-headerscors-with-php-headers) and elsewhere online (only a quick google away) – ADyson Apr 26 '23 at 08:25
  • Thanks a lot for your time @ADyson, this definitely clears up a lot of the confusion; if I do get the browser to accept requests from localhost3000, will that effect my web application once I deploy it live? – Santa Apr 26 '23 at 08:39
  • Yes - the live PHP application would need to set a header to enable the URL of the live react site (instead of localhost). So I'd advise you maybe to have the URL in a variable which the PHP code loads from a settings file (or database), so you can vary the value in different environments, without changing the code itself. – ADyson Apr 26 '23 at 08:41
  • 1
    Understood, this clears it all up for me; I really appreciate it @ADyson – Santa Apr 26 '23 at 08:42

2 Answers2

0

Many annoying things could be causing such. Here are some PHP tips for tracking down the issues:

  • Scatter this in your PHP; then look at the Apache error.log. It may help you narrow down the problem:

     error_log(__LINE__);
    
  • When Javascript hits a syntax error, it leaves no clues. It will even exit a function, leaving you wondering how the function seemed to work partially. Use Chrome's debugger. (Or another browser's debugger.)

  • PHP: This may catch some errors that silently crash your web page (especially in PHP 8).

     try { ... 
         }
     catch ($throwable $t) {
         echo "<pre>"; print_r($t); echo "/pre>";
                           }
    
  • Javascript: console.log("..."); and use Chrome's debugger.

  • PHP config -- There are some settings for displaying errors on the web page. They should be used only for Development, not for Production.

Rick James
  • 135,179
  • 13
  • 127
  • 222
-1
if ($_SERVER['REQUEST_METHOD'] === 'POST') {

}

This part is obviously not true edit: might as well just check for $_POST, and if each $_POST[''] is empty or not

Also be careful with using unsanitised $_POST directly into the code if it is user submitted.

Also, be careful with inbuild php mail() it is a bit weird and has some quirks