Jump to content
  • Announcements

    • boen_robot

      Guidelines and Netiquette   03/28/2017

      Posting Problems:   Having problems posting your topic? Read through this: To join, you agree to our terms and conditions and fill out and submit a registration form. An activation email will be sent to your email adress, so you'll need to verify your account. After that the account has to be validated by one of the moderators. This will mean that it can take up to a day to be activated. A couple of things to remember to ensure approval: Don't use an email address in one of those $2 four character .com domains eg. xyds.com. These will be deleted and the domain added to the banned list. Don't use an email address that is within a domain with a bad reputation for spam. A Google search is run on every email address and email domain. Don't sign up with an email address that doesn't exist, doesn't work or requires the sender to answer a quiz before their email can get to you. Put your country and or state and city in the signup form. Blank forms will go to the botton of the "to do" list. And make sure that your email address and your country match, saying you're from Alabama and using a .ru email address is not going to get you activated. After a membership is activated the first few posts will be monitored. Posting spam or unapproved topics described in the agreement results in an immediate ban. The email provider and the IP addresses associated with the account will be banned and all posts will be deleted. These strict measures have been deemed necessary to hinder spam. Sorry for any inconvenience this causes, but it's not liable to change. If, after reading this, you still can't post and don't understand why, contact one of the Moderators listed here.   Topic Guidelines   Including the following information can expedite an accurate response from board members: Must be a Specific Problem or Question related to web design and development Include Code in Question (wrap with   for small blocks of code and for longer blocks   ) Include Code Author Include Extra Notes/Modifications/Attempts Include web link to page/file when possible Content Guidelines   You may not post, upload, link to, or email any Content that contains, promotes, gives instruction about, or provides prohibited Content. Prohibited Content includes any Content that breaks any local, state, county, national or international law. Prohibited Content also includes: No direct or indirect advertising or websites, forums, products, services No hijacking of posts (do not post your question in someone elses) Content that infringes upon any rights [ex. MP3s and ROMs] (including, but not limited to, copyrights and trademarks) Abusive, threatening, defamatory, racist, or obscene Viruses or any other harmful computer software False Information or libel Spam, chain letters, or Pyramid schemes Gambling or Illicit drugs Terrorism Hacking or cheating for internet/online games Warez, Roms, CD-Keys, Cracks, Passwords, or Serial Numbers Pornography, nudity, or sexual material of any kind Excessive profanity Invasive of privacy or impersonation of any person/entity Hacking materials or information Posting Tips   There are more BBcodes than there are buttons for on the reply menu. To get the full list, click "BB Code Help" underneath the clickable smilie face menu. Use   for small snippets of code Use   for lengthy snippets of code Use   if your snippet is HTML (optional) Use   if your snippet is SQL (optional) Rules of Conduct   Be nice. There's no need for calling someone stupid if they ask an 'easy' question. Keep your avatars and signatures absolutely child friendly. We have a younger audience on this forum. Keep your language appropriate for the same reason above. Do not PM moderators for help on the forum. Post on the topic, or create a new one.   Spam:   Recently, as you have all without doubt noticed, we have had lots of spam and advertisement on the forum. Therefore, we'd like to alert you as to what to do when you have found any of the aforementioned annoying messages: it. Immediately. Give a clear reason, please, if the advertising is not evident. DO NOT POST! Report, let the post stay as is, and we will get to it, meanwhile if you continue to post as normal in the other threads, it won't be on the top so long. Refrain from PMing the member. This won't help at all, as they are most likely spambots anyway. Thank you.       Images in signatures:   After thinking of users on dial-up, we have decided to enforce the following rules regarding signatures. Please pay heed to them. Respecting these rules is respecting the members on this forum with dial-up. Signature rules: No animated images AT ALL. No matter the amount of animation. Maximum image widthxheight: 300x150 Maximum image (file) size: 15kb Use calm colors. Do not use highly contrasting images in your signature, as this can get really annoying when seeing several posts from one member in the same thread. The same prohibited content goes for images as for posts. Lastly, use common sense. No lengthy signatures please. Save us some scrolling. Thank you.       Links in signatures:   Please understand that w3schools.com only exists because of voluntary work and is barely supported by the advertising littered throughout the tutorials and the forum. So, please, stop advertising other sites. DO not post links that drive traffic away from the w3schools domain - especially to a site that offers similar if not identical information. Please help support the site by keeping individuals on it. Thank you. Here are some guidelines as to what you can put in your signature: w3schools links --> allowed w3.org links --> allowed browser links --> allowed html editor links --> allowed personal sites --> allowed tutorial sites competing with w3schools --> NOT allowed sites completely irrelevant to webprogramming and this forum --> NOT allowed   Thanks for understanding, and for taking the time to read this. ~W3Schools Modstaff~
