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.
Related
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
.
.
I wrote the following class, Cookie.php
class Cookie extends Config{
//Variables declaration
private $cookieName;
private $cookieValue;
private $cookieExpireTime;
private $cookiePath;
private $cookieDomain;
private $cookieSecureThroughSSL;
private $cookieOnlyThroughHTTP;
//Constructor method, creates a new cookie with the assigned values
function __construct($presetCookieName,
$presetCookieValue,
$presetCookieExpireTime,
$presetCookiePath='/',
$presetCookieDomain = NULL,
$presetCookieSecureThroughSSL = false,
$presetCookieOnlyThroughHTTP = true){
$this->cookieName = $presetCookieName;
$this->cookieValue = $presetCookieValue;
$this->cookieExpireTime = $presetCookieExpireTime;
$this->cookiePath = $presetCookiePath;
$this->cookieDomain = $presetCookieDomain;
$this->cookieSecureThroughSSL = $presetCookieSecureThroughSSL;
$this->cookieOnlyThroughHTTP = $presetCookieOnlyThroughHTTP;
return $this->createCookie();
}
//Clean cookie from possible malicious HTML code, or mistakenly typed spaces
private function cleanCookieValue($value){
return htmlspecialchars(str_replace(' ', '', $value));
}
//Create a new cookie function
public function createCookie(){
return setcookie($this->cleanCookieValue($this->cookieName),
$this->cleanCookieValue($this->cookieValue),
$this->cleanCookieValue($this->cookieExpireTime),
$this->cleanCookieValue($this->cookiePath),
$this->cleanCookieValue($this->cookieDomain),
$this->cleanCookieValue($this->cookieSecureThroughSSL),
$this->cleanCookieValue($this->cookieOnlyThroughHTTP));
}
And the following test file:
$cookie = new Cookie("testCookie", "Value", 3600, "/");
if(isset($_COOKIE['testCookie'])){
echo 'Success';
}
else{
echo 'Failed!';
}
And I keep getting 'Failed' error (After two or more refreshes as well).
Do you guys see the problem here?
By the way, the following simple example works perfectly:
setcookie("token", "value", time()+60*60*24*100, "/");
if(isset($_COOKIE['token'])){
echo 'Token succeeded';
}
else{
echo 'Token failed!';
}
In the class, you had posted 3rd parameter is $presetCookieExpireTime, not "seconds of life". To make it work - do the
$cookie = new Cookie("testCookie", "Value", time() + 3600, "/");
I am trying to save the session in a database instead of files on the server. I have defines the session_set_save_handler() like so
//Set handler to override SESSION
session_set_save_handler( array($this, "open"),
array($this, "close"),
array($this,"read"),
array($this, "write"),
array($this,"destroy"),
array($this, "gc"));
But I keep getting this warning
Undefined variable: this
Then I tried changing it to
session_set_save_handler( "open", "close", "read", "write", "destroy", "gc" );
I don't get the error but I get the following warning
Warning: session_set_save_handler(): Argument 1 is not a valid callback
this is my open() function
static protected function open(){
// If successful return true
if($this->db)
return true;
return false;
}
My question is how can I properly override the function?
this is my entire class
<?php
class SessionManager {
/**
* AOL users may switch IP addresses from one proxy to another.
*
* #link http://webmaster.info.aol.com/proxyinfo.html
* #var array
*/
protected $aolProxies = array('195.93.', '205.188', '198.81.', '207.200', '202.67.', '64.12.9');
private $db;
/**
* This function starts, validates and secures a session.
*
* #param string $name The name of the session.
* #param int $limit Expiration date of the session cookie, 0 for session only
* #param string $path Used to restrict where the browser sends the cookie
* #param string $domain Used to allow subdomains access to the cookie
* #param bool $secure If true the browser only sends the cookie over https
*/
static function sessionStart($dbo, $name, $limit = 0, $path = '/', $domain = null, $secure = null)
{
$this->db = $dbo;
//Set the cookie name
session_name($name); //. '_Session'
//Set SSL level
$https = isset($secure) ? $secure : isset($_SERVER['HTTPS']);
//Set session cookie options
session_set_cookie_params($limit, $path, $domain, $https, true);
//Set handler to override SESSION
session_set_save_handler( "open", "close", "read", "write", "destroy", "gc" );
session_start();
// Make sure the session hasn't expired, and destroy it if it has
if(self::validateSession()){
// Check to see if the session is new or a hijacking attempt
if(!self::preventHijacking()){
// Reset session data and regenerate id
$_SESSION = array();
$_SESSION['IPaddress'] = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
$_SESSION['userAgent'] = $_SERVER['HTTP_USER_AGENT'];
self::regenerateSession();
// Give a 5% chance of the session id changing on any request
} elseif(rand(1, 100) <= 5)
self::regenerateSession();
} else {
$_SESSION = array();
session_destroy();
session_start();
}
}
/*
* This function regenerates a new ID and invalidates the old session. This should be called whenever permission
* levels for a user change.
*/
static function regenerateSession(){
// If this session is obsolete it means there already is a new id
if(isset($_SESSION['OBSOLETE']) || $_SESSION['OBSOLETE'] == true)
return;
// Set current session to expire in 10 seconds
$_SESSION['OBSOLETE'] = true;
$_SESSION['EXPIRES'] = time() + 10;
// Create new session without destroying the old one
session_regenerate_id(false);
// Grab current session ID and close both sessions to allow other scripts to use them
$newSession = session_id();
session_write_close();
// Set session ID to the new one, and start it back up again
session_id($newSession);
session_start();
// Now we unset the obsolete and expiration values for the session we want to keep
unset($_SESSION['OBSOLETE']);
unset($_SESSION['EXPIRES']);
}
/*
* This function is used to see if a session has expired or not.
* #return bool
*/
static protected function validateSession(){
if( isset($_SESSION['OBSOLETE']) && !isset($_SESSION['EXPIRES']) )
return false;
if(isset($_SESSION['EXPIRES']) && $_SESSION['EXPIRES'] < time())
return false;
return true;
}
/*
* This function checks to make sure a session exists and is coming from the proper host. On new visits and hacking
* attempts this function will return false.
*
* #return bool
*/
static protected function preventHijacking(){
if(!isset($_SESSION['IPaddress']) || !isset($_SESSION['userAgent']))
return false;
if( $_SESSION['userAgent'] != $_SERVER['HTTP_USER_AGENT']
&& !( strpos($_SESSION['userAgent'], 'Trident') !== false
&& strpos($_SERVER['HTTP_USER_AGENT'], 'Trident') !== false))
return false;
$sessionIpSegment = substr($_SESSION['IPaddress'], 0, 7);
$remoteIpHeader = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
$remoteIpSegment = substr($remoteIpHeader, 0, 7);
if($_SESSION['IPaddress'] != $remoteIpHeader
&& !(in_array($sessionIpSegment, $this->aolProxies) && in_array($remoteIpSegment, $this->aolProxies)))
return false;
if( $_SESSION['userAgent'] != $_SERVER['HTTP_USER_AGENT'])
return false;
return true;
}
//Open the database connection
private function open(){
// If successful return true
if($this->db)
return true;
return false;
}
//Close the database connection
static protected function close(){
// If successful return true
if($this->db->endConnection())
return true;
return false;
}
//Read the session information
private function read($id){
//Select session data
$info = $this->db->getOneResult('SELECT data FROM sessions WHERE id = ?', array($id) );
//if data found return it
if($info)
return $info['data'];
// Return an empty string
return '';
}
//Write the session information
private function write($id, $data){
// Create time stamp
$access = time();
// Set query
$write = $this->db->processQuery('REPLACE INTO sessions VALUES (?, ?, ?)', array($id, $access, $data));
// If successful return true
if($write)
return true;
// Return False
return false;
}
//Destroy
private destroy($id){
//Delete record
$delete = $this->db->processQuery('DELETE FROM sessions WHERE id = ?',array($id) );
// Attempt execution
// If destroyed return true
if( $delete )
return true;
// Return False
return false;
}
//Garbage Collection
private function gc($max){
// Calculate what is to be deemed old
$old = time() - $max;
//Delete old sessions
$delete = $this->db->processQuery('DELETE FROM sessions WHERE access < ?', array($old));
//if Garbage has been removed return true
if($delete)
return true;
// Return False
return false;
}
}
?>
You are defining it in a static method. $this does not exist in static methods.
You can use the classname itself. So you would do something like:
//Set handler to override SESSION
session_set_save_handler( array("SessionManager", "open"),
array("SessionManager", "close"),
....);
first
//Destroy
private destroy($id){
change
//Destroy
public function destroy($id){
I've set a few cookies in a Controller action and then in another action I want to read the cookie set and do something with the value. However, when trying to read the cookies, all i see is an empty array, my code is as follows:
public function testSetCookieAction()
{
$value = 'ABCDEFGHI'
$cookie = new Cookie('SYMFONY2_TEST', $value, (time() + 3600 * 24 * 7), '/');
$response = new Response();
$response->headers->setCookie($cookie);
$response->send();
.
.
.
}
public function testReadCookieAction()
{
$response = new Response();
$cookies = $response->headers->getCookies();
// $cookies = array(0) { }
}
When i var_dump($_COOKIE);, I see array(1) { ["SYMFONY2_TEST"]=> string(9) "ABCDEFGHI" } Does anybody know what I am doing wrong?
Thanks in advance
You must read cookies on the Request object, not on the void Response object you just created ;)
public function testReadCookieAction(Request $request)
{
$cookies = $request->cookies;
if ($cookies->has('SYMFONY2_TEST'))
{
var_dump($cookies->get('SYMFONY2_TEST'));
}
}
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;
}