Link to home
Start Free TrialLog in
Avatar of Adam
AdamFlag for United Kingdom of Great Britain and Northern Ireland

asked on

My redirect isn't working on my live server

Hello. I am trying to add information into a database  via a php form page and then redirect onto another page after the submit button has been pressed and the table populated.

This works as intended when I am testing on my local server but when I try it on a live server I get the following errors (I turned error reporting on) and the page where it's supposed to be redirected to (welcome.php) doesn't appear.  However, the sql table (in the live server) is being populated with the form info.  

Erros:


Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at /home/orango5/public_html/form_studentjoin.php:1) in /home/orango5/public_html/private/initialize.php on line 6

The code on initilize.php line 6 is:

session_start();

Open in new window


Warning: Cannot modify header information - headers already sent by (output started at /home/orango5/public_html/form_studentjoin.php:1) in /home/orango5/public_html/form_studentjoin.php on line 41

The code on studentjoin.php line 41 is:
header('Location: welcome.php?id=' . $new_id);

Open in new window


I considered using something else for the redirect -
echo "<script>location.href='welcome.php';</script>";
but I want to be able to pass through the id am not sure how to do this with that javascript.

If it helps the code which I am using for the form (form_studentjoin.php) is below:

<?php require_once('private/initialize.php'); ?>
<?php include('header_NEWpaypalsignup.php');?>
<?php $page_title = 'Payment Successful - Welcome to Orango'; ?>


<?php

//require_login(); - When we are getting directed from the paypal site we will not require a login (however this is a bad system and needs to be updated otherwise people can come straight to this page - at least ensure it can;t be crawled)

if(is_post_request()) { //We are Posting to this page from this page 
  $student = [];			//we are creating an array called student and filling it with the items in the form
  $student['firstname'] = isset($_POST['firstname'])?$_POST['firstname']:'';
  $student['famname'] = isset($_POST['famname'])?$_POST['famname']:'';
  $student['email'] = isset($_POST['email'])?$_POST['email']:'';
  
  $student['language'] = isset($_POST['language'])?$_POST['language']:'';
  $student['prefecture'] = isset($_POST['prefecture'])?$_POST['prefecture']:'';
  $student['source'] = isset($_POST['source'])?$_POST['source']:'';
  $student['contactable'] = isset($_POST['contactable'])?$_POST['contactable']:'';
  
  $student['password'] = isset($_POST['password'])?$_POST['password']:'';
  $student['confirm_password'] = isset($_POST['confirm_password'])?$_POST['confirm_password']:'';
  
  
  
  $result = insert_student($student);
  
  //We use the 'insert_student'function, passing a string of '$student - i.e the array. The function is defined at 'sql_query_functions.php' SHown below
  
     
  
  if($result === true) {
    $new_id = mysqli_insert_id($db_connection); //existing mysql function - not one we created
    $_SESSION['message'] = 'Student created.';
	
	   //echo "<script>location.href='welcome.php';</script>"; //java script performing the redirect
	  
	  //redirect_to ('welcome.php?id=' . $new_id); //redirect to here:
     header('Location: welcome.php?id=' . $new_id);
	
    
  } else {
    $errors = $result;
  }

} else {
  // display the blank form
  $student = [];
  $student["firstname"] = '';
  $student["famname"] = '';
  $student["email"] = '';
  
  $student["language"] = '';
  $student["prefecture"] = '';
  $student["source"] = '';
  $student["contactable"] = '';
  
  $student["password"] = '';
  $student["confirm_password"] = '';
 
  }



?>

Open in new window



And the welcome page which it is supposed to go to is:

<?php require_once('private/initialize.php'); ?>
<?php include('header.php');?>
<?php $page_title = 'Welcome to Orangutan Japan'; ?>
<?php include('navbar.php');


ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

?>

<?php
mysqli_report(MYSQLI_REPORT_ALL);

//require_login(); - In this situation the user does not have to be logged in a s/he is coming from the paypal page

$id = isset($_GET['id'])?$_GET['id']:'1';
//echo "$id";
$student = find_student_by_id($id);

	/*function find_student_by_id($id)
	{ //so this function should return an associated array called teacher which has all teacher propertuies associated to that ID
    global $db_connection;

    $sql = "SELECT * FROM students_table";
    $sql .= "WHERE id='" . $id . "' ";
   
    $result = mysqli_query($db_connection, $sql);
    confirm_result_set($result);
    
	$student = mysqli_fetch_assoc($result); // find first
    mysqli_free_result($result);
    return $student; // returns an assoc. array called teacher
	}*/




