I have a header location problem despite following all the advice I can find online. The mailer script sends the email(s) but I get a 'headers already sent' error relating to Line 29 which is {header("Location: $thanksURL");} and no redirect to the confirmation page. If I replace the header location code with an instruction to print a confirmatory message instead, it works, so there must be something about the header location code that the server doesn't like.
Here is the code:
<?php
ob_start();
$to = "msheath#btinternet.com" ;
$from = $_REQUEST['email'] ;
$name = $_REQUEST['name'] ;
$headers = "From: $from";
$subject = "Request for Library Document";
$thanksURL = "http://www.postalhistory.org.uk/newsite/php/thankyou.php"; //confirmation page
$fields = array();
$fields{"name"} = "Name";
$fields{"address"} = "Address";
$fields{"email"} = "Email";
$fields{"tel"} = "Telephone No";
$fields{"author1"} = "First Author";
$fields{"title1"} = "First Title";
$fields{"author2"} = "Second Author";
$fields{"title2"} = "Second Title";
$body = "I would like to borrow the undermentioned book(s) from the PHS Library:\n\n"; foreach($fields as $a => $b){ $body .= sprintf("%20s: %s\n",$b,$_REQUEST[$a]); }
$headers2 = "From: The Librarian, Postal History Society";
$subject2 = "Thank you for contacting the Postal History Society";
$autoreply = "Thank you for your request. Somebody will get back to you as soon as possible, usually within 48 hours.";
if($from == '') {print "You have not entered an email, please go back and try again";}
else {
if($name == '') {print "You have not entered a name, please go back and try again";}
else {
$send = mail($to, $subject, $body, $headers);
$send2 = mail($from, $subject2, $autoreply, $headers2);
if($send)
{header("Location: $thanksURL");}
else
{print "We encountered an error sending your mail, please notify webmaster#YourCompany.com"; }
}
}
ob_end_flush()
?>
Go to http://www.postalhistory.org.uk/newsite/php/library.php to try it out for yourself.
Can anyone suggest what is wrong?
Mike
'headers already sent' means you've already sent something to the browser. This could be a whitespace somewhere. It could also be that your file is encoded in UTF-8 with BOM which means you've sent the BOM to the browser
Warning: Cannot modify header information - headers already sent by (output started at /home/users/uks52804/html/postalhistory.org.uk/newsite/php/contact.php:1) in /home/users/uks52804/html/postalhistory.org.uk/newsite/php/contact.php on line 29
This means that you have output prior to your ob_start() call. ob_start should be the first instruction of the page that is including that code.
I faced the same problem a while back and found that i was echoing something before setting the headers. I removed the echo statement and also cleared some whitespaces that removed the problem
Related
This question already has answers here:
How to fix "Headers already sent" error in PHP
(11 answers)
Closed 7 days ago.
Currently trying to create an email contact form for a personal website. The header() redirect function is not working and keeps returning the error message:
"PHP Warning: Cannot modify header information - headers already sent
by (output started at /home1/claireel/public_html/email.php:1) in
/home1/claireel/public_html/email.php on line 38"
Also, the form will send email to the testing email that I had originally had in the file but when I changed the address to the one I actually intend to use, it won't send.
<?php
$errors = [];
$errorMessage = '';
if (!empty($_POST)) {
$first = $_POST['first'];
$last = $_POST['last'];
$email = $_POST['email'];
$message = $_POST['message'];
if (empty($first)) {
$errors[] = 'First name is empty';
}
if (empty($last)) {
$errors[] = 'Last name is empty';
}
if (empty($email)) {
$errors[] = 'Email is empty';
} else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = 'Email is invalid';
}
if (empty($message)) {
$errors[] = 'Message is empty';
}
if (empty($errors)) {
$toEmail = '************#gmail.com';
$emailSubject = 'New email from your contact form';
$headers = ['From' => $email, 'Reply-To' => $email, 'Content-type' => 'text/html; charset=utf-8'];
$bodyParagraphs = ["Name: {$first} {$last}", "Email: {$email}", "Message:", $message];
$body = join(PHP_EOL, $bodyParagraphs);
if (mail($toEmail, $emailSubject, $body, $headers)) {
header('Location: thank-you.html');
} else {
$errorMessage = 'Oops, something went wrong. Please try again later';
}
} else {
$allErrors = join('<br/>', $errors);
$errorMessage = "<p style='color: red;'>{$allErrors}</p>";
}
}
?>
I have made sure there is no white-space before the opening or after the closing php tags. I have also made sure the file is encoded in UTF-8 wihtout BOM. I also don't see anything in the file that would be outputting before the header function.
Put exit in
if (mail($toEmail, $emailSubject, $body, $headers)) {
header('Location: thank-you.html');
} else {
$errorMessage = 'Oops, something went wrong. Please try again later';
}
after header():
if (mail($toEmail, $emailSubject, $body, $headers)) {
header('Location: thank-you.html');
exit;
} else {
$errorMessage = 'Oops, something went wrong. Please try again later';
}
Following are the steps that you can take to solve your problem. This problem occurs if output buffering is not enabled with ob_start() before any output is sent to the browser, the header() function call will likely fail with an error message similar to the one you mentioned earlier ("Cannot modify header information - headers already sent..."). This is because the header() function must be called before any output is sent to the browser, including any whitespace or HTML tags.
Output buffering with ob_start() allows you to capture and manipulate any output before it is sent to the browser, which can be useful for scenarios like this where you need to ensure that the header() function is called before any output is sent.
how you can modify your code to use output buffering with ob_start() to fix the header error:
Place the ob_start() function at the very beginning of your PHP file, before any output is sent to the browser. This will enable output buffering for the entire script, capturing any output before it is sent to the browser.
Then, replace the header('Location: thank-you.html') line with ob_end_clean(); followed by header('Location: thank-you.html');. This will discard any output that was captured by the output buffer and send the header() function call with a clean output buffer.
Here's the modified code:
<?php
ob_start();
$errors = [];
$errorMessage = '';
// Rest of your code
if (empty($errors)) {
$toEmail = '************#gmail.com';
$emailSubject = 'New email from your contact form';
$headers = ['From' => $email, 'Reply-To' => $email, 'Content-type' => 'text/html; charset=utf-8'];
$bodyParagraphs = ["Name: {$first} {$last}", "Email: {$email}", "Message:", $message];
$body = join(PHP_EOL, $bodyParagraphs);
if (mail($toEmail, $emailSubject, $body, $headers)) {
ob_end_clean();
header('Location: thank-you.html');
exit; // Always exit after a header redirect
} else {
$errorMessage = 'Oops, something went wrong. Please try again later';
}
}
// Rest of your code
ob_end_flush();
?>
With this modification, any output that is generated before the header() function call will be captured by the output buffer and discarded with ob_end_clean() before the header() function is called. This should fix the "Cannot modify header information" error.
If the problem continues you can use JavaScript to redirect the page by simply echoing:
<?php
echo '<script>window.location.href = "page.php";</script>';
?>
I'm writing an emailing script for order confirmation for customers of my website. I'm having a problem where the total of the order displayed in the email is being placed on a new line, however no new line is in the code. I've attached an image of what is happening.
Here is my code:
<?php
if(isset($_POST['email']) && isset($_POST['name']) && isset($_POST['order'])) {
$to = $_POST['email'];
$name = $_POST['name'] .",";
$order = $_POST['order'];
$trackingNumber = $_POST['trackingNumber'];
$totalAmount = "Your total was: $".$_POST['totalAmount'];
if(!empty($to) && !empty($name) && !empty($order)) {
$subject = 'From the band.it team ';
$text = "My name is Bobby and I am a part of band.it's fulfillment Team! We recieved your order and are working to process it from our Gainesville, Florida facility. Feel free to reach out to us at any point with any comments, questions, or concerns. You can find our contact infomation at the bottom of this email.";
$body = "Hey ".$name."\r\n".$text."\r\nYour order will contain:\r\n".$order."\r\n";
$body = $body.$totalAmount;
$body = $body."\r\nYou can track your package through USPS with this number:\r\n".$trackingNumber."\r\n";
$body = $body."\r\nYou can view any order you've made with us via going to the following link with your tracking number handy!\r\nhttps://camerabandit.com/findAnOrder/";
$body = $body."\r\n\r\nThanks again for your support of the band.it team, and reach out to us anytime by sending an email to contact#camerabandit.com";
$headers = 'Order Confirmed';
if (mail($to, $subject, $body, $headers)) {
echo 'Mail has been sent';
} else {
echo 'Mail failed to send';
}
}
}
?>
My best guess is that $_POST['totalAmount'] contains a line break.
You may want to trim() it:
$totalAmount = "Your total was: $".trim($_POST['totalAmount']);
i would suggest a table to enhance the display of the message also check your var i think it contains \r \n you can use this to trim it
$string = trim(preg_replace('/\s\s+/', ' ', $string));
The part of the body directly before it is:
$body = "Hey ".$name."\r\n".$text."\r\nYour order will contain:\r\n".$order."\r\n";
So that ends with
\r\n
That's where your linebreak is...
I have a website I'm working on with a contact form. Simple Name, Email, and Message fields. However, I'm not receiving the email from the form; though I do get the "Message Sent" success option.
I had found a way to test wp_mail to see if that was it, using https://gist.github.com/butlerblog/5c9b805529c419b81447#file-test_wp_mail-php and that works just fine - so I have no clue what the problem is.
<?php
//loading wordpress functions
require( '../../../wp-load.php' );
define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
$to = get_option('admin_email'); //Enter your e-mail here.
$subject = get_theme_option(tk_theme_name.'_contact_contact_subject');
$from = $_POST['contactname'];
$name = $_POST['email'];
$message = $_POST['message'];
$headers = "From: $name <$from>\n";
$headers .= "Reply-To: $subject <$from>\n";
$return = $_POST['returnurl'];
$sitename =get_bloginfo('name');
$body = "You received e-mail from ".$from." [".$name."] "." using ".$sitename."\n\n\n".$message;
$send = wp_mail($to, $subject, $body, $headers) ;
if($send){
wp_redirect($return.'?sent=success');
}else{
wp_redirect($return.'?sent=error');
}
?>
As I said, it does hit
wp_redirect($return.'?sent=success')
so I have no clue what is wrong.
EDIT:
Did a variable dump
To: uriah.h.brown#gmail.com
Subject: E-Mail from HollyBrown.Net
From: TestName
Name: test#yahoo.com
Message: TestMessage
Headers: From: test#yahoo.com Reply-To: E-Mail from HollyBrown.Net
Return: http://www.hollybrown.net/contact/
Sitename: The Artwork of Holly Brown
Body: You received e-mail from TestName [test#yahoo.com] using The Artwork of Holly Brown TestMessage
Send: 1
Warning: Cannot modify header information - headers already sent by (output started at /home/panoramicpanda/hollybrown.net/wp-content/themes/widely/sendcontact.php:21) in /home/panoramicpanda/hollybrown.net/wp-includes/pluggable.php on line 1178
The header already sent error leads me to believe output has already been started before you try and send the headers. In this case, the redirect won't work. Try this instead:
/loading wordpress functions
require( '../../../wp-load.php' );
ob_start(); // Starts data buffer.
define('IS_AJAX', isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
$to = get_option('admin_email'); //Enter your e-mail here.
$subject = get_theme_option(tk_theme_name.'_contact_contact_subject');
$from = $_POST['contactname'];
$name = $_POST['email'];
$message = $_POST['message'];
$headers = "From: $name <$from>\n";
$headers .= "Reply-To: $subject <$from>\n";
$return = $_POST['returnurl'];
$sitename =get_bloginfo('name');
$body = "You received e-mail from ".$from." [".$name."] "." using ".$sitename."\n\n\n".$message;
$send = wp_mail($to, $subject, $body, $headers) ;
ob_end_clean();// Purges data in buffer.
if($send){
wp_redirect($return.'?sent=success');
}else{
wp_redirect($return.'?sent=error');
}
Notice the ob_start and ob_end_clean. This will throw your output into the "buffer" and output it clean. The reason this is a problem, is because if any markup is sent BEFORE your sendmail (ie: html generated through templates etc, then the headers have already been started. At that point, unless your server configuration specifically allows you to modify already sent headers, then you will get the error you are getting. Using output buffering allows you to send the data as you intend.
This question already has answers here:
How to fix "Headers already sent" error in PHP
(11 answers)
Closed 9 years ago.
I know that this question has been asked many times, however, I can't seem to find solutions that are relevant to my situation, since they mostly deal with wordpress.
Here is my mail form:
<?php
$to = "email#gmail.com" ;
$from = $_REQUEST['email'] ;
$name = $_REQUEST['name'] ;
$headers = "From: $from";
$subject = "Contact Submission From domain.com";
$fields = array();
$fields{"name"} = "name";
$fields{"title"} = "title";
$fields{"email"} = "email";
$fields{"phone"} = "phone";
$fields{"prefer_phone"} = "pref_phone";
$fields{"prefer_email"} = "pref_email";
$fields{"message"} = "message";
$fields{"referral"} = "referral";
$body = "Here is their submitted message:\n\n"; foreach($fields as $a => $b){ $body .= sprintf("%20s: %s\n\n",$b,$_REQUEST[$a]); }
if($from == '') {print "You have not entered an email, please hit back and resubmit";}
else {
$send = mail($to, $subject, $body, $headers);
if($send)
{header( "Location: http://www.domain.com/sent.html" );}
else
{print "We encountered an error sending your mail, please notify support#domain.com";}
}
?>
The email sends just fine, but I get the titular error for the redirect:
Warning: Cannot modify header information - headers already sent by (output started at /home/wills5/public_html/send_henry.php:1) in /home/wills5/public_html/send_email.php on line 23
Edit: It was frickin' whitespace before line 1 apparently, thanks guys.
If the message says the error is in line 1, then it is typically leading whitespace, text >or HTML before the opening
Chances are you have whitespace besides or above your <?php tag, or HTML or some other type of "output". Maybe even a byte order mark.
<?php
echo "Correct";
// or vvv, but not with echo
// header("Location: http://www.example.com/");
?>
(space)
(space) <?php
echo "Incorrect";
header("Location: http://www.example.com/");
?>
<div align="center">Text</div>
<?php
echo "Incorrect";
header("Location: http://www.example.com/");
?>
Footnote: As per Gavin's suggestion, and I quote: "It is good form to leave off the closing php tag on class files for this reason. It prevents the inadvertent inclusion of white-space after an included file."
The aim of this script is to send an email, but instead of including your name and email, it would include it on the message because the website already has details of this from the PHP session. Currently the "2Email" works.. it can send a message to the recipient's mail box, and includes the user's input message. But it doesn't follow the template. I.E. It doesn't include the text "Sent via the dashbaord"
<?php
session_start();
if(!isset($_SESSION["USER"])){
header("Location: ../login.php?NotAuth");
}
$to = $_POST['2Email'];
$name = $_SESSION["USER"]["FullName"];
$email = $_SESSION["USER"]["Email"];
$subject = $_POST['regarding'];
$message = $_POST['msg'];
$Cc= $_SESSION["USER"]["Email"];
$headers = "From: $email";
$tracker = "This message was sent via the TrackerSystem dashboard";
$message = "Hi, "."\n".$message. "\n". "Regards, ".$name. "\n".$tracker.
$sent = mail($to, $subject, $message, $headers) ;
if($sent) {
print "Sent successfully! XD ";
} else {
print "The server made a booboo, the email didn't send :'( ";
}
?>
Is it a typo on line 19: "\n".$tracker. ? If so, that's what prevents your tracker being appended to the message.
What's actually happening: the whole expression on lines 19-20 (this one):
$message = "Hi, "."\n".$message. "\n". "Regards, ".$name. "\n".$tracker.
$sent = mail($to, $subject, $message, $headers) ;
is being evaluated from right to left (if it even works, of which I doubt). So (first) mail is sent and result is assigned to $sent and (second) the whole concatenated string is assigned to $message.
To fix it, make "\n".$tracker. "\n".$tracker;.