PHP setcookie() does not work after unsetting $_COOKIE - php

I've just written very simple wrapper class for Cookies, which goes as follow:
<?php
class Cookie {
// expire time of the cookie 31 days
private static $_expire = '2678400';
public static function set($name = null, $value = null, $expire = null) {
if (!empty($name)) {
$expire = !empty($expire) ? $expire : time() + self::$_expire;
if (setcookie($name, $value, $expire)) {
return true;
}
return false;
}
return false;
}
public static function get($name = null) {
if (!empty($name)) {
return !empty($_COOKIE[$name]) ? $_COOKIE[$name] : false;
}
return false;
}
public static function remove($name = null) {
if (!empty($name)) {
if (!empty($_COOKIE[$name])) {
if (setcookie($name, false, time() - self::$_expire)) {
unset($_COOKIE[$name]);
return true;
}
return false;
}
return true;
}
return false;
}
}
?>
However I have a problem when the cookie was initially set, then I want to change the value by first calling :
Cookie::remove('session_name');
and then
Cookie::set('session_name');
The second one (set) doesn't set the cookie.
Any idea what might be causing it?

I think you misunderstand how cookies work.
The contents of $_COOKIE are set once, when the HTTP request arrives and before your script starts execution.
If you use setcookie to add or modify a cookie, this addition or modification will not be visible until the next HTTP request to your server. This is what you are doing in your Cookie::set method.
If you are "testing" Cookie::set by looking at the contents of $_COOKIE (or by using Cookie::get, which does the same thing) then you will not see the changes to the cookie even though they have been made.
To see what you expect, you should add the value to $_COOKIE inside Cookie::set. However, I would suggest writing your program in a different manner. You are trying to use cookies like normal variables, which they are not.

if you whant to change the value of a cookie , there is no need to first remove it , you can call straight Session::set('session_name'); and the cookie would be overwrited . call Session::remove('session_name'); only when you don't need the cookie anymore.

if I correctly understood you , you need something like that
public static function set($name, $value,$expire)
{
setcookie($name, $value, $expire);
$_COOKIE[$name] = $value;
}

Related

How can I make a page reloading in the middle of the process using PHP?

