This question already has answers here:
How to fix "Headers already sent" error in PHP
(11 answers)
Closed 6 years ago.
I built a website locally with WAMP server, and everything worked fine, then ported over to web server on GoDaddy, and my redirect function suddenly stopped working.
Simple site at (www.minute.tech), you can test out the one form I have, goes to the form_processing.php, but should redirect back to the index page with a message. When you go back to the index page after the failed redirect, it still shows the proper message of "Booyah!...", and inputs the email into my database.
Any ideas why it won't redirect on my web server, but will on my local WAMP server with the same code? Cheers!
Here's my redirect function in sessions.php:
function redirect_to($new_location) {
header("Location: " . $new_location);
exit();
}
Here's process_email.php where I redirect:
<?php require_once("sessions.php"); ?>
<?php require_once("db_connection.php"); ?>
<?php require_once("functions.php"); ?>
<?php
if(isset($_POST['submit']) && !empty($_POST['email'])){
//Process form
$email = $_POST['email'];
$email = mysql_prep($email);
$techcheck = (isset($_POST['techcheck'])) ? 1 : 0;
// 2. Perform database query
$query = "INSERT INTO signups (";
$query .= " email, techcheck";
$query .= ") VALUES (";
$query .= "'{$email}', $techcheck";
$query .= ")";
$result = mysqli_query($connection, $query);
if ($result) {
// Success
$_SESSION["good_message"] = "Booyah! We will keep you posted on progress.";
redirect_to("../index.php");
} else {
//Failure
$_SESSION["bad_message"] = "Failed to accept email.";
redirect_to("../index.php");
}
} else {
//This can be an accidental GET request
$_SESSION["bad_message"] = "That is not a valid email! Please try again.";
redirect_to("../index.php");
}
?>
You have to start object for header function sometimes
Add this code to all pages
<?php ob_start(); ?>
Do with JS.
<?php
function redirect_to($new_location) { ?>
<script>window.location="<?php echo $new_location; ?>";</script>
<?php } ?>
Remove all the empty spaces. Some server set-ups will be okay with output before the header redirect but the vast majority of servers will not redirect properly. Turn on error reporting and it will probably tell you have output before the redirect:
<?php
// ^---- Just do one open tag
require_once("sessions.php"); // Remove close tag, possible empty space after
require_once("db_connection.php"); // Remove close tag, possible empty space after
require_once("functions.php"); // Remove close tag, possible empty space after
// Remove the close and open php tags
if(isset($_POST['submit']) && !empty($_POST['email'])){
//Process form
$email = $_POST['email'];
$email = mysql_prep($email);
$techcheck = (isset($_POST['techcheck'])) ? 1 : 0;
// 2. Perform database query
$query = "INSERT INTO signups (";
$query .= " email, techcheck";
$query .= ") VALUES (";
$query .= "'{$email}', $techcheck";
$query .= ")";
$result = mysqli_query($connection, $query);
if ($result) {
// Success
$_SESSION["good_message"] = "Booyah! We will keep you posted on progress.";
redirect_to("../index.php");
} else {
//Failure
$_SESSION["bad_message"] = "Failed to accept email.";
redirect_to("../index.php");
}
} else {
//This can be an accidental GET request
$_SESSION["bad_message"] = "That is not a valid email! Please try again.";
redirect_to("../index.php");
}
// If you have no more content below this point, just remove the close php tag
// it is not required and is a possible source of empty space down the line...
Also, you should not be using mysql_ anymore, it is deprecated and removed in PHP 7. Also, bind parameters instead of doing this parameter right into the sql:
$query .= "'{$email}', $techcheck";
Related
I have a page that connects to a MySQL database via PHP. On this page the data is fetched to load an image and its related details. This page all work OK when the page is loaded.
I also have a module included on this page where users can create a board (which will hold images) along a certain theme.
On other pages this board module works OK, but on a page where a $_GET request happens, which is needed to identify a user's username or an image filename (depending on the page), the board module doesn't work correctly. When you create a new board it fails and I get a PHP error saying Undefined variable: filename in with reference to the line of code ':filename' => $filename in the execute function below.
When this boards module is used to create a new board name I have some JavaScript fetch() code on the page that prevents a hard refresh. I'm not sure if this is causing the problem (although this JS is also used on the pages that don't have a problem, i.e. no $_GET request). On pages where this is no $_GET request everything works as expected.
Note: in the code below $connection is the database connection from a db.php file
PHP on pageload that loads the image and related data
isset($_GET['filename']) ? $filename = $_GET['filename'] : header("Location: login.php");
$image_stmt = $connection->prepare("SELECT * FROM `lj_imageposts` WHERE `filename` = :filename");
$image_stmt -> execute([
':filename' => $filename // variable that returns the error
]);
$image_row = $image_stmt->fetch();
// if the GET url parameter doesn't exist/changed
if ($image_row == 0) { header ("Location: index.php"); exit; }
$db_userid = htmlspecialchars($image_row['user_id']);
$db_image_id = htmlspecialchars($image_row['image_id']);
$db_image_title = htmlspecialchars($image_row['image_title']);
$db_image_filename = htmlspecialchars($image_row['filename']);
$db_image_ext = htmlspecialchars($image_row['file_extension']);
$db_username = htmlspecialchars($image_row['username']);
?>
---- HTML OUTPUT THAT INCORPORATES THE ABOVE VARIABLES
PHP for the boards module
if (isset($_POST['submit-board-name'])) {
$create_board_name = $_POST['create-board-name'];
if(strlen(trim($create_board_name)) < 10) {
$error[] = "Board name must be at least 10 characters long";
}
if(strlen(trim($create_board_name)) > 150) {
$error[] = "Board name can be at less than 150 characters long";
}
if(!isset($error)) {
try {
$createBoardSQL = "INSERT INTO lj_boards (board_name, user_id) VALUES (:board_name, :user_id )";
$bstmt = $connection->prepare($createBoardSQL);
$bstmt->execute([
':board_name' => $create_board_name,
':user_id' => $db_id
]);
} catch(PDOException $e) {
echo "Error: " . $e->getMessage();
}
}
} else {
// give values an empty string to avoid an error being thrown before form submission if empty
$create_board_name = "";
}
This first line is unnecessarily cryptic, making the mistake harder to spot (and harder to fix):
isset($_GET['filename']) ? $filename = $_GET['filename'] : header("Location: login.php");
It's pretending to be an expression, but it's actually an if statement in disguise - it consists of nothing but side effects. Let's write it out more clearly:
if ( isset($_GET['filename']) ) {
$filename = $_GET['filename'];
}
else {
header("Location: login.php");
}
Now we can look more clearly at what each branch does:
The if branch sets a variable. If the code takes that branch, everything should be fine.
The else branch sets a header to be included when PHP sends the response. It doesn't do anything else, and it doesn't set the variable, so if this path is taken, you'll have a problem later.
What you probably intended to happen was for the else branch to set that header and then immediately stop processing. For that you need an exit; statement (also known as die;
if ( isset($_GET['filename']) ) {
$filename = $_GET['filename'];
}
else {
header("Location: login.php");
exit;
}
I'm having trouble with a PHP script which apparently is getting errors from one single line. The top line in this bit of code is apparently causing quite a bit of trouble:
if (move_uploaded_file($_FILES["image"]["tmp_name"], "./upload/".$imageName)) {
mysql_query("INSERT " .$pages. " SET inmenu='$inmenu', pagid='$pagid', title='$titlename', content='$contentname', image='$image', youtube='$youtube'")
or die(mysql_error());
header("Location: index.php");
}
The errors I'm getting for the top line of code:
Warning: Unexpected character in input: ' in cms/new.php on line 131
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at cms/new.php:131) in cms/new.php on line 85
First I thought CHmodding the upload folder to 777 would solve this error, but apparently it doesn't. I really don't know what to do anymore. Is there anyone who can help?
The complete block of code that includes the little snippet above:
<?php
}
session_start();
if(!isset($_SESSION['username'])){
header("location:login.php");
}
include("config.php");
// check if the form has been submitted. If it has, start to process the form and save it to the database
if (isset($_POST['submit']))
{
//set root
$root = getcwd ();
// get form data, making sure it is valid
$inmenu = mysql_real_escape_string(htmlspecialchars($_POST['inmenu']));
$pagid = strtolower(str_replace(" ", "-", mysql_real_escape_string(htmlspecialchars($_POST['pagid']))));
$titlename = mysql_real_escape_string(htmlspecialchars($_POST['title']));
$contentname = mysql_real_escape_string(htmlspecialchars($_POST['contentedit']));
$youtube = mysql_real_escape_string(htmlspecialchars($_POST['youtube']));
// check to make sure both fields are entered
if ($titlename == '' || $pagid == '')
{
// generate error message
$error = 'ERROR: Please fill in all required fields!';
// if either field is blank, display the form again
renderForm($pagid, $titlename, $contentname, $error);
}
else
{
if(file_exists($root."/upload/".$_FILES["image"]["name"]))
{
$filename = explode(".",$_FILES['image']['name']);
$randomnumber = rand(0, 10000);
$imageName = $filename[0].$randomnumber.".".$filename[1];
}
else
{
$imageName = $_FILES['image']['name'];
}
$image = mysql_real_escape_string(htmlspecialchars("/upload/".$imageName));
if (move_uploaded_file($_FILES["image"]["tmp_name"], "./upload/".$imageName)) {
// save the data to the database
mysql_query("INSERT " .$pages. " SET inmenu='$inmenu', pagid='$pagid', title='$titlename', content='$contentname', image='$image', youtube='$youtube'")
or die(mysql_error());
// once saved, redirect back to the view page
header("Location: index.php");
}
else {
// save the data to the database
mysql_query("INSERT " .$pages. " SET inmenu='$inmenu', pagid='$pagid', title='$titlename', content='$contentname', youtube='$youtube'")
or die(mysql_error());
// once saved, redirect back to the view page
header("Location: index.php");
}
}
}
else
// if the form hasn't been submitted, display the form
{
renderForm('','','');
}
?>
When using double quotes you can just insert PHP variables so
Try this:
if (move_uploaded_file($_FILES["image"]["tmp_name"], "./upload/".$imageName)) {
$query = "INSERT " . $pages . SET inmenu=$inmenu, pagid=$pagid, title=$titlename, contenct=$contentname, image=$image, youtube=$youtube";
mysql_query($query) or die(mysql_error());
header("Location: index.php");
}
Another way (if you'd like) would be this:
if (move_uploaded_file($_FILES["image"]["tmp_name"], "./upload/".$imageName)) {
mysql_query("INSERT " .$pages. " SET inmenu='".$inmenu."', pagid='".$pagid."', title='".$titlename."', content='".$contentname."', image='".$image."', youtube='".$youtube."'")
or die(mysql_error());
header("Location: index.php");
}
I'm having issues to send an occuring error to another page.
I have already created the page the error will be sent to, and I've tried a header function. But that doesn't seem to work. Here is the php code that I am using for the page.
<?php
if(isset($_POST['username'], $_POST['password'])){
//login the user here
$connect = mysql_connect("","","")or die(mysql_error());
mysql_select_db("")or die(mysql_error());
$errors = array();
$username = strip_tags(mysql_real_escape_string($_POST['username']));
$password = strip_tags(mysql_real_escape_string($_POST['password']));
if (empty($Regi_Username) || empty($Regi_password)) {
$errors[] = 'All fields are requerid';
} else {
if (strlen($Regi_Username) > 25) {
$errors[] = 'Username is to long';
}
if (strlen($password) > 25) {
$errors[] = 'Password is to long';
}
}
$password = md5($_POST['password']);
$loginquery = "SELECT * FROM regi WHERE username='$username' and password='$password'" or die(mysql_error());
$result = mysql_query($loginquery);
$count = mysql_num_rows($result);
mysql_close();
if($count==1){
$seconds = 2000 + time();
setcookie(loggedin, date("F jS - g:i a"), $seconds);
header("location:member.php");
} else {
echo 'Wrong username and password please try agian.';
}
}
?>
Pass the GET variable in your URL like..
header('Location:page.php?err=1');
exit;
On the other page use this
if(isset($_GET['err'] && $_GET['err'] == 1) {
echo 'Error Occured';
}
Here is a session based approach. This is the best way to pass messages from one page to another as they are stored in the user's session (a piece of data related to each user and stored in the server side) and not in the browser (like cookies or URL GET parameters, which can be easily corrupted), so it is really quite harder to manipulate the messages from 3rd parties.
Page process.php:
<?php
// Very top of your page
session_start();
$_SESSION['errors'] = array();
// Do stuff now...
// ...
// Hey it's a X error!
$_SESSION['errors']['X'] = 'Message for X error';
// Continue doing stuff...
// ...
// OMG! It's a Y error now!
$_SESSION['errors']['Y'] = 'Message for Y error';
// Keep doing stuff till you're done...
// All right, process is finished. Any Errors?
if (count($_SESSION['errors']) > 0) {
// It seems there's been any errors
// time to redirect to error-displaying page
header('Location: error-page.php');
exit;
}
Page error-page.php:
<?php
// Very top of your page
session_start();
// Let's check if there is any error stored in the session.
// In the case no errors found, it is better to redirect to another page...
// ...why anybody would end in this page if no errors were thrown?
if (!isset($_SESSION['errors']) || !is_array($_SESSION['errors']) || empty($_SESSION['errors'])) {
header('Location: home.php');
exit;
}
// If we reach this point it means there's at least an error
foreach ($_SESSION['errors'] as $errorCode => $errorMessage) {
// Here we can display the errors...
echo '<p>Error ', $errorCode, ': ', $errorMessage, '</p>', PHP_EOL;
}
// You can also do stuff only if a certain error is received
if (array_key_exists('X', $_SESSION['errors'])) {
// Error `X` was thrown
echo '<p>Oh no! It seems you suffered a X error!!</p>', PHP_EOL;
echo 'Click here to go back home.', PHP_EOL;
}
// At the end you should to remove errors from the session
$_SESSION['errors'] = array();
// or
unset($_SESSION['errors']);
You could use Alien's method, but it'd better if you use Session:
// Assume you init the session already; Use json_encode since you use array for $errors
$_SESSION['errors_msg'] = json_encode($errors);
header("location:member.php");
// Remember to exit here after we call header-redirect
exit;
Besides, there are a lot of problems is your currently code:
Use salt for hashing password
Use mysqli over mysql
Filtering input, escaping output
.. Read other recommendations here in this topic ..
Please read http://www.phptherightway.com/. There is a lot of right recommendation (of course not all) for PHP.
If you visit my script "page.php" in the URL. A 500 Error appears. If you submit through a form it works.
<?php
## send forgot pass
$a=$_REQUEST['email_address'];
include("template.funcs.php");
$yz = mysql_connect("","","");
mysql_select_db("", $yz);
$b=mysql_real_escape_string($a);
$d=mysql_query("SELECT * FROM `customers` WHERE `customers_email` = '".$b."'");
if (mysql_affected_rows()==0){
header("Location: cart.php?pass=notsent");
}else{
send_registration_email($b,'','','');
header("Location: cart.php?pass=sent");
}
mysql_close($yz);
?>
A 500 error is a server side error, and I've found the best way to fix this is to check the logs on your server.
On the other hand, looking at your code, you may not have defined $_REQUEST['email_address']. Try this:
<?php
if (isset($_REQUEST['email_address'])) {
## send forgot pass
$a=$_REQUEST['email_address'];
include("template.funcs.php");
$yz = mysql_connect("","","");
mysql_select_db("", $yz);
$b=mysql_real_escape_string($a);
$d=mysql_query("SELECT * FROM `customers` WHERE `customers_email` = '".$b."'");
if (mysql_affected_rows()==0){
header("Location: cart.php?pass=notsent");
}else{
send_registration_email($b,'','','');
header("Location: cart.php?pass=sent");
}
mysql_close($yz);
}
?>
I would assume this has something to do with $_REQUEST['email_address'] not being defined on normal page load...
Use useful variable names. Use indenting appropriately. Only escape input before inserting it into your database. Group often used functionality in functions. Don't use $_REQUEST. Fail fast. A few hints which massively increase your code quality.
Now have a look at this:
include("template.funcs.php");
function Redirect($to)
{
header("Location: " . $to);
exit();
}
if ($_SERVER['REQUEST_METHOD' != "POST" || !isset($_POST['email_address']))
{
Redirect("cart.php?pass=notsent");
// or redirect to your "forgot password" form
}
$mailAddress = $_POST['email_address'];
$dbconn = mysql_connect("","","");
mysql_select_db("", $dbconn);
mysql_query("SELECT * FROM `customers` WHERE `customers_email` = '".mysql_real_escape_string($mailAddress)."'");
if (mysql_affected_rows() == 0)
{
Redirect("cart.php?pass=notsent");
}
send_registration_email($mailAddress,'','','');
Redirect("cart.php?pass=sent");
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Headers already sent by PHP
I am getting the following error from the following code, and I am not entirely sure why. If you could tell me how to fix it, that would be great. Thanks in advanced.
Warning: Cannot modify header information - headers already sent by (output started at...) on line 45.
<?php
// Initialization
$conn = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD);
mysql_select_db(DB_NAME, $conn);
// Error checking
if(!$conn) {
die('Could not connect ' . mysql_error());
}
// Localize the GET variables
$ref = isset($_GET['ref']) ? $_GET['ref'] : "";
// Protect against sql injections
// Insert the score
$retval = mysql_query("INSERT INTO $table(
site
) VALUES (
'$ref'
)",$conn);
if($retval) {
echo "Successfull";
} else {
echo "Unsuccessfull " . mysql_error();
}
mysql_close($conn);
?>
<?php
$url = $_GET['url'];
$loc = 'Location: '. $url;
header($loc);
exit;
?>
Take out the echo calls, you can't send information to the browser before the headers.
You can try something like this to still show if an error happens:
if(!$retval) {
echo "Unsuccessfull " . mysql_error();
}
If you change the headers you cannot output any text prior to to the header command otherwise the headers will already be sent.
ie.
if($retval) {
echo "Successfull";
} else {
echo "Unsuccessfull " . mysql_error();
}
Is outputting text before you change the headers.
Use Output Buffers: http://php.net/manual/en/function.ob-start.php
ob_start();
at the start and
ob_end_flush();
at the end.
What I generally recommend for situations like this, is save all output to the end, as gmadd mentioned, you can do the ob_start, but I prefer to store the data in a string without having to add the extra code (I know you can also designate this in the .htaccess file, I would go that route over adding the actual ob_start items).
What I would do:
$display = ""; // initiate the display string
// etc doe here
if($retval) {
$display .= "Successfull";
} else {
$display .= "Unsuccessfull " . mysql_error();
}
// end of the script right before ?>
echo $display;
?>
The ob_start method works and if you want to go that route, you can add this in the .htaccess file (given that allowoverride is set in your apache setup):
php_value output_buffering On
Again I still recommend the $display storage method, but that is my personal opinion.
Use:
<meta http-equiv="Refresh" content="0;url=http://www.example.com" />