Code:
<?php
include ("conf/conf.php");
include ("classes/dbhelper.php");
$conf = new Dbconf();
$dbURL = $conf->get_databaseURL();
$dbUName = $conf->get_databaseUName();
$dbPword = $conf->get_databasePWord();
$dbName = $conf->get_databaseName();
$nameOfDbWithWorkers = $conf->get_nameOfDbWithWorkers();
if($_POST['auth']){
$login = trim(($_POST['login']));
$pass = trim($_POST['pass']);
$dbHelp = new DbHelper($dbURL, $dbUName, $dbPword, $dbName, $nameOfDbWithWorkers);
$userType = $dbHelp->getUser($login, $pass);
switch ($userType){
case "admin":
startSession($login, $pass);
header("Location: adminpage.php");
break;
case "user":
startSession($login, $pass);
header("Location: operatorpage.php");
break;
case "nomatch":
echo
'<html>
<body>
<table width=100% height=100% border=0 cellpadding=0 cellspacing=0>
<tr valign="center" align="center">
<td>
<form action="authorize.php" method="post">
Логин:<input type="text" name="login"><br>
Пароль:<input type="password" name="pass"><br>
<input type="submit" name="auth">
<font color = red> Неправильный пароль или логин</font>
</td>
</tr>
</table>
</form>
</body>
</html>';
break;
}
}
else{
header("Location: index.php");
}
function startSession($login, $pass){
session_start();
$_SESSION['login'] = $login;
$_SESSION['pass'] = $pass;
$_SESSION['usr_id'] = md5(crypt($login,$pass));
}
When I enter right login and pass information, i have a next errors.
Warning: Cannot modify header information - headers already sent by (output started at Z:\home\ecl.ru\www\classes\dbhelper.php:24) in Z:\home\ecl.ru\www\authorize.php on line 20
Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at Z:\home\ecl.ru\www\classes\dbhelper.php:24) in Z:\home\ecl.ru\www\authorize.php on line 53
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at Z:\home\ecl.ru\www\classes\dbhelper.php:24) in Z:\home\ecl.ru\www\authorize.php on line 53
How to solve this?
You need to start the session before you do anything. Read the docs.
There is something outputted at you file dphelper.php, as the notice says:
Warning: Cannot modify header information - headers already sent by (output started at Z:\home\ecl.ru\www\classes\dbhelper.php:24) in Z:\home\ecl.ru\www\authorize.php on line 20
As headers are sent before any kind of output, your session_start() comes in too late. One suggestion, as people already stated, is to put session_start() on top of the file, another one (could be implemented together with the first one) - to look into dbhelper.php and make sure it does not output anything (from the name of the file - it should not, anyway). And, when I say "output", it is not necessarily echo / print / etc, it could also be white space after the closing php tag at the end of the file.
You can work around this by enabling output buffering, that way the headers will always be sent before the data.
Start your session before using headers
Looking at your code, there isn't any content obviously being sent before session start, however, you have various functions calls. Do any of them output content?
Is that the complete file? Even a line return before <?php will count as content sent to the browser....
Just put session_start(); on top before your includes so when you call your startSession function anywhere in your code it will just set any values you assign to $_SESSION.
Related
This question already has answers here:
How to fix "Headers already sent" error in PHP
(11 answers)
Closed 8 years ago.
I am getting this error:
Warning: Cannot modify header information - headers already sent by (output started at /removed/loginform.php:2) in /removed/loginform.php on line 24
I understand that I am getting the error when I try to set a cookie, and it's because setcookie can't have any output before it... the problem is, there is no output before it (At least from what I can see). It is saying that "< ?php" is a header, and I don't understand that. If setcookie can only be used in PHP and < ?php is a header, how is it even possible to use setcookie without getting this header error?
My code:
<!--Database Connections-->
<?php include "../../includes/dbpractice_con.php"; ?>
<?php
//Declare variables
$username = "";
$password = "";
$message = "";
if ($_SERVER["REQUEST_METHOD"] == "POST") { //Retrieve from form when submit is clicked.
//Escape to prevent SQL injection.
$username = mysqli_real_escape_string($connection, $_POST['username']);
$password = mysqli_real_escape_string($connection, $_POST['password']);
$check = mysqli_query($connection, "SELECT * FROM users WHERE username='$username' AND password='$password'");
$rowCount = mysqli_num_rows($check);
if ($rowCount == 1) {
$cookieExpiration = time() + 757368000; //1 year
setcookie("username", $username, $cookieExpiration);
} else {
$message = "Invalid username or password. <br/>Don't have an account? Click here to register.<br/><br/>";
}
}
?>
<html>
<!--Database Connections--> is HTML output, even if it is just a comment. Remove that and try again.
EDIT:
There is also a space between the PHP blocks. Try putting the include in the main PHP block.
Generally that means you have sent something to client prior to setcookie() call.
Do simple test:
<?php
ob_start();
include "../../includes/dbpractice_con.php"; ?>
# ... rest of your code... #
and before setcookie() call add line
ob_get_clean();
just to be sure that no output was made earlier.
Anything outside of <?php ?> is HTML and is sent to user. So this
<!--Database Connections-->
<?php include "../../includes/dbpractice_con.php"; ?>
outputs <!--Database Connections--> as HTML comment. Another possible output is here
<?php include "../../includes/dbpractice_con.php"; ?>
<?php ...
at least you have new line character between two PHP tags, which is also unwanted output.
You can't have anything to echo, print_r, var_dump data before cookieset() call, check manually for these functions.
Always check all included scripts (with include, require, etc).
BE SURE THEY START WITH <?php WITH NOTHING BEFORE and END WITH ?> FOLLOWING NOTHING.
this is good example:
<?php
// some lines
?>
these aren't
something<?php ?>
or
<?php ?>something
or
<?php ?>
(if file has been saved as UTF-8).
Look at your dbpractice_con.php, check is it saved as ANSI (from notepad check with save as dialog), be sure that everything is between and no one character is before and after the tags. Don't use multiple tags in same script because it increases risk of unwanted output.
Try this:
<?php
// Database connections
include "../../includes/dbpractice_con.php";
//Declare variables
// ... proceed with code ...
If this doesn't work then the problem is probably in dbpractice_con.php
I've made a login, that sets a cookie with a value of the imputed email address, so in the global.php file, it stores an array of the users data using:
$email = $_COOKIE["PeopleHub"];
$getuserdata = mysqli_query($con, "SELECT * FROM Earth WHERE email='$email'");
$userdata = mysqli_fetch_array($getuserdata, MYSQLI_ASSOC);
The cookie isn't being set, I know this because I made a test file:
echo $_COOKIE["PeopleHub"];
It just made a blank page.
The login code (where the cookie is set):
<?php
include "global.php";
?>
<h2>Login</h2>
<?php
echo "We currently have <b>" . $usercount . "</b> members, <b>" . $onlinecount . "</b> of which are online. ";
?>
<br>
<br>
<?php
if(isset($_POST["email"])){
$email = $_POST["email"];
$password = sha1($_POST["password"]);
$check = mysqli_query($con, "SELECT * FROM Earth WHERE `email`='$email' AND `password`='$password'");
$check = mysqli_num_rows($check);
if($check == 1){
setcookie("PeopleHub", $email, 0, '/');
echo "We logged you in!";
}
else {
echo "We couldn't log you in!";
}
}
?>
<form action="<?php echo $_SERVER['REQUEST_URI']; ?>" method="post">
Email <input name="email" placeholder="Email Address" required="" type="text"><br>
Password <input name="password" placeholder="Password" required="" type="password"><br>
<input type="reset" value="Start Over">
<input type="submit" value="Login">
</form>
You have to set cookies before any headers are sent out.
From the manual:
setcookie() defines a cookie to be sent along with the rest of the HTTP headers. Like other headers, cookies must be sent before any output from your script (this is a protocol restriction). This requires that you place calls to this function prior to any output, including and tags as well as any whitespace.
This means you will need to look into output buffering if you wish to use this code as is.
<?php
ob_start();
echo "Hello\n";
setcookie("cookiename", "cookiedata");
ob_end_flush();
?>
Depending on the contents of global.php, this might work for you. All I did was remove any output before setcookie() is called. If global.php contains any whitespace or HTML output in it this won't work:
<?php
include "global.php";
if(isset($_POST["email"])){
$email = $_POST["email"];
$password = sha1($_POST["password"]);
$check = mysqli_query($con, "SELECT * FROM Earth WHERE `email`='$email' AND `password`='$password'");
$check = mysqli_num_rows($check);
if($check == 1){
setcookie("PeopleHub", $email, 0, '/');
echo "We logged you in!";
}
else {
echo "We couldn't log you in!";
}
}
?>
<h2>Login</h2>
<?php
echo "We currently have <b>" . $usercount . "</b> members, <b>" . $onlinecount . "</b> of which are online. ";
?>
<br>
<br>
<form action="<?php echo $_SERVER['REQUEST_URI']; ?>" method="post">
Email <input name="email" placeholder="Email Address" required="" type="text"><br>
Password <input name="password" placeholder="Password" required="" type="password"><br>
<input type="reset" value="Start Over">
<input type="submit" value="Login">
</form>
Just wanted to point out, I had an issue with setcookie not working. When I investigated the file further it was encoded as UTF-8 with BOM. When I re-encoded it as UTF-8 without BOM setcookie worked fine, so the BOM was being written before my first php tag was encountered. I guess enabling buffering in my php.ini file probably would fix this too.
Someone may eventually find this information helpful.
I had the same problem and it turned out that it was caused because the domain I was passing to the function had a custom port (which is not allowed).
I had another problem with cookie update using setcookie function.
So I've set cookie string made from array using php serialize function. From now on I was not able to update that cookie - setcookie function was simply not working, wheather is was setting serialized string or any other simple string.
Then I've set another cookie with new cookie key, this time data was encoded with json_encode function. This time I was able to set the cookie and update it :-)
Mine was a slightly more exotic case: turns out my ad blocker (I use 1Blocker) kills cookies with certain names. In my case it was a cookie name ending with _login. I changed the name and it started working.
Just wanted to add that setcookie was not working for me when the user utilized my website with an url like this: https://mywebsite89898989.com. But when the website url was changed to https://www.mywebsite89898989.com setcookie worked correctly.
I am about as far from an expert as one can be so perhaps someone more knowledgeable can explain this behavior.
I just note this information to hopefully save someone some time debugging...
If you are using XAMPP you may find this helpful: Today I was trying to find the reason for a cookie bug. On my local XAMPP server setcookie() was working fine, but once I uploaded the project to my webhosting it simply stopped working, the cookie was not set. XAMPP uses PHP v8.1.10 and webhosting uses PHP v8.1.16, so version differences are not the cause of the bug.
It turned out my mistake was to output some text before setcookie() was called (so HTTP headers were already sent), but I have no idea why it was working on localhost/XAMPP. It really shouldn't be like that.
I have a button:
<form method="post">
<input name="submit" type="submit" class="icon2" value=" " />
</form>
And a redirect with a header using following code:
<?php
$homepage = '/2013/php/nelson-test.php';
$currentpage = $_SERVER['REQUEST_URI'];
if(isset($_POST['submit']) && $homepage==$currentpage)
{
header('Location:/2013/php/nelson.php');
}
?>
I used the exactly same code yesterday in a different site and it works (I only changed the links), and now it gives me this error:
Warning: Cannot modify header information - headers already sent by (output started at /homez.121/pneuexpo/www/2013/php/nelson-test.**php:1**) in /homez.121/pneuexpo/www/2013/php/nelson-test.php on **line 6**
I don't understand why since in line one I only have the php beginning tag and on line 6 there is only the header. Any ideas?
(BTW the purpose of the button and the header is that when you click the button it redirect to the same page but in English (the page is currently in French))
Remove ';' after this
if(isset($_POST['submit']) && $homepage==$currentpage) //Remove ;
{
header('Location:/2013/php/nelson.php');
exit;
}
try this:
echo("<script>location.href = '/2013/php/nelson.php';</script>");
yes that is correct remove ; from it if you put ; then it interprete as a statement and it will raise error, and before header there should not be output on the page.
as i am gussing your if condition is valid then please add exit
<?php
$homepage = '/2013/php/nelson-test.php';
$currentpage = $_SERVER['REQUEST_URI'];
if(isset($_POST['submit']) && $homepage==$currentpage);
{
header('Location:/2013/php/nelson.php');
exit;
}
?>
remove all white space after
still if you cant remove error than redirect using javascript as follow
echo '<script type="text/javascript">window.location="nelson.php"</script>';
I have a problem with 'setcookie' in PHP and I can't solve it.
so I receive this error "Warning: Cannot modify header information - headers already sent by (output started at C:\Program Files\VertrigoServ\www\vote.php:14) in C:\Program Files\VertrigoServ\www\vote.php on line 86"
and here is the file..
line 86 is setcookie ($cookie_name, 1, time()+86400, '/', '', 0);
is there any other way to do this ??
<html>
<head>
<title>Ranking</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body bgcolor="#EEF0FF">
<div align="center">
<br/>
<div align="center"><div id="header"></div></div>
<br/>
<table width="800" border="0" align="center" cellpadding="5" cellspacing="0" class="mid-table">
<tr><td height="5">
<center>
</tr>
</table>
</center>
</td></tr>
<tr><td height="5"></td></tr>
</table>
<br/>
<?php
include "conf.php";
$id = $_GET['id'];
if (!isset($_POST['submitted']))
{
if (isset($_GET['id']) && is_numeric($_GET['id']))
{
</div></td></tr>
<tr><td align="center" valign="top"><img src="images/ads/top_banner.png"></td></tr>
</table>
</form>
<?php
}
else
{
echo '<font color="red">You must select a valid server to vote for it!</font>';
}
}
else
{
$kod=$_POST['kod'];
if($kod!=$_COOKIE[imgcodepage])
{
echo "The code does not match";
}
else
{
$id = mysql_real_escape_string($_POST['id']);
$query = "SELECT SQL_CACHE id, votes FROM s_servers WHERE id = $id";
$result = mysql_query($query) OR die(mysql_error());
$row = mysql_fetch_array($result, MYSQL_ASSOC);
$votes = $row['votes'];
$id = $row['id'];
$cookie_name = 'vote_'.$id;
$ip = $_SERVER['REMOTE_ADDR'];
$ltime = mysql_fetch_assoc(mysql_query("SELECT SQL_CACHE `time` FROM `s_votes` WHERE `sid`='$id' AND `ip`='$ip'"));
$ltime = $ltime['time'] + 86400;
$time = time();
if (isset($_COOKIE['vote_'.$id]) OR $ltime > $time)
{
echo 'You have already voted in last 24 hours! Your vote is not recorded.';
}
else
{
$votes++;
$query = "UPDATE s_servers SET votes = $votes WHERE id = $id";
$time = time();
$query2 = mysql_query("INSERT INTO `s_votes` (`ip`, `time`, `sid`) VALUES ('$ip', '$time', '$id')");
$result = mysql_query($query) OR die(mysql_error());
setcookie ($cookie_name, 1, time()+86400, '/', '', 0);
}
}
}
?>
<p>[Click here if you don't want to vote]</p><br/>
<p>Ranking.net © 2010-2011<br> </p>
</div>
</body>
</html>
Thanks a lot!
You cannot have any output before header() and setcookie() calls.
https://stackoverflow.com/search?q=+headers+already+sent+by
https://stackoverflow.com/tags/php/info
Any output includes any <html> before the openeing <?php marker, or any print or echoing of content. Another culprit is the UTF-8 BOM http://en.wikipedia.org/wiki/Byte_Order_Mark - which most text editors do not show visibly, but confuses PHP when at the beginning of files.
Setting a cookie requires sending a header to the client, and you can't send headers if the output has already started.
You have to put the PHP code before the HTML markup so that you can call setcookie before any output is sent and you also separate PHP code from presentation which you should do anyway.
You should put the cookie code at the top of the page. A better layout would be something like this:
<?php
//include config
//check posted data (included settings cookies)
//set needed variables
?>
<html>
.....
You could also separated the php code and html. This is generally what i do. My uses generally involve a view class or (in the past) smarty. but a quick example would be to add this code at the bottom of the above php code and get rid of the html:
<?php
if(empty($tpl)) {
$tpl = 'index';
}
if(file_exists("template/{$tpl}.tpl.php")) {
include("template/{$tpl}.tpl.php");
}
else {
header('Location: /');
}
?>
YOu would need to create a directory called 'templates' and add the html code to files that end in the .tpl.php extension.
Really they are just php pages, but the .tpl. part help you remember that its just mark up.
Make them php pages (not html) so you can output variables
Then in your varios parts of your code above you would set $tpl to be the template you want to load.
This is a just a base bit of code, but it should give you a general idea on how to separate this data. THe main idea is that all html and text will be outputted "after" all programming code has been done.
What you need to do is to create a nice buffer to hold all the headers in until you are down processing. ob_start does the job for you and here is a reference to it. http://php.net/manual/en/function.ob-start.php
When you are finished loading all the different headers use ob_get_contents like this
$text = ob_get_contents();
echo($text);
ob_end_clean();
I hope this helps.
You can not use PHP to set a cookie after any thing has been outputted, and the html before the first php tag does count as output. to keep to a purely php method you'd have to move the whole part about determining what to put int he cookie and setting it up to the very top.
or what I do in situations where that would require to much extra work to do it that way is to have php echo out the JavaScript code to set a cookie. now if you make or get a nice JS cookie setting function and either embed it or link it into the page. then all you have to do is have php echo the function call with the proper data in it at that point. then when the page loads while php still will not set the cookie, but when the browser when it runs the js code it will. and so you get what you want the cookie is set. and you did not have to move the stuff up to the top.
This question already has answers here:
How to fix "Headers already sent" error in PHP
(11 answers)
Reference - What does this error mean in PHP?
(38 answers)
Closed 9 years ago.
Please save me. I know that this question has been asked many times, however, I can't seem to find solutions that are relevant to my situation.
The problem: Warning: Cannot modify header information - headers already sent by (output started at /.../Sites/st.ambulance/resources/views/login.view.php:32) in /.../Sites/st.ambulance/resources/controllers/tables_.php on line 47
This is the code block with line 32:
<label>Month</label>
<select name="dob_month">
<?php for($i=0,$j=1;$i<sizeof($month);$i++,$j++){ ?>
<option value="<?php h($j) ?>"><?php h($month[$i]) ?></option> //line 32
<?php } ?>
</select>
The definition of the h function:
function h($s){
echo(htmlspecialchars($s,ENT_QUOTES));
}
This is tables_.php:
<?php
$error = "";
if(isset($_POST['guest_tables'])){
if(isset($_SESSION['logged_in']) && $_SESSION['logged_in']){
$guest = array();
$volunteer = array();
$guest = isset($_POST['guest']) ? $_POST['guest'] : null;
$volunteer = isset($_POST['volunteer']) ? $_POST['volunteer'] : null;
$seat_array = array($volunteer['seat_no'].$volunteer['table']);
$seat_count = 0;
$table_seat_error = "";
if($form->is_seatOccupied($volunteer['table'],$volunteer['seat_no']) != "")
$table_seat_error .= "Seat (".$volunteer['seat_no'].")
at table (".$volunteer['table'].") is currently occupied";
if($_SESSION['no_guests'] >= 1){
if($guest && $volunteer){
foreach($guest as $gue){
$seat_table = $gue['seat_no'].$gue['table'];
for($h=0;$h<sizeof($seat_array);$h++){
if($seat_table == $seat_array[$h] )
$seat_count = $seat_count + 1;
}
if($form->is_seatOccupied($gue['table'], $gue['seat_no']) != "")
$table_seat_error .= "Seat (".$gue['seat_no'].")
at table (".$gue['table'].") is currently occupied";
$seat_array[] = $seat_table;
}
if($seat_count == 0){
if($table_seat_error == ""){
for($d=0;$d<$_SESSION['no_guests'];$d++){
$_SESSION['guests'][$d]['table'] = $guest[$d]['table'];
$_SESSION['guests'][$d]['seat'] = $guest[$d]['seat_no'];
}
$_SESSION['volunteer']['table'] = $volunteer['table'];
$_SESSION['volunteer']['seat'] = $volunteer['seat_no'];
$form->set_guests($_SESSION['guests']);
$form->set_volunteer($_SESSION['volunteer']);
header('location: /branch/menus.php'); //line 47
exit();
}
else{
$error = $table_seat_error;
}
}
else{
$error = "You have selected the same seat for two or more
people: one person, per seat, per table. Only.";
}
}
}
else{
$_SESSION['volunteer']['table'] = $volunteer['table'];
$_SESSION['volunteer']['seat'] = $volunteer['seat_no'];
if(!$form->is_seatOccupied($_SESSION['volunteer']['table'],
$_SESSION['volunteer']['seat']) != ""){
$form->set_volunteer($_SESSION['volunteer']);
header('location: /branch/menus.php');
exit();
}
}
}
}
?>
EDIT: would it help to know that I'm trying to handle multiple forms on a single page?
Line 47 modifies the response headers:
header('location: /branch/menus.php'); //line 47
Line 47 cannot be executed because the headers have already been sent, which happened to occur on line 32. All that happened on line 32 was that PHP decided it had enough content in the response to start sending it back to the browser.
Generally, if you want to modify the headers (whatever you're doing on line 47), you need to do it at the very beginning of the file.
This is a good time to learn about the MVC design pattern - it would eliminate the possibility of this issue in the future. In MVC, the Controller executes first, and prepares everything for the View. So, you can modify your headers all you want in the Controller, and they won't be sent until during or after the View is processed.
EDIT: It looks like you are using MVC, but somehow your view is executing before the controller has started (or perhaps finished)... that shouldn't happen! Unfortunately, the code you've posted doesn't illustrate how either the controller or view are being accessed... but they're being accessed out of order.
As TRiG point out in the comments below, you probably want to insert an exit() statement after line 47 as follows:
header('location: /branch/menus.php'); //line 47
exit();
This will cause the server to immediately send the Location redirect to the browser, and the request/response cycle is complete. All your header('Location: ...'); calls should be immediately followed by exit();. This doesn't fix the issue at hand, but it is very important.
switch on output buffering, locate php.ini and look for / uncomment / change / add the following line:
output_buffering = On
edit: and include a line saying ob_start(); in some initial include, like some common init.php or database.php
edit^2: the ob_start is not needed (anymore?); this works, save as test.php and request. Seeing is believing.
Output has started
<?php
header("Content-Type: text/plain");
?>
The point is that in HTTP the response of the server consists of 2 parts: the headers and the body.
The headers contain information about the content, the connection etc, like what type of content, e.g.
Content-Type: text/html
or
Content-Type: image/jpeg
indicating it's html or jpg. Without it, the browser wouldn't be sure what to do with the content. Of course once PHP has to start outputting the body part of the response, there's no way to change the header. So you can either do anything header-related first before emitting any byte of the body, or you could instruct php to hold it's breath and emit the body only when the script is done, or when you say so. And that's what they call output buffering.