Reputation: 47
This is my second attempt in trying to make a working contact section on my website. After reading up on debugging php I still don't know what to do next. After hitting submit I get an "undefined index" error -- and it cites multiple lines as the problem.
<?php
// Only process POST reqeusts.
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Get the form fields and remove whitespace.
$name = strip_tags(trim($_POST["name"]));
$name = str_replace(array("\r","\n"),array(" "," "),$name);
$email = filter_var(trim($_POST["email"]), FILTER_SANITIZE_EMAIL);
$message = trim($_POST["message"]);
// Check that data was sent to the mailer.
if ( empty($name) OR empty($message) OR !filter_var($email, FILTER_VALIDATE_EMAIL)) {
// Set a 400 (bad request) response code and exit.
http_response_code(400);
echo "Oops! There was a problem with your submission. Please complete the form and try again.";
exit;
}
// Set the recipient email address.
$recipient = "[email protected]";
// Set the email subject.
$subject = "New contact from $name";
// Build the email content.
$email_content = "Name: $name\n";
$email_content .= "Email: $email\n\n";
$email_content .= "Message:\n$message\n";
// Build the email headers.
$email_headers = "From: $name <$email>";
// Send the email.
if (mail($recipient, $subject, $email_content, $email_headers)) {
// Set a 200 (okay) response code.
http_response_code(200);
echo "Thank You! Your message has been sent.";
} else {
// Set a 500 (internal server error) response code.
http_response_code(500);
echo "Oops! Something went wrong and we couldn't send your message.";
}
} else {
// Not a POST request, set a 403 (forbidden) response code.
http_response_code(403);
echo "There was a problem with your submission, please try again.";
}
?>
It seems like the ajax validation is working -- but once I hit submit there's an error. I'll include the HTML below as well.
<form id="ajax-contact" method="post" action="php/mailer.php" role="form">
<div class="form-group">
<label for="name">Your Name</label>
<input type="text" id="name" class="form-control" required>
</div>
<div class="form-group">
<label for="email">Email address</label>
<input type="email" id="email" class="form-control" required>
</div>
<div class="form-group">
<label for="message">Message</label>
<textarea id="message" rows="5" class="form-control" required></textarea>
</div>
<button type="submit" class="btn">Submit</button>
</form>
Please let me know if you need more information -- or if I need to debug this more on my own. Thanks for your time!
$(function() {
// Get the form.
var form = $('#ajax-contact');
// Get the messages div.
var formMessages = $('#form-messages');
// Set up an event listener for the contact form.
$(form).submit(function(e) {
// Stop the browser from submitting the form.
e.preventDefault();
// Serialize the form data.
var formData = $(form).serialize();
// Submit the form using AJAX.
$.ajax({
type: 'POST',
url: $(form).attr('action'),
data: formData
})
.done(function(response) {
// Make sure that the formMessages div has the 'success' class.
$(formMessages).removeClass('error');
$(formMessages).addClass('success');
// Set the message text.
$(formMessages).text(response);
// Clear the form.
$('#name').val('');
$('#email').val('');
$('#message').val('');
})
.fail(function(data) {
// Make sure that the formMessages div has the 'error' class.
$(formMessages).removeClass('success');
$(formMessages).addClass('error');
// Set the message text.
if (data.responseText !== '') {
$(formMessages).text(data.responseText);
} else {
$(formMessages).text('Oops! An error occured and your message could not be sent.');
}
});
});
});
I've added the ajax. The first time I tested the page with the HTML corrected, it did exactly what I wanted. Now, however, the "Success" message will be shown on a new page after I click "Submit".
Upvotes: 1
Views: 1071
Reputation: 2061
As @RST said in the his comment, you need to give your input fields a name
. The id
attribute is only used in the DOM, for JS, HTML anchors and CSS classes. They are not sent back as a part of the POST/GET request, and as suchdoes not exist as far as PHP knows.
A good way to ensure that you don't get such errors in the future, is to check for an empty (or non-set) value. If it's a required field, you should use empty()
to check for this, but if the field can be an empty string then isset()
would be the proper way of testing.
Quick, and dirty, example:
// Test and validate the username, which is a required field.
if (empty ($_POST['username'])) {
$errors[] = "Username must be specified";
} elseif (!filter_var ($_POST['username'], E_VALIDATE_REGEXP, '/^[A-Za-z0-9]+\\z/u')) {
$errors[] = "Invalid username specified";
} else {
$username = $_POST['username'];
}
// Test an optional field like a checkbox, which (if not checked)
// causes the field to be missing from the POST data.
$optional = false;
if (isset ($_POST['checkbox']) && $_POST['checkbox'] == 1) {
$optional = true;
}
You'll notice that I've used an errors array in the code above, which makes it very easy to detect (and display) if anything fails validation. Now you only need to check of said array is empty, instead of checking if every single variable contains a value. With the added benefit of having all of the errors readily available, for easier listing to the user, should something be amiss.
One more thing I want to point out, and that is your use of strip_tags()
. This won't help you against SQL injections, and will not give you an adequate protection against XSS attack either. Its use should therefore be avoided, and proper techniques employed instead. Such as htmlspecialchars()
when adding stuff to HTML output, or prepared statements when sending stuff to the database.
Upvotes: 1
Reputation: 1907
name
attribute in form fieldsname
attribute in form fieldsname
attribute missing from form fields. I have updated your form fields with name attribute. Update your form to the below form and check your ajax calls.
<form id="ajax-contact" method="post" action="php/mailer.php" role="form">
<div class="form-group">
<label for="name">Your Name</label>
<input type="text" id="name" name="name" class="form-control" required>
</div>
<div class="form-group">
<label for="email">Email address</label>
<input type="email" id="email" name="email" class="form-control" required>
</div>
<div class="form-group">
<label for="message">Message</label>
<textarea id="message" rows="5" name="message" class="form-control" required></textarea>
</div>
<button type="submit" name="submit" class="btn">Submit</button>
</form>
After your form field has name attribute, update your ajax call to utilize those name. During ajax request also include the form fields as follows. By using $('#ajax-contact').serialize()
it will send all the information to the server. Play with it if its your first time with serialize
.
$.ajax({
url: 'yourdomain.com/php/mailer.php',
method: 'POST',
data: $('#ajax-contact').serialize(),
dataType: 'json',
success: function() {
// Your success callback
},
error: function() {
// Your error callback
}
});
Also like other suggested, implement the strict check of the values with isset()
, empty()
. It's a good practice. If you still have problem after it please update your question with AJAX calls and we'll try to help you. Please let us know whether it worked for you or not.
Upvotes: 2