English 中文(简体)
How to suppress/remove PHP session cookie
原标题:

I need to suppress an already set session cookie header, but I cannot find any way to do this.

Why?
I need to make an image, sent by a PHP script, cacheable by the end user; this image is used to track if a newsletter has been read by the receiver, so if the image is requested I know the newsletter has been read. I only need to know when the newsletter gets opened for the first time, the subsequent requests can be ignored. The problem is that, even if I properly set the Expire and Cache-Control headers, the image is requested every time the user opens the newsletter--only that image used for the tracking--basically because it s not cached by the user. I used this tool to understand why the URL is not cacheable, and it says because of the cookie sent.

What I want to avoid is the user seeing a delay on the load of the tracking image.

So I have a session_start() in my website init function, that I don t want to remove, because the website is big and complicated, and making some radical change like starting the session only if needed (one of the solutions I envisioned) is not desirable. Calling session_start() sets the Set-Cookie: header with the PHPSESSID cookie, and I need to remove it. Reading from the header() page on php.net I tried setting it with an empty value like this

header( Set-Cookie: );
header( Set-Cookie: , true);
header( Set-Cookie:  );
header( Set-Cookie:  , true);

before and after a call to session_write_close(), but all I obtained is that the user receives a Set-Cookie: header, without any value, exactly as written in the header function argument.

I must say I m still using PHP 5.2, so I cannot use the header_remove() function I see in the manual, and lighttpd 1.4.24.

EDIT: so, it seems the tool I used to check my headers is not that good. I looked at the headers with curl --head and saw the headers below.

HTTP/1.1 200 OK
X-Powered-By: PHP/5.2.9
Set-Cookie: PHPSESSID=qn3ms55nvst2717e7b73qqu445; path=/
Last-Modified: Sun, 29 Mar 2009 21:53:36 GMT
ETag: "cb1dffff8c10db7b0a88794b1453cab8"
Expires: Sun, 20 Dec 2009 23:28:07 GMT
Cache-Control: private, max-age=2592000
Pragma: no-cache
Content-Type: image/png
Content-Length: 1322
Date: Fri, 20 Nov 2009 23:28:07 GMT
Server: lighttpd/1.4.24

As you see it is set a Pragma: no-cache. The tool I used said that the Pragma header is not used, but it was wrong. I tried setting Pragma: cache, and it made the mail client cache the image.

I made another discovery, maybe the impossibility of unsetting the Set-Cookie header is because of lighttpd, since I cannot remove the Pragma header using header( Pragma: ). Looking forward to PHP 5.3. Can someone using Apache confirm that the above header call removes the Pragma header?

Thanks txyoji for the enlightening comment :-)

At this point it seems this question is here only to confirm lighttpd cannot remove headers by setting an header without value.

问题回答

try header_remove( Set-Cookie );

From session_destroy:

In order to kill the session altogether, like to log the user out, the session id must also be unset. If a cookie is used to propagate the session id (default behavior), then the session cookie must be deleted. setcookie() may be used for that.

Does this code work?

setcookie("PHPSESSID",  foo , time()-3600);  /* expired 1 hour ago */

Another solution would be to serve the image through a PHP file, so whenever it gets requested, you can update your database and set a flag to your subscriber table that the newsletter was opened. Much cleaner solution IMHO. You would embed the image with code like this:

<img src="http://www.example.com/tracker.php?idhash=1234234"/>

where idhash could be a combination of subscriber ID plus newsletter ID.

Can you increase the length of the sessions so they don t expire when the user closes thier browser? Set a session variable on the first time the image is loaded by the user. This way it doesn t matter if the image was requested multiple times. You only update the db when the variable isn t set.

Are you sure the image is requested because of the session cookie, and not simply because the E-Mail client for some reason doesn t do any caching?

How about conditionally changing the session cookie name with session_name() depending on the url that s requested?

Try this:

header( Pragma: ,true);

PHP will not send a set cookie header the first time that you start your session.

PHP will set the pragma: nocache header if your session_cache_limiter() is set to private when the session is started. If allowing the cache is all you want, call

session_cache_limiter( public )

before you call session_start(). It must be before session_start(), which means that if your php environment is set to autostart the session, then you have to set session.cache_limiter = public in your php.ini.

If PHP is sending the set cookie header, then one of four things is happening.


1) The session is being started multiple times.


no source - but a one-line PHP program will verify this for you.


session_start();        //  <-- cookie is not sent
session_start();        //  <-- does not count as a second start, nothing happens

session_start();        //  <-- cookie is not sent
session_write_close();  // session_destroy() counts as well
session_start();        //  <-- cookie is sent, since the session has been closed

Check your request and response headers. If the phpsessid value is the same in the response as it is in the request, then this probably is what is happening.


2) The session is being regenerated after it is started


PHP.NET - session_regenerate_id() - Changelog for 4.3.3


session_regenerate_id();

Check your request and response headers. If they are different, then this is probably what is happening.


3) The sessionid is being set prior to the session being started


PHP.NET - session_id - Parameters


session_id( whatever );
session_start();

This one is easy to check for. If you see a call to session_id anywhere in your code, then it s either: before a call to session_start, and is the problem; or it s after a call to session_start, and it does nothing.

4) setcookie( session_name() , ... , ... ) is being called, setting the cookie manually somewhere


No Source


setcookie(session_name(), a session id )
// or setcookie( PHPSESSID ,  a session id )

This one is also easy to check for. Look for any instances of setcookie.

your question isnt really clear, but if you want to remove the PHP session cookie completely (on log-out for example), you can use

  $params = session_get_cookie_params();
  setcookie(session_name(),   , 0, $params[ path ], $params[ domain ], $params[ secure ], isset($params[ httponly ]));  




相关问题
why the session in iis automatically log out?

I used iis6, and when i called a function Directory.delete(), the all the session relate this website will be logged out. and i debugged the website, i found no exception. any one have ideas on this ? ...

Check session from a view in CodeIgniter

What is the best way to check session from a view in CodeIgniter, it shows no way in their user guide, otherwise I will have to make two views on everything, which is kinda weird...still a newbie to ...

Can I get the size of a Session object in bytes in c#?

Is it possible to get the size(in bytes) of a Session object after storing something such as a datatable inside it? I want to get the size of a particular Session object, such as Session["table1"], ...

提供严格分类的出席会议物体

提供严格分类的与会机会的最佳方式是什么? 我正计划转而选择矩阵,这正在促使汇编者抱怨我的幻觉方案拟订方法......

PHP Session is not destroying after user logout

I m trying to create an authentication mechanism for my PHP Application and I m having difficulty destroying the session. I ve tried unsetting the authentication token which was previously set within ...

热门标签