?>

Open in new window


Many thanks,

Adam
Avatar of gr8gonzo
gr8gonzo
Flag of United States of America image

First, the problem is actually described here:
"headers already sent (output started at /home/orango5/public_html/form_studentjoin.php:1)"

It's saying that there is probably some whitespace (blank lines, spaces, tabs, etc...) on line 1 of form_studentjoin.php. As soon as PHP encounters ANYTHING that can be considered "content", it stops allowing you to process the headers (there are exceptions but that's the basic idea). So just clear the content from line 1 on that file and you should be good to go.

Also, whenever you use header() to redirect to a new location, issue a die() or exit() command afterwards:

header("Location: newlocation");
exit();

Otherwise, PHP will continue to process the rest of the code until it finishes the script, and the rest of the code might override that earlier header or might have unintended results.
ASKER CERTIFIED SOLUTION
Avatar of gr8gonzo
gr8gonzo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of noci
noci

what would be wrong with:

echo "<script>location.href='welcome.php?id=".$new_id."';</script>";

A href is (should be( just an URL.
Alternatively, if you don't want to change the approach you already have, then you'll need to use output buffering. My guess is that output buffering is turned on by default on your non-live server, if it works there. To enable it via code, just add:
ob_start(); to the beginning of your script:

<?php ob_start(); require_once('private/initialize.php'); ?>

That will start an output buffer so that instead of content immediately being sent out when PHP encounters any, the content will get stored into a buffer until the end of the script. This means that since no content is actually sent until the end, you can manipulate headers all day long if the buffer has started before any output was sent.
Don't use a Javascript when you can do it with a PHP location redirect. The PHP approach is much cleaner and can avoid unnecessary downloading of page content.
why Your Error showing..?
"Headers already sent" means that your PHP script already sent the HTTP headers, and as such it can't make modifications to them now.

Check that you don't send ANY content before calling session_start. Better yet, just make session_start the first thing you do in your PHP file (so put it at the absolute beginning, before all HTML etc).



redirect your page without using header location function
<?php
echo"<script>window.location.href=' '</script>";

Open in new window


Definitely it will work
Avatar of Adam

ASKER

Many thanks great Gonzo. This worked exactly as you said.

It's great waking up to see a solution to something which resolves it completely after spend hours puzzling over it the day before.

Many thanks and have a great weekend.
Avatar of Adam

ASKER

Alternatively, if you don't want to change the approach you already have, then you'll need to use output buffering. My guess is that output buffering is turned on by default on your non-live server, if it works there. To enable it via code, just add:
ob_start(); to the beginning of your script:

<?php ob_start(); require_once('private/initialize.php'); ?>

Also I never tried this approach, but I did have the line
ob_start(); 

Open in new window

in my initialize.php file already (wasn't sure why - from a previous tutorial I suspect).  Would I have had to have added

<?php ob_start(); require_once('private/initialize.php'); ?> to here, like this? - Good to know for future endevours:


<?php ob_start(); require_once('private/initialize.php'); ?>
<?php require_once('private/initialize.php'); ?>
<?php include('header_NEWpaypalsignup.php');?>
<?php $page_title = 'Payment Successful - Welcome to Orango'; ?>

Open in new window


Thanks....
It's good to have spent hours on it already without a solution - the best way to retain anything is to spend a lot of time on it, especially if that time SEEMS unproductive. That "breakthrough" feeling is like mental cement, so don't feel like you wasted any time.

As far as ob_start() being in the other file, I guess it depends on when ob_start() is executed in the overall flow, or if the output buffer is ended later on in that same script.

Every HTTP response has 2 sections - the header and the footer. Since PHP is building that response, it's up to PHP to determine which part it is working on.

By default, as PHP sends content to the output, that content is immediately sent back to the browser. So the moment that any non-header content (even a line break outside of the <?php ... ?> block) is sent to the output, that's when PHP says, "Okay, since you want to send some body content, and the end user's browser will need the HTTP header before it can receive HTTP body content, I need to go ahead and generate and send the HTTP headers that have been configured."

And once that HTTP response has been sent to the browser, it's like mailing a letter. You can't go back and change the contents of the letter after it's been mailed.

If you run ob_start() before ANY output, then instead of sending stuff back right away, it will store everything in memory and let you manipulate it at any time until the end of the script, at which point it will take whatever is currently in the buffer and send it all back to the browser at once.