Why doesn't cookie work in CodeIgniter?

2019-01-20 01:50发布

问题:

I use this function to add cookie and it adds perfectly as I can see in browser options.

function login($username,$password){

    $cookieUsername = array(
        'name'   => 'user',
        'value'  => md5($username),
        'expire' => time()+1000,
        'path'   => '/',
        'secure' => TRUE
    );

    $cookiePassword = array(
        'name'   => 'pass',
        'value'  => $password,
        'expire' => time()+1000,
        'path'   => '/',
        'secure' => TRUE
    );

    $this->input->set_cookie($cookieUsername);
    $this->input->set_cookie($cookiePassword);

}

I am unable to get back the cookie from this function:

 echo $this->input->cookie('user');

Please help - how can I get cookie back from CodeIgniter?

回答1:

Its problem with CI built in function which writes the cookie. What i changed is now i am setting cookie whith

setcookie($name,$value,$expire,$path); 

function and getting it back through

$this->input->cookie('user',TRUE); 

this is work damn fine!



回答2:

You can not get cookie on the same http request. Once you set a cookie it must be sent to browser by Set-Cookie header. And you can not send header until the http transaction is completed. After that browser will get the cookie and on the next request browser will send it to server by Cookie header.

From PHP.NET

Cookies will not become visible until the next loading of a page that the cookie should be visible for. To test if a cookie was successfully set, check for the cookie on a next loading page before the cookie expires. Expire time is set via the expire parameter.

So the cookie will be available on the next page load.



回答3:

I was having this problem and found that Codeigniter requires an expiry value, NOT just the name and value as stated in the documentation. I.e.

$cookie = array(
'name'  => 'logged',
'value'  => 1,
'expire' => '86500',
);

set_cookie($cookie);


回答4:

Switching to PHP's setcookie() instead of CI's $this->input->set_cookie() didn't work for me; the cookie was still not available until the next request. This makes sense because CI's method in fact generates a setcookie() so they're functionally equivalent. However, I was able to get it working right away by doing the following:

//this is the original code, which is made available next request:
$this->input->set_cookie('foo', 'bar', 86500);
//this is what I added, to make the cookie available immediately:
$_COOKIE['foo'] = 'bar';

Hope that helps someone.



回答5:

Check your config.php cookie settings. If they are set wrong, cookies won't work. The defaults work for me locally using your code

$config['cookie_prefix']    = '';
$config['cookie_domain']    = '';
$config['cookie_path']      = '/';

also, you should encrypt the password if you're going to encrypt anything. And you shouldn't use md5. Use CI's built in encryption ($this->encrypt->encode();) which uses a safer algorithm [don't forget to set your encryption key in config.php].



回答6:

there is a bug in codeigniter: it doesn't use your cookie_prefix when reading the cookie (when writing the cookie, it does) see /system/core/Input.php in function cookie



回答7:

That is caused by an incorrect initialization of function set_cookie() about $expire parameter, setted to empty string by default but it must be setted to 0 by default because it rapresent timestamp. Look at there correction

Line 342 on system/core/Input.php

https://github.com/diegomariani/CodeIgniter/commit/64ac9e711100605f41a3b37bc897a12063fed70b



回答8:

First make sure you are including cookie helper:

$this->load->helper('cookie');

And set cookie like this:

set_cookie($cookie_name, $value, $time);


回答9:

public function cookie()
{
    $this->load->helper('cookie');

    $name   = 'user';
    $value  = 'pradip';
    $expire = time()+1000;
    $path  = '/';
    $secure = TRUE;

    setcookie($name,$value,$expire,$path); 

    $this->load->view('welcome_message');

}

call in view page like echo $this->input->cookie('user');

output = pradip



回答10:

Check your config.php for cookie_secure directive. It must be FALSE for non-https domains.

If domain is not https and cookie_secure is set TRUE in config.php, cookies simply will not be set. Change to FALSE and it will be set in both http and https.



回答11:

Codeigniter, in its code, already adds time() for expiry, so you don't need to add time() in your cookie config.

Change:

 'expire' => time()+1000

To:

'expire' => 1000

Also use the procedural style cookie helper functions such as (set_cookie, get_cookie, delete_cookie..) as they automatically adds the cookie prefix config, while with the OOP ones ($this->input->set_cookie etc.), you will have to manually type in the cookie prefix config as well each time.