I've a server where I test everything before setting it in my main server. The issue appears when i'm setting a cookie with setcookie();
I'm using a cookie to set a session with ajax, the code is this:
require '../init.php';
$user = $_POST['user'];
$pass = $_POST['pass'];
$newhash = createHash();
//LOGIN STUFF
if(strtolower($user) == strtolower($userA['user']))
{
if($pass == $userA['pass'])
{
$expiration = ( time() + ( 24 * 60 * 60 * 365) );
setcookie('session', $newhash, $expiration, '/');
$userAdd = MYSQL_::Bits("INSERT INTO users_sessions (hash,userid) VALUES ('$newhash','$userAID')");
//LOGIN STUFF
}
else
{
$datos = array('response' => 'fail','reason' => 'pass');
}
}
else
{
$datos = array('response' => 'fail','reason' => 'user');
}
header('Content-Type: application/json');
echo json_encode($datos, JSON_FORCE_OBJECT);
This code works perfectly on localhost, but when I put it in my main host it doesn't. I've been reading all this related posts on stackoverflow and no one has the solution, it says that there can't be nothing before the cookie but it'd be impossible to set the cookie with nothing before it. I wish someone had the answer :-(
You have output somewhere in init.php or any files init includes.
The output can be direct, as in a echo.
Or a space before the PHP tag or I think even an error/notice created by PHP.
As I wrote in comments find out where your output is, we can't help you with that.
You can as mentioned move then setcookie around in your code and see where it works and where it doesn't work.
When it stops working you have found the line that creates an output.
Related
This question already has answers here:
How to fix "Headers already sent" error in PHP
(11 answers)
Closed 3 years ago.
I am getting this error:
An error Occured in script '/home/path/to/file/php' on line 35:Cannot modify header information - headers already sent by (output started at /home/path/to/file/to/header.html:7)
I understand that I am getting the error when I try to set a cookie, and I know that the setcookie can't have any output before it... the problem is there, I have to add the include file for database connection and redirection of file. So I have added the setcookie after the include file. I also tried putting the setcookie above the include file, but it doesn't also help.
My Code
<?php # Script 2.5 - main.inc.php 2 3
// Redirect if this page was accessed directly:
if (!defined('BASE_URL')) {
// Need the BASE_URL, defined in the config file:
require('../includes/config.inc.php');
// Redirect to the index page:
$url = BASE_URL . 'index.php?p=vote';
header ("Location: $url");
exit;
}
$vote = new Vote;
//get vote and options data
$voteData = $vote->getVotes();
//if vote is submitted
if(isset($_POST['voteSubmit'])){
$votesData = array(
'vote_id' => $_POST['voteID'],
'vote_option_id' => $_POST['voteOpt']
);
//insert vote data
$voteSubmit = $vote->vote($votesData);
if($voteSubmit){
//store in $_COOKIE to signify the user has voted
setcookie($_POST['voteID'], 1, time()+60*60*24*365); //Error Occurs here
$statusMsg = 'Your vote has been submitted successfully.';
}else{
$statusMsg = 'You cannot vote more than once.';
}
}
?>
//The html form code goes here
I have also tried
setcookie($_POST['voteID'], 1, time()+60*60*24*365, '\');
and
setcookie($_POST['voteID'], 1, time()+60*60*24*365, '\', domainName);
But these also didn't solve my problem.
Also I have created a new file named it as test.php and tested the following code.
<?php
$cookie = 'test';
$cookie_name = "cookieName";
$cookie_value = $cookie;
setcookie($cookie_name, $cookie_value, time() + (86400 * 365));
if((isset($_COOKIE[$cookie_name])) && ($_COOKIE[$cookie_name] != "")) {
echo 'yes';
}
else{
echo 'no';
}
phpinfo();
?>
It prints the yes
And the same code when I tried in my main php file than it displays the error and also prints the yes. I didn't know what's wrong with my code.
I have also tried googling but didn't got any luck.
you can make use of output_buffering in php.ini. as headers are already sent above you need to hold output before sending it to client.
I am getting unknown issue that is i am not able to unset my session with the browser.
Here is my code that checks on every request:
if (isset($_SESSION["logid"])) {
$log = TRUE;
$logid = $_SESSION["logid"];
$session_id = $_SESSION["sid"];
} else {
$log = FALSE;
}
if (!isset($_COOKIE["cook"])) {
if ($log) {
unset($_SESSION["logid"]);
unset($_SESSION["sid"]);
$log = false;
}
$expire = time() + 60 * 60 * 24 * 30 * 2;
$data = array(
"ip" => $_SERVER['REMOTE_ADDR'],
"browser" => $_SERVER['HTTP_USER_AGENT'],
"create_time" => $now
);
$result = $db->insert("cookies", $data);
$cookie_id = $db->lastid;
$cookie_id = my_encrypt($cookie_id);
setcookie("cook", $cookie_id, $expire, "/");
} else {
$cookie_id = $_COOKIE["cook"];
}
and code for logging out is here
unset($_SESSION["logid"]);
unset($_SESSION["sid"]);
I don't want to unset/expire cookie named cook but i want to create it if cookie deleted manually or other reason so the code in first block does that.
Not quite sure I understand the issue, but maybe this will help. All browser instances (windows or tabs) share the same cookie jar. While this is rarely a problem in "real life" it plays havoc with developers because you, as a developer, may have many tabs open. If you want to test an application that changes cookies (such as a login or logout) you should close all instances of your browser and open only one instance, then test.
PROBLEM
I've got an admin panel. Currently only Mozilla is able to process log ins. Browsers like Chrome, IE, Opera won't even show any message carried through sessions thus no one is able to log in any browser but Mozilla.
SOME INFORMATION
I'm using PHP 5.3.6 on my server, PHP 5.3.5 on my local
computer.
My code is Object Oriented.
ini_set("session.use_only_cookies", 1); and
ini_set('session.cookie_secure', 1); are used in construction method
of my session class.
This website on SLL
Login process: First I gather all information from form, validate and gather data. After validation if everything is right, I send this data to login method in my session class.
public function login ($user) {
global $siteSettings;
if ($user) {
$this->id = $_SESSION['id'] = $user->id;
$this->username = $_SESSION['username'] = $user->username;
$this->fullName = $_SESSION['fullName'] = $user->fullName;
$this->group_id = $_SESSION['group_id'] = $user->group_id;
$this->groupName = $_SESSION['groupName'] = $user->groupName;
$this->lastLogin = $_SESSION['lastLogin'] = $user->lastLogin;
$this->isAdmin = $_SESSION['isAdmin'] = ($user->admin == 1) ? true : false;
$this->isAgent = $_SESSION['isAgent'] = ($user->agent == 1) ? true : false;
self::$language = $_SESSION['language'] = ($user->language != "" || $user->language != NULL) ? $user->language : self::$language;
if ($user->language != "" || $user->language != NULL) {
$_SESSION['language'] = $user->language;
}else {
if (!defined(DEFAULT_LANGUAGE)) {
$browserLang = "|".$_SERVER["HTTP_ACCEPT_LANGUAGE"];
$browserLang = getStringBetween($browserLang, "|","-", FALSE);
if (!file_exists(LANGUAGES.$browserLang.".php")) $browserLang = FALSE;
}
$_SESSION['language'] = ($browserLang) ? $browserLang : DEFAULT_LANGUAGE;
}
# When 2 Update session_id
$date = new DateTime("now");
$UpdateTime = $siteSettings->session->timeOut * 60;
$date->add(new DateInterval("PT".$UpdateTime."S"));
$_SESSION['SIDUpdateTime'] = $date->format("Y-m-d G:i:s");
# UPDATE LAST LOGIN & ADD SESSION ID
# Clear Fields
members::clearFields();
members::$fields['id'] = $_SESSION['id'];
members::$fields['lastLogin'] = date("Y.m.d G:i:s");
members::$fields['lastLoginIP'] = $_SERVER['REMOTE_ADDR'];
# GET THE SALT
$saltInfo = members::getData("id", "salt", members::$fields['id']);
# SETTING SESSION ID ENCRYPTION
crypt::setKey($saltInfo->salt);
members::$fields['sessionID'] = crypt::encode(session_id());
members::$fields['sessionIP'] = $_SERVER['REMOTE_ADDR'];
members::$fields['sessionAgent'] = $_SERVER['HTTP_USER_AGENT'];
members::save();
$this->loggedIn = true;
var_dump($_SESSION);
}
}
When I dumb the data I can see $_SESSION got some values.
Just to test it, I stopped the script where after var_dump($_SESSION); (added die();) I created test.php file and tried this;
<?php
ob_start();
session_start();
echo '<pre>';
var_dump($_SESSION);
echo '<pre>';
ob_end_flush();
?>
Output is array(0) {}
But when I try exactly the same thing with Mozilla, output of test.php is the way it should be (matching with login method's result in my session class).
I have tried from my local computer and I don't experience the same
problem.
I disabled all java script and jquery codes from the page just to
have no 'maybe' in my mind.
After dumping the data, script is stopped. That's why $_SESSION variable shouldn't change. For some reason when it is on the server only Mozilla is able to show expected result while other browsers shows NULL.
At this point I really don't know what to think of about this problem to try to solve it. All I can think of is, this problem is possibly related to server configuration. But then, PHP is server side programming. PHP shouldn't display different behavior for browsers like Jquery, CSS, HTML...
I'm sorry, I can't provide admin panel link. Considering this is an active admin panel. If necessary I could install it on another domain to let you try but I believe the information I gave above explains everything.
Thank you for your help in advance.
I had a similar problem... just enable the cookies.. so that after login the code to set the sessions will be executed and the sessions will be set. may be the sessions r not able to set...
also check this http://php.net/manual/en/function.session-cache-limiter.php
If something large doesn't work, trim it down, test & debug, and build up from there.
Does this work? (Run it twice).
<?php
session_start();
echo "Session ID: " . session_id() . "<br/>\n";
if (!isset($_SESSION['test']))
{
$_SESSION['test'] = "foobar";
echo "Setting session variable: ";
echo $_SESSION['test'];
}
else
{
echo "Restoring session variable: ";
echo $_SESSION['test'];
}
If this works in all browsers, it's got something to do with your code. An empty session might have something to do with a cookie that can't be written, for example. Also set error reporting to E_ALL | E_STRICT, so you'll see everything that goes wrong.
It turns out Mozilla FireFox is able to process some data but other browsers I tried with are not and therefore they reset the whole session with each page load.
I had no problem with my local computer but on the server I had sessions problem. I don't know why session_set_cookie_params(); and setcookie(); didn't work on the server so I had to code longer version;
private static function sessionLifeTime() {
global $siteSettings;
# HOW LONG WE WANT SESSIONS
$lifeTime = intval($siteSettings->session->timeOut) * 60;
if (isset($_SESSION['id']) && isset($_SESSION['lastActivity']) && (time() - $_SESSION['lastActivity'] > $lifeTime) ) {
// SEND INFORMATION TO USER
self::logout();
}
$_SESSION['lastActivity'] = time();
}
Replacing my method with the code above solved the problem.
Thank you all for your time, concern and interest.
Kind of a weird issue, ok here is my setup...
domain.com calls reads from an Iframe on sub.domain.com
sub.domain.com makes an ajax call to sub.domain.com/call.php
sub.domain.com returns ajax call to domain.com
AKA long-polling
Now, everything works perfectly when there is no session data (I close the browser and restart the page). However, once I reload the page and their is session data, call.php does a start_session() and hangs there.
I have tried almost everything and can't figure this out. I've tried destroying the session, unsetting all the session variables, modifying some ini settings, and nothing has worked.
Here is the code of call.php where the session data is...
session_start();
$sql = ("SELECT userid FROM status WHERE typing = '".mysql_real_escape_string($userid)."'");
$result = mysql_query($sql);
if ($result && mysql_num_rows($result) > 0) {
$row = mysql_fetch_array($result);
$typing_id = $row['userid'];
if (!empty($typing_id)) {
if (isset($_SESSION['typing2'])) {
unset($_SESSION['typing2']);
}
} else {
$typing_id = "-1";
}
} else {
$typing_id = "-1";
if (isset($_SESSION['typing'])) {
unset($_SESSION['typing']);
}
}
if ($_SESSION['typing'] != $typing_id && !isset($_SESSION['typing2']) || $initialize == "1") {
$typing = array('typing_id' => $typing_id);
}
if ($typing_id == "-1") {
$_SESSION['typing2'] = "-1";
} else {
$_SESSION['typing'] = $typing_id;
}
Does anyone have any ideas? I was thinking it might have to do with the domain but I'm not sure.
Thanks!
I actually found out (after hours and hours of debugging and research) that the problem is being caused because the PHP session locks up. Then, when the new page loads, it won't work until the old session times out. A session_write_close() will fix it.
default session storage in php is cookie based. if you are using that you must set domain for your session cookie in php.ini
http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-domain
I am writing a custom session handler and for the life of me I cannot get a cookie to set in it. I'm not outputting anything to the browser before I set the cookie but it still doesn't work. Its killing me.
The cookie will set if I set it in the script I define and call on the session handler with. If necessary I will post code. Any ideas people?
<?php
/* require the needed classes comment out what is not needed */
require_once("classes/sessionmanager.php");
require_once("classes/template.php");
require_once("classes/database.php");
$title=" "; //titlebar of the web browser
$description=" ";
$keywords=" "; //meta keywords
$menutype="default"; //default or customer, customer is elevated
$pagetitle="dflsfsf "; //title of the webpage
$pagebody=" "; //body of the webpage
$template=template::def_instance();
$database=database::def_instance();
$session=sessionmanager::def_instance();
$session->sessions();
session_start();
?>
and this is the one that actually sets the cookie for the session
function write($session_id,$session_data)
{
$session_id = mysql_real_escape_string($session_id);
$session_data = mysql_real_escape_string(serialize($session_data));
$expires = time() + 3600;
$user_ip = $_SERVER['REMOTE_ADDR'];
$bol = FALSE;
$time = time();
$newsession = FALSE;
$auth = FALSE;
$query = "SELECT * FROM 'sessions' WHERE 'expires' > '$time'";
$sessions_result = $this->query($query);
$newsession = $this->newsession_check($session_id,$sessions_result);
while($sessions_array = mysql_fetch_array($sessions_result) AND $auth = FALSE)
{
$session_array = $this->strip($session_array);
$auth = $this->auth_check($session_array,$session_id);
}
/* this is an authentic session. build queries and update it */
if($auth == TRUE AND $newsession == FALSE)
{
$session_data = mysql_real_escape_string($session_data);
$update_query1 = "UPDATE 'sessions' SET 'user_ip' = '$user_ip' WHERE 'session_id' = '$session_id'";
$update_query2 = "UPDATE 'sessions' SET 'data' = '$session_data' WHERE 'session_id = '$session_id'";
$update_query3 = "UPDATE 'sessions' SET 'expires' = '$expires' WHERE 'session_id' = '$session_id'";
$this->query($update_query1);
$this->query($update_query2);
$this->query($update_query3);
$bol = TRUE;
}
elseif($newsession == TRUE)
{
/* this is a new session, build and create it */
$random_number = $this->obtain_random();
$cookieval = hash("sha512",$random_number);
setcookie("rndn",$cookieval,$expires,'/');
$query = "INSERT INTO sessions VALUES('$session_id','0','$user_ip','$random_number','$session_data','$expires')";
$this->query($query);
//echo $cookieval."this is the cookie <<";
$bol = TRUE;
}
return $bol;
}
code updated. still no luck
for some reason if any html is echoed after the session manager is started the cookie is called after the html. this doesnt make any sense to me
The problem is likely in your if/else statements. You are using:
if($auth = TRUE AND $newsession = FALSE)
...
elseif($newsession = TRUE)
The use of a single = means that you are assigning values, not comparing them. You need to use == instead of =.
Change to this:
if($auth == TRUE AND $newsession == FALSE)
...
elseif($newsession == TRUE)
With the code that you have right now, the first if block of your code will run every time, so your setcookie() call is never reached.
setcookie() returns false if php can't add the header. So for debugging try something like
setcookie("rndn",$cookieval) or die('setcookie failed');
You can combine that with a test whether setcookie() is called in the first place
$rc = setcookie("rndn",$cookieval);
/* DEBUG-code don't forget to remove me */
error_log(sprintf("%s %s\n", date('Y-m-d H:i:s setcookie():'), $rc?'success':'failed'));
(or even better use a debugger like xdebug and e.g. netbeans as frontend).
Did you check the response headers in your browser? E.g. via the firebug extension. Perhaps the client receives the cookie header but doesn't accept it.
According to tour code, at least you have to set / directory in the cookie parameters.
But anyway, first of all you have to sniff cookies from the HTTP log. You can use Firebug to watch if server does set any cookie and if browser send any back