When a header has been set using header('Foo: bar') it can be replaced with
other headers, but it cannot be removed.
For instance, one could imagine that the auto_prepend_file calls
header('Vary: Accept-Language') because most pages do language-negotiation.
But if a single file generates, say, an image, it would improve caching if
the Vary header was removed. Setting it to the empty string using
header('Vary:') is not equivalent to unsetting the header.
I suggest extending the behaviour of header()
so that when the first
argument does not contain a colon (and does not begin with "HTTP/"), e.g.
header('Vary'), it unsets the header with the specified name.
AFAICT this change is backwards compatible. According to the HTTP spec, RFC
2616, section 4.2, header lines must include a colon, so calling e.g.
header('Vary') does currently not generate a valid header:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
The attached patch contains an implementation for the cgi and apache2handler
SAPIs.
AFAICT these SAPIs don't need to be changed:
cli, embed, isapi, milter, pi3web, thttpd, tux, webjames.
These SAPIs need additional patching:
apache, apache_hooks, apache2filter, continuity/capi, caudium, nsapi,
phttpd, roxen
I don't have an easy way to test these SAPIs, so any help with adding
support for them is appreciated. AFAICT some of these don't have full
header()
support (in particular for the second $replace parameter), so it
may not be a big issue if they aren't patched right away.
For some reason I couldn't build apache2filter on my machine.
The atteched phpt file is intended to be put in
ext/standard/tests/general_functions.
What do you think of the general idea of being able to unset headers?
And what do you think of my patch?
This is my first patch for PHP. I am not a strong C programmer.
Christian
When a header has been set using header('Foo: bar') it can be replaced
with
other headers, but it cannot be removed.
I like the idea of being able to "unset" headers.
I'm not sure I like the idea of calling what looks lik an invalid
header()
to unset one...
One might envision a future PHP that would want to, for example, say:
"Invalid header: Header must start with [A-Z]:"
for somebody who does:
header($foo);
where $foo is some random typo string that's not a header at all.
At the risk of incurring the wrath of everybody else, I'd prefer to
see a new function like header_unset (or unset_header) to "undo" a
header.
Some questions I'd have about functionality:
If a header was not set, and then you unset it, is that an error or
E_NOTICE
or anything?
If you try to unset a header after the headers have gone out,
presumably the same nifty message about WHERE the header was set would
be output.
But then to be truly pedantic, what if you unset a header that was
never set in the first place, after the headers have gone out? Is
this an error or any kind?
Just trying to anticipate all the edge cases. :-)
--
Some people have a "gift" link here.
Know what I want?
I want you to buy a CD from some indie artist.
http://cdbaby.com/from/lynch
Yeah, I get a buck. So?
Richard Lynch wrote:
At the risk of incurring the wrath of everybody else, I'd prefer to
see a new function like header_unset (or unset_header) to "undo" a
header.
Currentlyheader()
supports adding, replacing and appending to existing
headers as well as specifying the response status code, so I think that
adding a header_unset() would break the current tradition. But I wouldn't
object to adding a new function, though this is probably above by skills.
If a header was not set, and then you unset it, is that an error or
E_NOTICE
or anything?
No. I think that the currentheader()
implementation relies on the
reasonable assumption that the user don't need to know or care what headers
are already set. For instance, by default existing headers are silently
overwritten.
If you try to unset a header after the headers have gone out,
presumably the same nifty message about WHERE the header was set would
be output.
Yes - the same error message is generated for header('Foo') and header('Foo:
bar').
But then to be truly pedantic, what if you unset a header that was
never set in the first place, after the headers have gone out? Is
this an error or any kind?
Yes -header()
always generates an error when called after the headers have
gone out. This is analog to the current behaviour when setting a header that
was already set.
Just trying to anticipate all the edge cases. :-)
I appreciate that :-) I should probably add checks for these to the phpt.
Christian
Christian Schmidt wrote:
What do you think of the general idea of being able to unset headers?
And what do you think of my patch?
If you need this kind of flexibility, I recommend you make an
HttpHeaders class which manages these things and then sends them when
necessary.
--
Edward Z. Yang GnuPG: 0x869C48DA
HTML Purifier http://htmlpurifier.org Anti-XSS Filter
[[ 3FA8 E9A9 7385 B691 A6FC B3CB A933 BE7D 869C 48DA ]]
Christian Schmidt wrote:
What do you think of the general idea of being able to unset
headers?
And what do you think of my patch?If you need this kind of flexibility, I recommend you make an
HttpHeaders class which manages these things and then sends them when
necessary.
That's what I do. All you need is some simple functions:
$headers = array();
addHeader($name, $value) {
global $headers;
$headers[$name] = $value;
return true;
}
deleteHeader($name) {
global $headers;
if (array_key_exists($name, $headers)) {
unset($headers[$name]);
}
return true;
}
sendHeaders() {
global $headers;
foreach ($headers as $name => $value) {
header($name . ': ' . $value);
}
return true;
}
Edward Z. Yang wrote:
If you need this kind of flexibility, I recommend you make an
HttpHeaders class which manages these things and then sends them when
necessary.
Thanks, I'll consider that for now. However, it has the downside that I
have to make an explicit function call in every PHP file in order to
send the headers. My use case is a site with an auto_prepend_file that
sets a header that is relevant for almost all .php files on the site
except a few that unsets the header.
So I hope people my patch for the PHP core will still be considered. I
think the added functionality is in line with the existing functionality
to replace and append to existing headers.
Christian