Here is my code:
public function save_problem(Request $request)
{
$doesnot_turn_on = isset($request->doesnot_turn_on) ? $request->doesnot_turn_on : "";
$res = setcookie('guarantee_ticket', json_encode(["title"=>$request->problem_title, "description"=>$request->problem_description, "turn_on" => $doesnot_turn_on, "unique_product_id" => $request->unique_product_id]), time() + 200000, "/");
if ( Auth::check() ){
return $this->register_guarantee_ticket();
} else {
return \redirect()->route('short_register',["des" => route('register_guarantee_ticket')]);
}
}
public function register_guarantee_ticket()
{
$problem = json_decode($_COOKIE['guarantee_ticket']);
.
.
As you can see, when Auth::check() is true, then register_guarantee_ticket() will be called while still $_COOKIE['guarantee_ticket'] isn't defined and it (cookie) needs a page reloading to be defined.
How can I make that page reloading with PHP?
I know header("Location: ...") will be used for redirecting. But how can I keep the process and do also a redirect?
The problem is why you need reloading the page while the request is processing (that's impossible in HTTP mechanism)
So I have an idea for you to fix this (by passing cookie data to sub-function) :
public function save_problem(Request $request)
{
$doesnot_turn_on = isset($request->doesnot_turn_on) ? $request->doesnot_turn_on : "";
$cookie_data = ["title"=>$request->problem_title, "description"=>$request->problem_description, "turn_on" => $doesnot_turn_on, "unique_product_id" => $request->unique_product_id];
$res = setcookie('guarantee_ticket', json_encode($cookie_data), time() + 200000, "/");
if ( Auth::check() ){
return $this->register_guarantee_ticket();
} else {
return \redirect()->route('short_register',["des" => route('register_guarantee_ticket')]);
}
}
public function register_guarantee_ticket($cookie_data)
{
$problem = $cookie_data; // No need this assign, but I put it here to point out you should pass cookie data directly to sub-function
.
.

Issue with redirect() when using conditional to evaluate multiple form buttons

So I've built a small conditional to evaluate which button is pressed in my form (as there are 2). This works fine and fires off the correct method and writes the appropriate data to the DB, however my redirect is not working. It saves() to the DB and then simply stays on the page designated as the POST route.
I suspect the problem has something to do with my conditional and the use of $this.
Here is my check_submit method:
public function check_submit()
{
if(!is_null(Input::get('add_to_invoice'))){
$this->invoice_add_item();
} elseif(!is_null(Input::get('complete_invoice'))) {
$this->invoice_complete();
}
}
Here is one of the 2 methods which I am currently testing:
public function invoice_add_item()
{
$input = Request::all();
$invoice_items = new Expense;
$invoice_items->item_id = $input['item_id'];
$invoice_items->category_id = $input['category'];
$invoice_items->price = $input['price'];
$invoice_items->store_id = $input['store'];
if(Input::has('business_expense'))
{
$invoice_items->business_expense = 1;
}
else{
$invoice_items->business_expense = 0;
}
$invoice_items->save();
return redirect('/');
}
Perhaps there is a better way of handling this in my routes(web) file, but I'm not sure how to go about this.
You should add the return to the check_submit() method. Something like
public function check_submit()
{
if(!is_null(Input::get('add_to_invoice'))){
return $this->invoice_add_item();
} elseif(!is_null(Input::get('complete_invoice'))) {
return $this->invoice_complete();
}
}
Better yet, you should probably return a boolean on invoice_add_item() and based on that, redirect the user to the correct place (or with some session flash variable with an error message)

Session variable in Kohana 3 keeps being reset after having been deleted

I have a Notices class which is used to provide one-time message notifications. The notifications are stored in a Kohana session (cookie) and my getter looks like this (echos are there for debugging purposes):
private static function _get($key)
{
$session = Session::instance();
$value = $session->get($key);
echo $key . ': ' . $session->get($key) . '<br />';
$session->delete($key);
echo 'deleted ' .$key. ', value now: ' .$session->get($key). '<br /><br />';
return $value;
}
Now, one page I use this class on is the login page. When a user enters incorrect login info it does what I expect it too: displays an error saying "username/password incorrect". This message should then be deleted as I've called the getter and the getter deletes it from the session.
However, this is not the case. The message is shown on the next page too. And if I go to any other page which displays notifications, the error is shown there too, until a different error is displayed (say if I enter information on another form incorrectly).
This is what is displayed from the echo's on the page:
error: Username/password combination is incorrect.
deleted error, value now:
Which suggests that the value is being deleted, but it's still showing the same thing when I refresh the page.
If it helps this is what the process of setting an error message is like, from a controller I call Notices::error('message'); which calls this method:
public static function error($value = NULL)
{
return Notices::_notice('error', $value);
}
which calls:
private static function _notice($key, $value)
{
// If value is not NULL, then store the notice
if ( ! is_null($value))
{
Notices::_set($key, $value);
return TRUE;
}
else
{
// If value is not NULL. retieve key and format HTML
if ( ! is_null($value = Notices::_get($key)))
{
return "$value";
}
// If the key does not exist return empty string
else
{
return '';
}
}
}
and the setter looks like this:
private static function _set($key, $value)
{
Session::instance()->set($key, $value);
return TRUE;
}
If session settings are playing up on you, check two things:
Your browser cache is not so aggressive that it appears to hold on to remnants of elements unless you force flush it.
You're not also setting the session in the same method, thus having it re-fill the variable when you refresh the page or call the method again.
You should also check out the existing get_once method in the Kohana_Session class that destroys the variable after it's done taking it out of the $_SESSION variable:
/**
* Get and delete a variable from the session array.
*
* $bar = $session->get_once('bar');
*
* #param string variable name
* #param mixed default value to return
* #return mixed
*/
public function get_once($key, $default = NULL)
{
$value = $this->get($key, $default);
unset($this->_data[$key]);
return $value;
}

Update Class variable outside PHP Class

I'm gonna make this too complicated, just going to break it down to the main parts.
I have a form that changes the boolean of a variable when the form gets submitted, however it gets called by a function, the function has to change the variable.
class updates
{
var $yesno = false;
function updateBool()
{
$this->yesno = true;
}
}
So when the form gets submitted, it will call $up->updateBool() to change the boolean to true. When I do var_dump($up->yesno), it says false when it should be true. If I do this:
class updates
{
var $yesno = false;
function updateBool()
{
$this->yesno = true;
var_dump($this->yesno); // <-- outputs true
}
}
So how come I cannot get the variable to print out true in a seperate script?
EDIT:
$sql = "SELECT boolean
FROM config
WHERE boolean = 'true'";
$result = mysql_query($sql);
if(mysql_num_rows($result) > 0)
{
$up->updateBool();
}
else
{
header("Location: index.php?d=none");
}
This is part of the code where it gets called. I can confirm there are more than 1 record in the SQL statement.
So when the form gets submitted, it will call $up->updateBool() to change the boolean to true
You seem to be switching to a new page, where $up will be a new object. Objects do not persist across requests. PHP "loses its memory" when you call a new page, and all variables are started from scratch.
To persist values across page requests, you would need to use something like sessions.
class updates
{
public $yesno;
function __construct(){
$this->yesno = false;
}
function updateBool()
{
$this->yesno = true;
}
}

PHP: Cookie problem

Can anyone tell me what is wrong with my code?
<?php
class MyCookie
{
private $expiration = 0;
private $path = "";
private $domain = "";
private $secure = false;
private $httponly = false;
private $names = array();
public function __construct($e, $p = "/temp/", $s = false, $h = false) {
$this->expiration = $e;
$this->path = $p;
$this->domain = '.' . $_SERVER["SERVER_NAME"];
$this->secure = $s;
$this->httponly = $h;
}
public function getDomain() {
return $this->domain;
}
public function write($name, $value) {
return setcookie($name, $value, time() + $this->expiration, $this->path, $this->domain, $this->secure, $this->httponly);
}
public function delete($name) {
return setcookie($name, $value, time() - $this->expiration, $this->path, $this->domain, $this->secure, $this->httponly);
}
public function read($name) {
return $_COOKIE[$name];
}
}
session_start();
$cookie = new MyCookie(3600 * 24 * 30);
$cookie->write('name', 'jun');
echo $cookie->read('name');
?>
Somehow the cookie is not registering or showing up.
Cookie won't show up in $_COOKIE array until you reload the page (cookies are sent with HTTP response)
Two suggestions...
a) Try making the cookie visible to your whole domain, rather than a specified path
b) Get the Web Developer Toolbar for Firefox so you can easily view the current list of Cookies while you browse, which is really useful for de-bugging.
In PHP, the cookie is not actually set until the page reloads. You're creating the cookie then immediately trying to get a value from $_COOKIE, but that value doesn't exist yet in $_COOKIE.
Although it's generally not a good idea to alter values of any of the superglobal arrays, you can do this:
replace:
public function write($name, $value) {
return setcookie($name, $value, time() + $this->expiration, $this->path, $this->domain, $this->secure, $this->httponly);
}
with:
public function write($name, $value) {
$_COOKIE[$name] = $value;
return setcookie($name, $value, time() + $this->expiration, $this->path, $this->domain, $this->secure, $this->httponly);
}
setcookie will not moify the $_COOKIE superglobal.
Is your directory currently '/temp/'? If not, the cookie won't be passed along. Try not giving the new cookie a directory while you're at it, it will auto set to the correct one anyway.
Yup it isn't registering because it needs to reload the page.
It works like this:
_>Http Request
_>Php SetCookie
_>Http Response with cookie header
->New Http Request with cookie
->Php can read cookie now.

Categories