iwato

The header( ) Function

Recommended Posts

iwato    6

DISCLAIMER: After seeing what has been written on the internet on this subject I am loathe to start here, but have I any other choice?

QUESTION:  The PHP header(location: './sample.html'); is telling me that my headers have already been sent and is referring me back to the beginning of my PHP script.  Can I buffer my way out of this mess?  If so,

  • Where to I start and stop the buffer?
  • Where do I place the header( ) function?

BACKGROUND:  I have just spent several weeks setting up an email verification system and am putting on the decorative touches.  Truly, I thought that I had almost reached the end; truly I fear now that I am far from finished.  I hope that I am wrong.

 

Share this post


Link to post
Share on other sites
Ingolme    794

Headers can only be sent before anything is printed. If you're not printing anything and it's pointing to the first line of your document there are two possible reasons:

  1. There's a space or line break before the opening <?php tag
  2. The document is saved as UTF-8 with a byte-order mark (BOM).

Eliminate all whitespace before the <?php tag and make sure to save your documents as UTF-8 without a BOM.

Share this post


Link to post
Share on other sites
iwato    6

As I feared, this will likely not be easy.  Here is all that comes before the <?php tag.  I have scrutinized the invisibles of all lines before the tag.  All lines end with line breaks and begin with either tabs or nothing.  Of course, there are blank spaces within the lines of code, else the code would be unintelligible.

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8" />
	<title>Gate Seven - An Invitation and Gift</title>
	<meta name="generator" content="BBEdit 11.6" />
	<link rel="stylesheet" href="../../_utilities/css/gc_splash.css">
	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
	<script>
		$( document ).ready(function() {
			console.log( "ready!" );
			var tongue = 'other_tongue';
			$('#other').hide();
			$('#tongue').change(function() {
				if ($('#tongue').val() == tongue) {
					$('#other').show();
				}
				if ($('#tongue').val() != tongue) {
					$('#other').hide();
				}
			});
		});
	</script>
</head>
<body>
	<?php

 

Edited by iwato

Share this post


Link to post
Share on other sites
iwato    6

If the problem is within the PHP code, then would this not be a likely source?  Specifically, the first line. For, the file confirmation_mail.php contains headers.

	$html_message = file_get_contents('../../confirmation_mail.php');
	$html_message = str_replace('%username%', $name, $html_message);
	$html_message = str_replace('%email%', $email, $html_message);
	$html_message = str_replace('%hash%', $hash, $html_message);



Could I find a better place for it?  I think not.
Could I buffer it?  Surely, but I am not sure how.

Surely the email that PHP sends on the sending page must be sent before the header( ) function is invoked else the PHP on the sending page would fail, would it not?

Surely, the document confirmation_mail.php must be included in the document before it is sent, else it would be omitted from the mail, would it not?

I do not see how to get around this problem, if it is, indeed, it is its proper source.

Roddy

Edited by iwato

Share this post


Link to post
Share on other sites
iwato    6

This is how the email is sent.

      if (!$mail->send()) {
            echo "Mailer Error: " . $mail->ErrorInfo;
      } else {
//			echo "Message sent!";
			header('Location: ../../gate_confirmation.html');
	  }

 

Share this post


Link to post
Share on other sites
thescientist    231

it would be helpful to share the relevant code in one block, instead of three code blocks in as many posts, since it makes it harder to understand the context of your issue.  And in particular with headers, seeing the whole file is important.

Share this post


Link to post
Share on other sites
Ingolme    794

You should have the PHP run first, then the HTML.

Here's the general structure of my PHP applications:

