Set cookie after output without ob_start - php

I'm guessing not, but is there a way to set a cookie in PHP without having to put ob_start() at the start of the output?
My problem is, that I am developing a class, which among others, needs to set a cookie. Now I can't tell the person who uses it "you have to make a new instance of the class before you make any output", cause that would be lame. So can I somehow pull it off?

See Headers already sent by PHP
The unprofessional workarounds listed there apply. Specifically:
<META HTTP-EQUIV="Set-Cookie"
CONTENT="cookievalue=xy;expires=Friday, 14-Dec-12 12:12:12 GMT; path=/">
Or use javascript and set document.cookie.

You cannot. Cookies are sent as part of the header, so if you've already sent the body, it's too late. Output buffering is the solution.
Perhaps you could use session variables instead.

This is my workround and is working fine for me.
// Force set cookie now
$_COOKIE['ref_url'] = $_SERVER['HTTP_REFERER'];
// Set cookie after refresh site
setcookie('ref_url', $_SERVER['HTTP_REFERER'], Affiliate::$cookieTime);
// Diplay $_COOKIE
var_dump($_COOKIE['ref_url']);

Related

Set cookie in PHP from a getJSON call on two different servers

I have two servers, 'www.domain.local' and 'api.domain.local'. I want to set a cookie in a script on the api server that is called from the www. Chrome does not let me do that (didn't try other browsers yet)
my PHP code:
header("Access-Control-Allow-Origin:*");
echo json_encode(array("cookie"=>print_r($_COOKIE,true)));
setcookie("test","ok",time()+24000*3600,"/",".domain.local");
in my jQuery:
$.getJSON("http://api.domain.local/test.php",{
command:"setcookie"
},function(fb){
alert(fb.cookie);
});
The PHP is first returning the cookies it has, the first run this should be zero, and it is. In the header of the PHP script I see the following:
Set-Cookie:test=ok; expires=Tue, 27-Oct-2015 22:52:52 GMT; path=/; domain=.domain.local X-Powered-By:PHP/5.3.14
Which is what I expect. But the cookie isn't set. When I run the jQuery again I am expecting the cookie to be set (get an alert with the print_r of $_COOKIE), but I get nothing. One thing I noticed in the 'cookies' tab of the network resources in the debug part of Chrome is that the expiry was set as "Invalid Date". If I run the PHP script directly I don't have this problem though.
Is it possible to set a cookie in a PHP script called from jQuery and if so, how?
Let's see, set a cookie on a different domain to the one that the page is loading on and in PHP from jQuery
Someone might post how you're supposed to do it.
I might just cheat.
www.domain.local/test.html includes
$.getScript("http://api.domain.local/test.php?dowhat=setcookie");
api.domain.local/test.php is
<?php
switch ($_GET['dowhat']){
case 'showcookie':
print_r($_COOKIE);
break;
case 'setcookie':
setcookie("test",date('Y m D H:i:s'),time()+24000*3600,"/");
break;
}
header("Content-type: application/javascript"); // may as well, it expects this
die;
Now go to http://api.domain.local/test.php?dowhat=showcookie
Array ([test] => 2013 01 Thu 00:20:52 )
Ta-da!
P.S. I wouldn't advise doing it this simply if you need it to be set without someone naughty being able to cheat too.
There seems to be a problem with your code. On the first line you forgot to close your string with ".

Setcookie does not set a cookie

Hi guys im trying to set a cookie using
setcookie("ms_il_cart_save_for_3", "cName", time()+3600);
header("Location: store-cart3.php");
exit;
when i am move to store-cart3.php the cookie was not set var dump on cookie shows NULL, this has work for me for a year by now. today i have updated changes no related to this piece of code, i know for a fact this worked so far, nothing is outputed with HTML before this code and i dont think i changed the files encoding, maybe my web server blocks creating cookie because of security mesures? (i have run this code today about 100 times)
this is pritty annoying any ideas?
Cookie setting will only work if headers haven't been sent yet. If you've already sent headers or content to the client then setcookie won't work. Setting cookies also requires the client to accept the cookie, if it doesn't then there's nothing you can do about that other than inform them that they need to accept cookies for your system to work.
EDIT: You said in your post that you made changes to unrelated code and now your setcookie doesn't work any more. It is possible that your unrelated code has an error in it that's causing PHP to echo an error message to the browser. This will cause all headers to be sent and any setcookie calls made after this point won't work.
When you're setting a cookie on a page that redirects in this manner, you have to set the cookie after the call to header().
So your example needs to be:
header("Location: store-cart3.php");
setcookie("ms_il_cart_save_for_3", "cName", time()+3600);
exit;
Propably you have outpuded some content before calling that functions and headers were already sent.
Try to start output buffering at start of your script by ob_start()
Also check your files for warnings/notices and BOM utf-8 bytes at begining of text file, wich ones aren't seen in text editor.
Is it browser specific? I've noticed that Blackberry browsers don't process cookies returned in a redirect response - but MSIE and Firefox are happy to.
Since the redirect is after the setcookie, I presume it would be fairly obvious if the headers had already been sent. But have you checked that the cookie is still in the response headers? (ieHTTPHeaders, firebug, tamperdata, fiddler, wireshark)
If not, try switching around the order of the setcookie() and header() calls.

PHP session_write_close() keeps sending a set-cookie header

In my framework, I make a number of calls to session_write_close().
Let's assume that a session has been initiated with a user agent. The following code...
foreach($i = 0; $i < 3; $i++) {
session_start();
session_write_close();
}
...will send the following request header to the browser:
Set-Cookie PHPSESSID=bv4d0n31vj2otb8mjtr59ln322; path=/
PHPSESSID=bv4d0n31vj2otb8mjtr59ln322; path=/
There should be no Set-Cookie header because, as I stipulated, the session cookie has already been created on the user's end. But every call to session_write_close() after the first one in the script above will result in PHP instructing the browser to set the current session again.
This is not breaking my app or anything, but it is annoying. Does anyone have any insight into preventing PHP from re-setting the cookie with each subsequent call to session_write_close?
EDIT
The problem seems to be that with every subsequent call to session_start(), PHP re-sets the session cookie to its own SID and sends a Set-Cookie response header. But why??
PHP does not recommend doing so, and there were bunch of bugs submitted for this. Since they think it's not a good practice - this is the bug that is not going to be fixed.
Almost every answer I found on SO says to just do a session_write_close() and session_start() over and over again...some even disable cookies with ini_set temporarily...this seems to be a very bad approach. The PHP authors provided a very clear, best-practice, path to injecting your own way of handling the sessions using session_set_save_handler.
I have created an example on another post that shows how you can replace your session_start() with Session::start() and replace session_write_close() with Session::save(). The class is a non-blocking (a user can have concurrent requests) class implemented for PHP 5.4+. In fact, it's just a tweaked version of PHP's example class.
While my example is PHP 5.4+, the same method works in older versions of PHP with callback methods instead of an interface implementation.
https://stackoverflow.com/a/27993746/482256
session_write_close just close session and write data
while session_start send cookies
if your don`t want send session cookie your mustn't call session_start

How to set cookies via PHP in the middle of a document?

how can I set cookies in the middle of a document, without incurring a 'headers already sent' error? What I'm trying to do is make a log out script (the log in cookie setting works...so odd. Is it because it's enclosed in an if statement?) however I've already echoed the page title and some other stuff at the top of the page, before I've made this logout happen.
Thanks!
The easiest way is to use output buffering to stop PHP from sending data to the client until you're ready
<?php
ob_start();
// your code
ob_end_flush();
?>
Output buffering stores all outputted data until the buffer is flushed, and then sends it all at once, so any echos after the start will remain buffered until the end_flush and then sent
Try to decompose your application in two parts :
First, you unset the cookie, then you redirect user on the result page. It's a common way to work.
Also try to use a framework in your development, it will improve your skills and the maintenability of your code.
Cookies are sent in the headers, which are sent before anything else is sent. Therefore, if you have actually 'echoed' something to the client (browser), your headers have also been sent.
That said, you can buffer your output and send it all once all the code has been run (ob_start() and ob_end_flush())

Semantics of setting cookies and redirecting without getting header error

I would like to do the following in php :
setcookie('name', $value, $Cookie_Expiration,'/');
then some action
header("location:http://www.example.com")
the problem is that I get :
warning: Cannot modify header information - headers already sent by (...etc )
could you please let me know what i am doing wrong and if there is a way to do this?
by the way , this code is before any output is made ...the cookie setting part works fine on its own and so does the redirection code....the combination fails
thank you
Cookies are sent in the header, and you can't set headers if any output is already sent to the browser (which is is when you set the cookie).
The easiest solution, mind you it is a bit sloppy is to use ob_start() and ob_clean(), for example:
ob_start();
setcookie('name', $value, time()+3600);
ob_clean();
header("Location:http://www.example.com");
Please note the upper case L in the Location header, it is very important.
A better solution might be to set the cookie on the page you are redirecting to, and pass the information to set that header through a session.
From the php manual:
setcookie() defines a cookie to be sent along with the rest of the HTTP headers. Like other headers, cookies must be sent before any output from your script (this is a protocol restriction). This
requires that you place calls to this function prior to any output, including and tags as well as any whitespace.
basically saying what you already know from your warning; that the setcookie is itself sending a header. I'd probably wonder why you want to set a cookie on a page then redirect, why not just redirect and include the data in the URL then pick it up on the target page and use the data there and/or store it in a cookie then, or store in session data if you have a session set already.

Categories