PHP: Can't Set Cookie - php

For some reason, I can't seem to set a cookie in one of my PHP files. All of the code works fine, except it refuses to set the cookie. I've placed different versions of cookie setting with different arguments, but it doesn't seem to make a difference. On top of that, I can set a cookie using that same line of code in a separate PHP file in the same directory. I've tried placing setcookie() at different places and I still get the same result. Am I missing something?
<?php
$table_name="lfgs";
$name=$_POST['name'];
$event="[";
$level=$_POST['level'];
$comments=$_POST['comments'];
$hours=$_POST['hours']*60*60;
$minutes=$_POST['minutes']*60;
$time=$hours+$minutes+time();
setcookie("remember", $name, $time, 'www.domain.com', '/');
if(isset($_POST['event'])){
if (is_array($_POST['event'])) {
foreach($_POST['event'] as $value){
$event = $event . "\"" . $value . "\",";
}
} else {
$value = $_POST['event'];
$event = $event . "\"" . $value . "\"]";
}
} else {
$event = "";
}
if($event[strlen($event)-1] == ',') {
$event = substr_replace($event ,"]",-1);
}
$con=mysqli_connect("domain.com","username","password","database");
$req="INSERT INTO $table_name(name, event, level, comments, time) VALUES ('$name', '$event', '$level', '$comments', '$time')";
mysqli_query($con,$req);
mysqli_close($con);
foreach($_COOKIE as $c) {
echo $c . "<br />";
}
?>
Edit: This is ALL the code for the entire file.

According to the php reference, the correct way to use the setcookie function is
bool setcookie ( string $name [, string $value [, int $expire = 0 [, string $path [, string $domain [, bool $secure = false [, bool $httponly = false ]]]]]] )
Didn't you swaped the $path and $domain argument?
Try
setcookie("remember", $name, $time, '/', 'www.domain.com');

try
setcookie("remember", $name, '/', $time);

I dont't understand what you want to do, but it'll not works the way you do.
Always remember: you work with PHP on the server side.
So to set a cookie an then to test if it worked, you need always tow steps (because you are on the server side):
The first step is to set the cookie.
And then during the next request you can check if ur cookie contains in the global $_COOKIE array. if yes then ok, if not then mybe the client/user donsen't allow to set cookies.
If you need to do it in "one step", you should use JavaScript. Something like that:
On submit the form, set the cookie and then propagate the submit action (send the data to the server). JQuery support a good solution to set and read cookies.

Are you sure the php interpreter doesn't send a char before the setcookie() call for some reason? The function send a HTTP header, so it have to appear before any printing on the page.

From my experience, if you have any session active on the page it will not allow you to create PHP cookies. Start a new blank page and test it that way.
You should be able to set a cookie on the new generic page. Then go back to your other page that has a session started on it. Echo the details of that set cookie in the session page and you will get the stored value, no problem.
You can call cookies but you can't seem to create them in an active session page. At least, I can't with my current system settings/config.

Related

Delete a value from cookie with php

I am storing product id-s in a cookie with php. (These are the favorite products on a webshop.)
I added many products as favorit, so my cookie looks like: 12,55,120,43
What i know, that the $_COOKIE[$cookie_name] is not an array. (checked with is_array function)
How can i delete a product id from that cookie? I send the id that i want to delete with ajax to this php file:
if(isset($_POST['id']))
{
$id = intval($_POST['id']);
$cookie_name = "kedvenc_termek";
if(isset($_COOKIE[$cookie_name]))
{
echo $_COOKIE[$cookie_name];
}
}
Unset your cookie:
unset($_COOKIE[$cookie_name]);
Set your cookie null:
setcookie($cookie_name, null, -1, '/');
This should delete or invalidate cookie
// set the expiration date to one hour ago
setcookie($cookie_name, " ", time() - 3600);
?>
If I understand you correct you have a string stored in the cookie like 12,55,120,43 and you want to remove one of them using $_POST['id']?
Since it's a string I believe the best option is preg_replace() this gives you the benefit over str_replace that you can create a pattern to remove.
$id = $_POST['id'];
$cookie_name = "kedvenc_termek";
$_COOKIE[$cookie_name] = preg_replace("/\b(" . preg_quote($id) . ",)\b/", "", $_COOKIE[$cookie_name]);
echo $_COOKIE[$cookie_name];
If you want to store the new string in the cookie then be sure to do that before you echo the value since you can't set a cookie after an output.
Example: https://3v4l.org/RQH4o

PHP delete cookie that starts with wp_postpass_