<?php
// Form handling logic
if(isset($_POST['submit')) {
  // If submission was successful
  // Do something
  header('Location: http://www.example.com/target.php');
  exit;
}

// Set variables for use in templates
$template = 5;

// Include a template file
include 'template.php';
?>

 

  • Like 1

Share this post


Link to post
Share on other sites
justsomeguy    936

You should get in the habit of structuring your code like Ingolme mentions.  Put your PHP code first that will decide what the page is even going to do, and output HTML and whatever later on.  If you're just going to redirect there's no reason to output a bunch of HTML anyway, right?  So figure out first if you're going to redirect or show HTML or whatever else, and then do that.

  • Like 1

Share this post


Link to post
Share on other sites
iwato    6

This is how the email is sent.

I have eliminated all comments and non-essential code.  Sensitive information has been replaced with placeholders.

In addition, I have added row spaces to departmentalize the code into specific tasks for easier digestion.

No rearrangement of code that I have made achieves the desired affect -- namely, the loading of the confirmation page (gate_confirmation.html).   The sending of the verification email (confirmation_mail.php) works fine!

The desired affect, by the way, can be viewed by going to the last (5th) frame of the last gate (7th) in the second splash panel at www.grammarcaptive.com/overview.  The quickest way to get there is by using the back arrows built-into the splash panels.  If you know the way, you can arrive in seconds.

Please enter a phony email address, if you do not wish to be entered into my database.  The only check for validity is format. 

Also, if you wish to repeat the procedure, you can get the splash panel to reopen by clicking on my stylized image on the main page..

		require_once '../../_utilities/php/php_mailer/PHPMailerAutoload.php';
		$name = $email = $newsletter = $webinar = $language = $error_msg = '' ;

		if ($_SERVER["REQUEST_METHOD"] == "POST") {


			if (empty($_POST['language'])) {
				$error_msg = "Please select your first language.";
			} else if ($_POST['language'] == 'other_tongue') {
				if (empty($_POST['other'])) {
					$error_msg = "Please enter your first language.";
				} else {
					$language = filter_var($_POST["other"], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
				}
			} else {
				$language = filter_var($_POST["language"], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
			}


			if (!($_POST["newsletter"]) && !($_POST["webinar"])) {
				$error_msg = "Have you forgotten to select a gift?";
			} else {
				$newsletter = filter_var($_POST["newsletter"], FILTER_SANITIZE_NUMBER_INT, FILTER_VALIDATE_INT);
				$newsletter = !empty($newsletter) ? "$newsletter" : 0;
				$webinar = filter_var($_POST["webinar"], FILTER_SANITIZE_NUMBER_INT, FILTER_VALIDATE_INT);
				$webinar = !empty($webinar) ? "$webinar" : 0;
			}


			if (empty($_POST["email"])) {
				$error_msg = "Please enter your email address.";
			} else if (!filter_var($_POST["email"], FILTER_VALIDATE_EMAIL, FILTER_SANITIZE_EMAIL)) {
				$error_msg = "Invalid email format. Please try again!";
			} else {
				$email = filter_var($_POST["email"], FILTER_VALIDATE_EMAIL, FILTER_SANITIZE_EMAIL);
			}


			if (empty($_POST['name'])) {
				$error_msg = "Please enter a name with which you would like to be greeted.";
			} else {
				$name = filter_var($_POST["name"], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW);
			}


			if ((!empty($name) && !empty($language) && !empty($email) && (isset($_POST["newsletter"]) || isset($_POST["webinar"])))) {
				$hostname = "localhost";
				$user = "...";
				$pwd = "...";
				$db = "...";
				$mysqli_obj = mysqli_connect($hostname, $user, $pwd, $db);
				$mysqli_obj->set_charset("utf8");


				function random_password() {
					$alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!$%&!$%&!$%&!$%&!$%&!$%&';
					$pass = array();
					$alphaLength = strlen($alphabet) - 1;
					for ($i = 0; $i < 8; $i++) {
						$n = rand(0, $alphaLength);
						$pass[] = $alphabet[$n];
					}
					return implode($pass);
				}
				$password = random_password();

                                        
                $hash = password_hash($password, PASSWORD_DEFAULT);
				$active = 0;

                                        
                $tbl_name = '---.---';
				$sql_1 = "INSERT INTO " . $tbl_name . " (user_name, language, email_address, hash, active, newsletter, webinar) VALUES ('" . $name . "','" . $language . "','" . $email . "','" . $hash . "','" . $hash . "','" . $newsletter . "','" . $webinar . "')"; 
				$mysqli_obj->query($sql_1);

                      
				$mail = new PHPMailer;
				$mail->CharSet = 'UTF-8';
				$mail->isSMTP();
				$mail->SMTPDebug = 0;
				$mail->Debugoutput = 'html';
				$mail->Host = "---.---.com";
				$mail->Port = ...;
				$mail->SMTPAuth = true;
				$mail->Username = "---@---.---";
				$mail->Password = "...";
				$mail->setFrom('---@---.com', 'Grammar Captive');
				$mail->addReplyTo('---@---.com', 'Grammar Captive Administration');
				$mail->addAddress($email, $name);
				$mail->Subject = 'Account Verification';

                      
                $html_message = file_get_contents('../../confirmation_mail.php');
				$html_message = str_replace('%username%', $name, $html_message);
				$html_message = str_replace('%email%', $email, $html_message);
				$html_message = str_replace('%hash%', $hash, $html_message);

                      
                $mail->msgHTML($html_message);
				$alt_message = 'Congratulations, ' . $name . '! You have successfully created a Grammar Captive account./n/r Please click on the link below to verify that you are the owner of the account and to receive the first edition of Seven Gates, the Grammar Captive weekly newsletter./n/r http://www.grammarcaptive.com/email_verify.php?name=' . $name . '&email=' . $email . '&hash=' . $hash;
				$mail->AltBody = $alt_message;

                      
                if (!$mail->send()) {
					echo "Mailer Error: " . $mail->ErrorInfo;
				} else {
					header('Location: ../../gate_confirmation.html');
				}

                      
            }
		}
 

I suppose that the best way for you to help me at this time is to regroup the above code in the matter that you believe will work.   Then, I can test and compare it with Ingolme's explanation and grasp the entire concept in a flash.

Roddy

Edited by iwato

Share this post


Link to post
Share on other sites
Ingolme    794

The concept is simple: All processing first, HTML last. Move all output to the bottom of your code. The first thing in your document should be an opening <?php tag.

The code in your post does not have the HTML in it, which is crucial for understanding how to fix your problem. No HTML can be printed before a header() function call, or session_start() or setcookie() either.

Share this post


Link to post
Share on other sites
iwato    6
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8" />
	<title>Gate Seven - An Invitation and Gift</title>
	<meta name="generator" content="BBEdit 11.6" />
	<link rel="stylesheet" href="../../_utilities/css/gc_splash.css">
	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
	<script>
		$( document ).ready(function() {
			console.log( "ready!" );
			var tongue = 'other_tongue';
			$('#other').hide();
			$('#tongue').change(function() {
				if ($('#tongue').val() == tongue) {
					$('#other').show();
				}
				if ($('#tongue').val() != tongue) {
					$('#other').hide();
				}
			});
		});
	</script>
</head>
<body>

This is the HTML that appears before the <?php tag.  I see no effect on the headers.  All non-essential blank spaces were stripped away.  Actually, there were none.  Only tabs and line breaks remain.

Share this post


Link to post
Share on other sites
Ingolme    794

Headers have to be sent before any content. There should be nothing between the start of the document and the opening <?php tag.

HTTP messages are divided into two sections: The headers and the body. The headers contain information about the page, while the body contains the actual page itself. The headers must always come first. Any header sent after the body was sent will actually be considered part of the body, but rather than doing that PHP will give you a warning instead.

The HTML must go last, after all the PHP, not before it.

Share this post


Link to post
Share on other sites
iwato    6

Firstly, already long ago I tried moving the last, above, displayed section of PHP to the top of the page, but it had no effect.

Secondly, there is PHP contained in the body of the page.

<form id="subscribe" method="post" name="subscribe" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']);?>">
              
<input type="text" name="name" id="name" value='<?php echo $name;?>'>
<input type="checkbox" value="1" id="checkbox1" name="newsletter" <?php if(isset($_POST['newsletter'])) echo 'checked'; ?> />
  
<?php echo '<p><span style="font-size:0.7em; color:#f00;">' . $error_msg . '</span></p>';?>

etc.

I fear that I must do what I was loathe to do at the beginning and believed that this dialogue would inevitably lead me -- separate the email processing page from the form page.  Am I correct?

Edited by iwato

Share this post


Link to post
Share on other sites
Ingolme    794

It's not necessary to separate it into two files. It doesn't matter if there's PHP embedded in the HTML, you just have to put the form processing logic before the code that prints out the HTML.

Do that first, then if you're getting errors find out what's causing them,

Share this post


Link to post
Share on other sites
iwato    6

Please read carefully.  Long ago I tried putting the PHP first, but there was no change.  The header( ) function failed.

Maybe it is because I am using the PHPMailer Autoloader.  It spews out the entire correspondence with the SMTP server, as well as error messages that surely must surely be generated by PHP echo statements.  Then too, the statements are unformatted, so there is likely no HTML contained within.

Roddy

Edited by iwato

Share this post


Link to post
Share on other sites
Ingolme    794

Turn off debugoutput in your PHPMailer settings. That's what's causing the problem. 

You still should have HTML last. If another problem occurs then find out why and fix it.

Share this post


Link to post
Share on other sites
dsonesuk    701

IF the error is one line then its your script showing the error, else if multiple lines it is usually phpmailer's STMPDebug, but your code shows debug as disabled? so you should not be getting any multiple line error messages, and since it is disabled, Debugoutput="html" won't take effect in making outputted error message break into multiple lines using <br>, instead of errors bundled together in a big block of text which is more difficult to read.

The idea is to process the email sent values IF SET, by validation/sanitization and if valid, send email and redirect, before it reaches '<!DOCTYPE html>' else return to form until valid. It does not matter about php within body, as  its the placement of header() function is the key factor here.

Edited by dsonesuk

Share this post


Link to post
Share on other sites
iwato    6

I would like to thank everyone for your patience, encouragement, and most of all your insight.

The failure of the confirmation page to appear has been resolved.  Apparently there were two complications that had been resolved separately, but not together:  one, placing the PHPMailer code ahead of all HTML code, and two, setting the STMPDebug property value to 0.  Doing both of these together appears to have resolved the problem.

Hooray, hooray, hooray!

Roddy

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×