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'));
}
}
Related
I am new to Laravel (version 8) and i am trying to figure out why my cookie is returning a null. I am setting up the cookie like this'
public function setCookies($value){
$minutes = 60;
$response = new Response('Hello World');
$response->withCookie(cookie('name', $value, $minutes));
return $response;
}
where $value is the string value of the cookie
and i am trying to get the cookie with this method
public function getCookies(Request $request) {
$value = $request->cookie('name');
return $value;
}
but the return value is always null. please let me know where i am going wrong
here are my routes
Route::get('/cookie/set','App\Http\Controllers\Cont#setCookies');
Route::get('/cookie/get','App\Http\Controllers\cont#getCookies');
you have to change code to this :
public function setCookie(Request $request){
$minutes = 60;
$response = new Response('Set Cookie');
$response->withCookie(cookie('name', 'MyValue', $minutes));
return $response;
}
You need to change the route to accept dynamic value.
If you're sending values from url, then set the route to
Route::get('/cookie/set/{value}','App\Http\Controllers\Cont#setCookies');
i am creating a website which needs to store user info and save to cookie.
here is my get cookie controller
public function index($id, Request $request)
{
$petitions = Petitions::where('id',$id)->first();
$sign->name = $request->cookie('name');
$sign->email = $request->cookie('email');
return view('petitions.index', compact('petitions'))->with(['name'=>$sign->name,'email'=>$sign->email]);
}
and here is set cookie controller
public function store(Request $request)
{
$sign = new ActionUsers();
$sign->name = $request->get('name');
$sign->email = $request->get('email');
$sign->job = $request->get('job');
$sign->reason = $request->get('reason');
$sign->ip_address = $request->get('ip_address');
$sign->petition_id = $request->get('petition_id');
$sign->is_anonymous = $request->get('is_anonymous');
$sign->save();
$name_cookie = cookie('name', $sign->name, 30);
$email_cookie = cookie('email', $sign->email, 30);
return back()->withCookie($name_cookie,$email_cookie);
}
my view to check cookie existed
#if( isset($sign->name) && isset($sign->email) )
done!
#else Oops! Error
and return error Creating default object from empty value in $sign->name = $request->cookie('name');
$sign->email = $request->cookie('email');
anyone help me solve that! thank you
Try return in store function as :
return back()->withCookie($name_cookie)->withCookie($email_cookie);
There are several ways to do this:
$response = new \Illuminate\Http\Response(view('your_view'));
$response->withCookie(cookie('cookieName' , 'cookieValue' , expires_in_minutes));
return $response;
or
\Cookie::queue('cookieName', 'cookieValue', expires_in_minutes);
return view('your_view');
you can also use this code to get cookies :
$request->cookie('coockieName');
Not sure what is the correct way to display in a php page a Psr7 Guzzle Response.
Right now, I am doing:
use GuzzleHttp\Psr7\BufferStream;
use GuzzleHttp\Psr7\Response;
class Main extends \pla\igg\Main
{
function __construct()
{
$stream = new BufferStream();
$stream->write("Hello I am a buffer");
$response = new Response();
$response = $response->withBody($stream);
$response = $response->withStatus('201');
$response = $response->withHeader("Content-type", "text/plain");
$response = $response->withAddedHeader("IGG", "0.4.0");
//Outputing the response
http_response_code($response->getStatusCode());
foreach ($response->getHeaders() as $strName => $arrValue)
{
foreach ($arrValue as $strValue)
{
header("{$strName}:{$strValue}");
}
}
echo $response->getBody()->getContents();
}
}
Is there a more OOP way to display the response?
A more OOP way of doing the same thing is to create a Sender object that requires a ResponseInterface in its constructor. This class would be responsible for setting headers, clearing buffers and render the response:
use Psr\Http\Message\ResponseInterface;
class Sender
{
protected $response;
public function __construct(ResponseInterface $response)
{
$this->response = $response;
}
public function send(): void
{
$this->sendHeaders();
$this->sendContent();
$this->clearBuffers();
}
protected function sendHeaders(): void
{
$response = $this->response;
$headers = $response->getHeaders();
$version = $response->getProtocolVersion();
$status = $response->getStatusCode();
$reason = $response->getReasonPhrase();
$httpString = sprintf('HTTP/%s %s %s', $version, $status, $reason);
// custom headers
foreach ($headers as $key => $values) {
foreach ($values as $value) {
header($key.': '.$value, false);
}
}
// status
header($httpString, true, $status);
}
protected function sendContent()
{
echo (string) $this->response->getBody();
}
protected function clearBuffers()
{
if (function_exists('fastcgi_finish_request')) {
fastcgi_finish_request();
} elseif (PHP_SAPI !== 'cli') {
$this->closeOutputBuffers();
}
}
private function closeOutputBuffers()
{
if (ob_get_level()) {
ob_end_flush();
}
}
}
Use it like this:
$sender = new Sender($response);
$sender->send();
Better yet, you could inject the Sender into your app object and transform it in a class variable, so you'd call it like this:
function renderAllMyCoolStuff()
{
$this->sender->send();
}
I'll leave it as a reader's exercise to implement getters and setters for the Response object, plus a method to receive some content string and transform it into a Response object internally.
Guzzle is a library for doing HTTP calls inside your app, it has nothing to do with the end user communication.
If you need to send specific headers to your end user, just use http_response_code() (that you are already using), header() and echo. Or see the docs for your framework, if you use one (Symfony, Slim, whatever).
I am trying to convert a slim 2 project to slim 3.
I am stucking with a problem.
When I call my method:
http://localhost:8000/task_manager/v1/tasks
I get the next error:
Catchable fatal error: Argument 1 passed to authenticate() must
be an instance of Slim\Route, instance of
Slim\Http\Request given in
C:\wamp64\www\task_manager\v1\index.php on line 42.
How could I fix it? Some help will be appreciated.
Here is my php code:
$app = new \Slim\App();
...
...
function authenticate(\Slim\Route $route) {
// Getting request headers
$headers = apache_request_headers();
$data = array();
$app = AppContainer::getInstance();
// Verifying Authorization Header
if (isset($headers['Authorization'])) {
$db = new DbHandler();
// get the api key
$api_key = $headers['Authorization'];
// validating api key
if (!$db->isValidApiKey($api_key)) {
// api key is not present in users table
$data["error"] = true;
$data["message"] = "Access Denied. Invalid Api key";
return echoRespnse(401, $data, $response);
//$app->stop();
return $response->withStatus(401)->withBody("Bad Request");
} else {
global $user_id;
// get user primary key id
$user_id = $db->getUserId($api_key);
}
} else {
// api key is missing in header
$data["error"] = true;
$data["message"] = "Api key is misssing";
return echoRespnse(400, $data, $response);
}
}
$app->get('/tasks', function (Request $request, Response $response) {
global $user_id;
$data = array();
$db = new DbHandler();
// fetching all user tasks
$result = $db->getAllUserTasks($user_id);
$data["error"] = false;
$data["tasks"] = array();
// looping through result and preparing tasks array
while ($task = $result->fetch_assoc()) {
$tmp = array();
$tmp["id"] = $task["id"];
$tmp["task"] = $task["task"];
$tmp["status"] = $task["status"];
$tmp["createdAt"] = $task["created_at"];
array_push($data["tasks"], $tmp);
}
return echoRespnse(200, $data, $response);
})->add('authenticate');
In Slim2 you could add middleware like this:
<?php
$aBitOfInfo = function (\Slim\Route $route) {
echo "Current route is " . $route->getName();
};
$app->get('/foo', $aBitOfInfo, function () {
echo "foo";
});
This is not possible in slim3: first the middleware must be added with the add method like this:
$app->get('/foo', function () {
echo "foo";
})->add($aBitOfInfo);
Secondly middleware doesn't have the \Slim\Route-Object as first parameter.
These are not the Request, Response and the callable of the next middleware. So this should be like this:
/**
* Example middleware closure
*
* #param \Psr\Http\Message\ServerRequestInterface $request PSR7 request
* #param \Psr\Http\Message\ResponseInterface $response PSR7 response
* #param callable $next Next middleware
*
* #return \Psr\Http\Message\ResponseInterface
*/
$aBitOfInfo = function ($request, $response, $next) {
$response->getBody()->write('BEFORE');
$response = $next($request, $response);
$response->getBody()->write('AFTER');
return $response;
};
(Source https://www.slimframework.com/docs/concepts/middleware.html)
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.