15

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>
user2999920
  • 275
  • 1
  • 2
  • 11
  • 3
    just saying here, but YOU SHOULD sanitize your data, because the code you put there is terribly vulnerable to an SQLI attack – Youness Mar 28 '19 at 16:59
  • 1
    No, serialising data isn't a *great* option. Consider prepared statements or PDO. – undefined Apr 02 '21 at 06:43

7 Answers7

45

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>
John Conde
  • 217,595
  • 99
  • 455
  • 496
  • Click on the output buffering link I gave you. There is an example that actually uses setcookie(). – John Conde Dec 01 '13 at 20:32
  • Would it work if I put ob_start(); at the top of the global file? – user2999920 Dec 01 '13 at 20:53
  • Yes. Just make sure to call ob_end_flush() at the end of each file, too. – John Conde Dec 01 '13 at 20:55
  • 1
    define a custom function like function cookie_set() in global core functions file which contains the setcookie() and use that function at the top of the html code.if you want to delete the cookie, just use this same method with unset($_COOKIE['cookiename']) and setcookie('cookiename',NULL,time()-3600, '/') – Karthikeyan Ganesan Oct 21 '15 at 05:36
9

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.

Robert
  • 2,441
  • 21
  • 12
  • That's what you get for using Notepad++! :) – Christian Sep 25 '15 at 13:06
  • Thanks Robert! But Notepad++ defaults to UTF-8 without BOM... What are you getting at, Christian? I think it was Visual Studio Express that added the BOM in my case. – Nicolas Mar 15 '16 at 18:55
  • Yes, Notepad++ typically defaults to UTF-8 without BOM. However if you, or someone you work with, used some other tool, it is easy to have a file which looks fine, but PHP will send the BOM and break the cookie. For example, I work in a heterogeneous environment and some IDEs default to UTF-8 with BOM. – Robert Mar 17 '16 at 13:50
3

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).

Vahid Amiri
  • 10,769
  • 13
  • 68
  • 113
1

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 :-)

ArturOlszak
  • 2,653
  • 2
  • 21
  • 20
1

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.

mojuba
  • 11,842
  • 9
  • 51
  • 72
0

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...

E.Bradford
  • 783
  • 7
  • 21
0

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.

Amarok24
  • 94
  • 1
  • 9