I need to write some custom code for a Wordpress function, and I need to be able to delete any cookies that start with wp-postpass_. I know this can be done with jQuery but I'm unsure of how to approach it in PHP.
I have tried Googling and searching on here but I haven't been able to find anything that matches what I'm trying to do.
Thank you in advance,
Andy
EDIT:
Sorry, I should have mentioned that Wordpress appends a random string onto the end of wp-postpass_ hence why I need to find any cookies that start with wp-postpass_. Apologies, early morning.
So iterate through all cookies and check if there contain wp_postpass_ and then remove the cookie.
foreach($_COOKIE as $cookieKey => $cookieValue) {
if(strpos($cookieKey,'wp-postpass_') === 0) {
// remove the cookie
setcookie($cookieKey, null, -1);
unset($_COOKIE[$cookieKey]);
}
}
If you have access to the $_COOKIE superglobal just do
$past = time() - 86400;
foreach($_COOKIE as $name => $value) {
if(strpos($name, 'wp-postpass_') === 0) {
setcookie($name, '', $past);
unset($_COOKIE[$name]);
}
}

php cookie not rewrite the new value

Good morning,
I've got such problem. I would like to store in cookies language, which user will choose. The value in local variable is still changed, but value in cookie is always the same. Even if I always delete the cookie and then I create it again the value stored in cookie is wrong and my local is good. Here's my code:
<?php
if (isset($_GET['lng'])) {
$lng = $_GET['lng'];
if (($lng != "en") && ($lng != "de")) {
$lng = "en";
}
} else {
if(!isset($_COOKIE['lang'])) {
$lng = "en";
} else {
$lng = $_COOKIE['lang'];
}
}
if(isset($_COOKIE['lang'])) {
setcookie("lang", $_COOKIE['lang'], time()-10); //here I try to remove cookie and then create another
}
setcookie("lang", $lng, time()+5);
print_r($_COOKIE);
echo $lng;
?>
print_r will allways return me the main language (en), even if in variable $lng there is de. I think, there will be just stupid problem, but I can't fix it. This removing line (which I commented) is there because of problem written on official php site:
Be careful of using the same cookie name in subdirectories. Setting a simple cookie
setcookie("region", $_GET['set_region']);
both in the root / and for instance in this case /admin/ will create 2 cookies with different paths. In reading the cookies back only the first one is read regardless of path.
And I thought I've similar problem. But this didn't fix my problem and even when the cookie after 5 second will expire to cookie is then written again the bad "en" value.
Thank for your answer
Can you try this, it works for me.
I edited the code a bit, sorry for obfuscating it with one line if-statements.
I also set the cookie time to 1 day so it won't disappear when testing the code.
And remember, you have to update the page to read the new cookie, it will be one step behind $lng.
<?php
$allowed = array('en', 'de');
$chosen = $_GET['lng'] ? $_GET['lng'] : ($_COOKIE['lang'] ? $_COOKIE['lang'] : 'en');
$lng = in_array($chosen, $allowed) ? $chosen : 'en';
setcookie("lang", $lng, time()+24*60*60, '/');
var_dump($_COOKIE['lang']);
echo $lng;
?>

Setting cookie using header("Set-cookie") vs setcookie() function

I'm refactoring some code and found something I've never seen. the function is used for user to set cookie when user logs in:
function setUserCookie($name, $value) {
$date = date("D, d M Y H:i:s",strtotime('1 January 2015')) . 'GMT';
header("Set-Cookie: {$name}={$value}; EXPIRES{$date};");
}
now that I've been assigned to refactor code I'm planning to use setcookie function which essentially does same thing according to php.net.
My question is: is there any difference between two and which one should I use?
NOTE: this code was written long time ago so I'm assuming that at that time setcookie didnt exist?
There's no good reason not to use setcookie. The above code doesn't properly encode names and values, so that's at least one major benefit to refactoring.
The difference between the two functions is that header() is the general function for setting HTTP headers while setcookie() is specifically meant to set the Set-Cookie header.
header() therefore takes a string containing the complete header, while setcookie() takes several cookie-specific arguments and then creates the Set-Cookie header from them.
Here's a use case in which you can't use setcookie
you run a website on PHP<7.3
you have to set 'SameSite' cookie attribute
You can achieve that by exploiting a bug in setcookie, but I wouldn't rely on a bug as it gets fixed over time: setcookie('samesite-test', '1', 0, '/; samesite=strict');
Or you can use PHP header function: header("Set-Cookie: samesite-test=1; expires=0; path=/; samesite=Strict");
Note that secure option is required when setting samesite attribute
One big difference is, that setcookie always sets host_only=false and there is nothing you can do about it.
So if you have to set host_only=true for whatever reasons you have to use the header method. As far as I know.
I replicated what I believe to be the exact behavior of setCookie programmatically. Here is my implementation, if it can be useful for anyone else.
function setUserCookie($name, $value, $expires = 0, $path = "", $domain = "", $secure = false, $http_only = false) {
$value = rawurlencode($value);
date_default_timezone_set('UTC');
$date = date("D, d-M-Y H:i:s",$expires) . ' GMT';
$header = "Set-Cookie: {$name}={$value}";
if($expires != 0) {
$header .= "; expires={$date}; Max-Age=".($expires - time());
}
if($path != "") {
$header .= "; path=".$path;
}
if($domain != "") {
$header .= "; domain=".$domain;
}
if($secure) {
$header .= "; secure";
}
if($http_only) {
$header .= "; HttpOnly";
}
header($header, false);
}
The difference with your function are exactly the difference with setCookie (more arguments like custom expires, path, domain, secure and httpOnly). Especially, note the second argument to "header" (false) so that it becomes possible to place multiple cookies with different calls to the function.

