i have this code im trying to do for a type of cache system so it remembers the city the user has selected. if the user has selected a city it stores it in sessions and cookies, and will automatically redirect them to the city page if they've selected it before.
sessions work fine, but it doesn't seem to be setting the cookie to an empty value if the $_GET['city'] variable is empty...
heres my code:
function gen_url ($city)
{
$url = 'http://www.mysite.com';
if (!empty($city)) $url .= "/c-$city";
return $url;
}
function set_cache ($variable, $value)
{
$_SESSION[$variable] = $value;
setcookie($variable, $value, time() + 31536000);
}
$redirect = false;
$redirect_array['city'] = '';
if (!empty($_GET['city']))
{
$sql = mysql_query("select * from `cities` where `slug`='".mysql_real_escape_string($_GET['city'])."'");
if (mysql_num_rows($sql) != 0)
{
while ($row = mysql_fetch_assoc($sql))
{
foreach ($row as $k => $v)
$city[$k] = $v;
}
$redirect_array['city'] = $city['slug'];
}
else
{
$redirect = true;
}
}
if ($redirect)
{
header('Location: '.gen_url($redirect_array['city']);
die();
}
set_cache('city', $redirect_array['city']);
You can't set a cookie with an empty string as it will delete the cookie.
From the docs:
If the value argument is an empty string, or FALSE, and all other
arguments match a previous call to setcookie, then the cookie with the
specified name will be deleted from the remote client.
You can't set a cookie to most falsy values to indicate falseness of a trit cookie. Only '0' will work. Use that.
PHP's setcookie() doesn't allow you to set cookies with empty values. But you can do that with header()
replace:
setcookie($variable, $value, time() + 31536000);
with:
header('set-cookie: '.rawurlencode($variable).'='.rawurlencode($value).'; max-age=31536000', false);
You can set empty value to the cookie by using null pointer as the value
like this:
setrawcookie('testEmptyCookie', "\x00", time() + 3600, '/');
(tried on php 5.6, 7.2)
Make sure to set your cookie with a negative time:
setcookie($variable, '', -1);
Related
I have page with 4 links, when someone clicks on one of the links I want to set a cookie to store the selected link, then when they return to the site, the cookie redirects them to the link they previously selected. Since I only want the 4 links to set a cookie I'm using a query string (?sel=p1) in the link and checking for that to set the cookie.
function set_pref_cookie(){
if (isset($_GET['sel'])) {
$root = $_GET['sel'];
if ($root = 'p1'){
$cookie_var = '/page1/';
} else if ($root = 'p2'){
$cookie_var = '/page2/';
} else if ($root = 'p3'){
$cookie_var = '/page3/';
} else if ($root = 'p4'){
$cookie_var = '/page4/';
}
} else {
$root = '';
}
if ($root !=''){
setcookie('pref_sel',$_COOKIE['sel'] = $cookie_var, time()+60*60*24*5, "/");
}
if (isset($_COOKIE['pref_sel']) && $_COOKIE['pref_sel'] != ''){
header('Location:' . $_COOKIE['pref_sel']);
exit;
}
}
add_action('init','set_pref_cookie');
The issue is, all 4 links set the same value in the cookie /page1/
, and, on return to the site, I'm getting a redirect loop.
I've also tried checking for an empty cookie
if (isset($_COOKIE['pref_sel']) && !empty($_COOKIE['pref_sel']) ){
but same result.
To refer to all the comments in your first ticket, and this one (please don't use 2 questions for the same problem)
=> Redirection with cookie without loop : ok fixed by the correction i gave you and explained to you in the first question.
=> second problem : you're always redirected to page-1.
=> please fix this part of you're code like this :
if ($root == 'p1'){
$cookie_var = '/page1/';
} else if ($root == 'p2'){
$cookie_var = '/page2/';
} else if ($root == 'p3'){
$cookie_var = '/page3/';
} else if ($root == 'p4'){
$cookie_var = '/page4/';
}
You also should add an else case cause your $cookie_var could have sometimes empty value.
=> third, what do you want to achieve with your setcookie with an affectation ?
setcookie('pref_sel',$_COOKIE['sel'] = $cookie_var, time()+60*60*24*5, "/");
you should only do this :
setcookie('pref_sel', $cookie_var, time()+60*60*24*5, "/");
=> to debug, comment you're redirection and replace it by
echo $_COOKIE['pref_sel'];
I am trying to delete a cookie by setting that cookie in past time:
$cookie_name = "user";
$cookie_value = "david";
//subtraction from time causes deletion of cookie
setcookie($cookie_name, $cookie_value, time() - (86400 * 30), "/");
With the below code I try to check whether cookie is enabled or not and it returns if case rather than else part, while I already dell that cookie:
//counting number of cookies
if(count($_COOKIE) > 0) {
echo "<br>Cookies are enabled/exists";
} else {
echo "<br>Cookies are disabled/not exists";
}
But the else part is not working when we delete cookie and I don't know why?
The main problem is you just set user cookie time to past date not all the other cookie in super global $_COOKIE array . Try like this way to set for all $_COOKIE value using foreach() to past date and then check count condition.
<?php
$cookie_name = "user";
$cookie_value = "david";
$past_time = time() - 3600;
//use look set all cookie time to past date.
foreach ( $_COOKIE as $key => $value )
{
setcookie( $key, $value, $past_time, '/' );
}
//counting number of cookies
if(count($_COOKIE) > 0) {
echo "<br>Cookies are enabled/exists";
} else {
echo "<br>Cookies are disabled/not exists";
}
?>
DEMO: https://3v4l.org/jvRXW
I have a custom class I am writing for easier scripting for myself. I generate life spanned sessions and normal sessions (normal life span). So here's my script parts for creating and getting
CREATE
public static function create($session_name,$value="") {
//check if the $_SESSION was started manually without using our functions...
if(!isset($_SESSION)) {
//init this- it creates session_start session_id
self::init(self::$settings["default_name"]);
}
//create array for serialization
$new_session = array();
//if our session is an array means we want this session to have some unique properties compared to others
if( is_array($session_name)) {
//store the session value in the array
$new_session["value"] = $session_name["value"];
//total time is null, this indicates if we want a life expectancy of total 10 hours total or total from current time.
$total = null;
if(isset($session_name["lifeclock"])) { //lifeclock should be a hh:mm:ss format to be exploded
$clock = explode(":",$session_name["lifeclock"]); //we've exploded it now assign it
$hours = $clock[0]; //hours
$minutes = $clock[1]; //minutes
$seconds = $clock[2]; //seconds
$session_add = 0; //variable to be added to total or not technically
if(isset($session_name["concurrent"])) {
$session_add = time(); //if concurrent time is true assign time to the session_add
}
$total = ( $session_add ) + ((int)$hours * 60 * 60) + ((int)$minutes * 60) + (int)$seconds; //broken down math to make all seconds
}
if(!isset($total)) { //this is why total is null
$total = self::$settings["lifetime"]; //if null lifetime we'll use the default lifetime
}
session_set_cookie_params( $total, //assing all data to the session_set_cookie_params
isset($session_name["path"]) ? $session_name["path"] : self::$settings["path"],
isset($session_name["domain"]) ? $session_name["domain"] : self::$settings["domain"],
isset($session_name["secure"]) ? $session_name["secure"] : self::$settings["secure"],
isset($session_name["httponly"]) ? $session_name["httponly"] : self::$settings["httponly"]
);
$new_session["life"] = $total; //we'll also add the time and when it was born
$new_session["born"] = time(); // so the user can use this later in the programming code
$_SESSION[$session_name["name"]] = serialize($new_session); //serialize the array
} elseif(is_string($session_name)) {
$new_session["value"] = $value; //assign value value
$new_session["born"] = time(); //assign born time
$_SESSION[$session_name] = serialize($new_session); //serialize the array
}
session_write_close(); //close the lock
}
GET
public static function get($session_name,$data = false) {
//test if session has been opened via manual or programatically
if(!isset($_SESSION)) {
self::init(self::$settings["default_name"]);
}
//if data argument is true meaning we don't want all the extra information we'll just return value!
if($data === false) {
if(isset($_SESSION[$session_name])) {
$sess = unserialize($_SESSION[$session_name]);
if(isset($sess["value"])){
return $sess["value"];
} else return false;
} else return false;
} elseif($data === true) {
return unserialize($_SESSION[$session_name]);
}
}
Now here is my file for testing this altogether.
<?php
set_include_path(dirname($_SERVER["DOCUMENT_ROOT"]));
require "admininit__autoload.php";
Session::configure(array(
"default_name"=>"boogie",
"lifetime"=> 3600,
));
Session::create( array(
"name"=>"my_session",
"value"=>"boogie all night long",
"lifeclock"=>"00:05:00"
));
$session_value = Session::get("my_session");
var_dump($session_value);
echo "<pre>";
print_r($_SESSION);
echo "</pre>";
?>
So this is what I get in response to the var_dump and print_r
bool(false)
Array
(
)
So this tells me that $session_value is return false from the get function meaning altogether that the darn session is not saving for some strange reason. Here is what I see in google developers resource panel as well
So to me that's telling me a session is being created somewhere. I've also went ahead and checked my /tmp folder and see no file starting with sess_ which is the usual file for sessions. Any hints as to where my issue lies or maybe flat out what the hell is wrong here?
Update
While the creation of the code is uncommented out I get this
array(1) {
["my_session"]=> string(88) "a:3:{s:5:"value";s:21:"boogie all night long";s:4:"life";i:300;s:4:"born";i:1431562088;}"
}
string(21) "boogie all night long"
Array
(
[my_session] => a:3:{s:5:"value";s:21:"boogie all night long";s:4:"life";i:300;s:4:"born";i:1431562088;}
)
But when I comment out the creation part it returns this
bool(false)
Array
(
)
i need help again.
I have to code a function that gets me the cookie. but i only knows part of the cookie name. I got a JavaScript-Function that's working very well:
function readCookie(cookiePart){
var results = document.cookie.match(cookiePart + '(.*)=(.*?)(;|$)');
if(results){
var result = results[0].replace(cookiePart,'');
var cookie= result.split("=");
return(cookie[0])
}else{
return null
}
}
alert(readCookie("cookie_"));
I try to code the same for PHP. But still stuck:
$cookie_name = "cookie_";
if(!isset($_COOKIE["$cookie_name" . "/^*$/"])) {
echo "Cookie named '" . $cookie_name . "' is not set!";
} else {
echo "Cookie '" . $cookie_name . "' is set!<br>";
}
i think i do the regex part wrong. maybe you can help me where to add it? i tried on the varaiablename when define or match, but nothing works.
thx for any hint my friends!
Problem
The thing is, that in JavaScript you used a method .match() for regexp, but you didn't use anything for regexp in PHP.
And you cannot that easily match keys, you can only do this when iterating over entire array.
But you don't have to use regexp to achieve what you need.
Solution
I recommend this:
$set = false;
$cookie_name = 'cookie_';
foreach ($_COOKIE as $name => $value) {
if (stripos($name,$cookie_name) === 0) {
echo "Cookie named '$name' is set with value '$value'!";
$set = true;
}
}
if (!$set) {
echo 'No cookie found :(';
}
Will list all valid cookies (having names beginning with "cookie_"), or display sad message.
And I think that if you can achieve something relatively easy without regex, you should.
If you need to use cookie names afterwards
Use this modified code:
$cookie_name = 'cookie_';
foreach ($_COOKIE as $name => $value) {
if (stripos($name,$cookie_name) === 0) {
$cookies[] = $name;
}
}
And you have now table $cookies that contains names of every valid cookie set. If you need only part that's after _ then use this line instead:
$cookies[] = str_replace('cookie_','',$name);
function keyLike(array $arr, $like)
{
foreach (array_keys($arr) as $k) {
if (preg_match($like, $k)) {
return true;
}
}
return false;
}
...
if (keyLike($_COOKIE, '/^cookie_.+/')) { ...
I want to set a cookie with the country name and city location but I am unable as we had to set cookies before anything. How can I set my variables to its value?
include_once('ip2locationlite.class.php');
$ipLite = new ip2location_lite;
$ipLite->setKey('d930e8b9b1a38e8f647a5f22cce63e18a414e99aaf329a9f38a6caf8f623ec31');
$locations = $ipLite->getCity($_SERVER['REMOTE_ADDR']);
$errors = $ipLite->getError();
$values="";
if (!empty($locations) && is_array($locations)) {
echo $locations['ipAddress'];
echo $locations['countryName'];
echo $locations['regionName'];
echo $locations['cityName'];
$values="ipaddress : ".$locations['ipAddress']."<br>country : ".$locations['countryName']."<br>region : ".$locations['regionName']."<br> city :".$locations['cityName'];
}
if(!isset($_COOKIE['trakcer']))
{
setcookie('trakcer',$values);
}
\you are using wrong way to set cookie, try:
if (!empty($locations) && is_array($locations)) {
$values = serialize($location); //serialize you array
//then set cookie
if(!isset($_COOKIE['trakcer'])) {
setcookie("CookieName", $values, time()+3600); /* expires in 1 hour */
}
}
//and to get it
$array = unserialize($_COOKIE['CookieName']);
You cannot do any echo or print before setcookie. Cookie can be set when no other headers were set/send.
Read documentation for more information php.net/setcookie