6

I'm using the latest version of Laravel 4 and I can't set cookies:

Route::get('cookietest', function()
{
    Cookie::forever('forever', 'Success');
    $forever = Cookie::get('forever');
    Cookie::make('temporary', 'Victory', 5);
    $temporary = Cookie::get('temporary');
    return View::make('cookietest', array('forever' => $forever, 'temporary' => $temporary, 'variableTest' => 'works'));
});

View script:

@extends('layouts.master')

@section('content')
    Forever cookie: {{ $forever }} <br />
    Temporary cookie: {{ $temporary }} <br />
    Variable test: {{ $variableTest }}
@stop

Yields:

Forever cookie: 
Temporary cookie: 
Variable test: works

It doesn't matter if I refresh the page or create the cookies in one route and try to access them in another. I can confirm that no cookies are being set with the above operation. The cookies 'laravel_payload' and 'laravel_session' as well as 'remember_[HASH]' do exist and I can set cookies with regular PHP using setcookie.

No errors are thrown or logged anywhere that I can find. I'm running Linux Mint locally and Debian on my server, both with nginx and I have the same problem in both places.

Phill Sparks
  • 20,000
  • 3
  • 33
  • 46
Beau
  • 1,771
  • 1
  • 15
  • 20

3 Answers3

17

Cookies are not meant to be used like this, they are set for the next-request, not for the current request. And you have to manually attach them to your Response, as stated in the documentation.

So this code

Cookie::forever('cookie', 'value');
$cookie = Cookie::get('cookie');

will get no result because the cookie is not attached at the end of the request.

You can try it by splitting it in two routes like

Route::get('cookieset', function()
{
    $foreverCookie = Cookie::forever('forever', 'Success');
    $tempCookie = Cookie::make('temporary', 'Victory', 5);
    return Response::make()->withCookie($foreverCookie)->withCookie($tempCookie);
});


Route::get('cookietest', function()
{
     $forever = Cookie::get('forever');
     $temporary = Cookie::get('temporary');
     return View::make('cookietest', array('forever' => $forever, 'temporary' => $temporary, 'variableTest' => 'works'));
});

then first access yoursite.local/cookieset and then yoursite.local/cookietestto see that it works this way and the cookie will be set.

Antonio Frignani
  • 961
  • 1
  • 11
  • 23
15

In Laravel 4 we get the expected cookie behavior with queue.

// Set a cookie before a response has been created
Cookie::queue('key', 'value', 'minutes');

Example:

Cookie::queue('username', 'mojoman', 60 * 24 * 30); // 30 days

Warning: In Laravel 3 use put (http://v3.golaravel.com/api/class-Laravel.Cookie.html#_put).

Example:

Cookie::put('username', 'mojoman', 60 * 24 * 30); // 30 days
Igor Parra
  • 10,214
  • 10
  • 69
  • 101
  • +1 for queued. An important note with the queue method in L4: There are two methods `queued` and `queue`. The former is a getter and returns an already queued cookie, the latter queues a cookie. If you accidentally call `queued('name', 'value')` it will fail silently because it can accept 2 params: a key and an optional default. – Bailey Parker Jan 04 '14 at 02:21
0

The afterFilter can be used to set Cookie in the controller. Assuming the cookie is stored in a controller's class variable $cookie. In the controller's constructor, the following code will automatically insert the cookie into whatever view returned to client:

public function __construct () {
    $cookie = &$this->cookie;
    $this->afterFilter(function ($route, $request, $response) use(&$cookie)  {
            if ($cookie) {
                $response->withCookie( $cookie );
            }
    });
}
Bat Fung
  • 61
  • 1
  • 2