Can multiple independent $_SESSIONs be used in a single PHP script?

I want to use two independent $_SESSIONs in a single PHP script.
I have attempted to verify that this is possible using the following code.
error_reporting(-1);
session_name('session_one');
session_start();
$_SESSION = array();
$_SESSION['session_one_var'] = 'test_one';
$output1 =
(
"session_id(): '" . session_id() . "'.<br/>\n" .
"session_name(): '" . session_name() . "'.<br/>\n" .
print_r($_SESSION, true)
);
session_write_close();
$_SESSION = array();
session_name('session_two');
session_start();
$_SESSION['session_two_var'] = 'test_two';
$output2 =
(
"session_id(): '" . session_id() . "'.<br/>\n" .
"session_name(): '" . session_name() . "'.<br/>\n" .
print_r($_SESSION, true)
);
session_write_close();
$_SESSION = array();
echo "$output1<br/>\n<br/>\n$output2";
Output:
session_id(): 'f19aecd8d3ce0c5d444456d2387c6e35'.
session_name(): 'session_one'.
Array ( [session_one_var] => test_one )
session_id(): 'f19aecd8d3ce0c5d444456d2387c6e35'.
session_name(): 'session_two'.
Array ( [session_one_var] => test_one [session_two_var] => test_two )
I expect the output to show that the session named 'session_one' contains array('session_one_var' => 'test_one') and the session named 'session_two' contains array('session_two_var' => 'test_two'). Instead, 'session_two' seems to be the same session as 'session_one'.
If I insert a line 'session_regenerate_id();' after the second 'session_start();' line, a different session id is reported for 'session_two', but the output is otherwise the same. See below.
session_id(): 'f19aecd8d3ce0c5d444456d2387c6e35'.
session_name(): 'session_one'.
Array ( [session_one_var] => test_one )
session_id(): '3bcc74a7bcbac30e680c5b94fadcede1'.
session_name(): 'session_two'.
Array ( [session_one_var] => test_one [session_two_var] => test_two )
What am I doing wrong?
I know similar questions have been asked on this forum before, here and here, but the answers offered so far have failed to enlighten me.
Any help will be much appreciated.
The session ID is read from a cookie when you run the first session_start() and sticks around even if you use session_write_close() (otherwise you wouldn't be able to call session_start() to reopen the same session)
I don't have PHP handy here to test this, but in theory, you can do session_id($_COOKIE['session_two']); before the second session_start() to switch to the correct ID.
I may have the cookie name wrong, though, so you may want to printr($_COOKIE); to see which cookies are set.
Edit: I forgot to mention: The session's cookie name is based on session_name, or at least it is if you only use a single session in a file.
According to the docs,
As of PHP 4.3.3, calling session_start() after the session was previously started will result in an error of level E_NOTICE. Also, the second session start will simply be ignored.
My interpretation is that no, you cannot use session_start() more than once per page, regardless of the name.
The regenerate_id() is changing the ID for the first session, and the second session_start is being ignored. That is why you see the behavior described.
I'd suggest letting us know what you're seeking to accomplish by doing this, and probably someone can recommend another way to do it.
My solution is
ob_start();
$name1 = 'session_1';
session_name($name1);
if(empty($_COOKIE[$name1]))
$sid = md5(microtime(true));
else
$sid = $_COOKIE[$name1];
session_id($sid);
session_start();
$_SESSION['count']++;
print_r($_SESSION);
session_write_close();
$_SESSION = array();
$name2 = 'session_2';
session_name($name2);
if(empty($_COOKIE[$name2]))
$sid2 = md5(microtime(true));
else
$sid2 = $_COOKIE[$name2];
session_id($sid2);
session_start();
$_SESSION['count'] = $_SESSION['count'] + 2;
print_r($_SESSION);
session_write_close();
ob_end_flush();

Categories