ZF-2841: Zend_Cache_Frontend_Page and Redirector : add header redirect saving support to Zend_Cache_Frontend_Page

Issue Type: Improvement Created: 2008-03-10T10:03:00.000+0000 Last Updated: 2008-09-02T10:38:59.000+0000 Status: Resolved Fix version(s): - 1.6.0 (02/Sep/08)

Reporter: David Berlioz (quazardous) Assignee: Fabien MARTY (fab) Tags: - Zend_Cache

Related issues: Attachments: - frontend-page.patch


snapshot : 8205

I m using Zend_Cache_Frontend_Page and Redirector (action helper).

the first time a page is generated, the redirection (gotoRouteAndExit) goes fine, but when the page is called from the cache, "of course" the header 'redirect' is not present...

It will be interesting to add more header support to Zend_Cache_Frontend_Page and of course redirection headers.

best regards


Posted by Fabien MARTY (fab) on 2008-04-19T03:26:34.000+0000

I agree with you

We will work on this part soon

Posted by Geoff Speicher (gspeicher) on 2008-05-21T07:01:09.000+0000

Other important headers (Expires, for example) are also not preserved. This effectively prevents you from caching a far-future expiring document (YSlow recommendation #3).

Is there any good reason not to preserve every response header for cached pages (possibly by default)? I cannot think of a situation where a cached copy of a document would be expected to have different headers than the original.

Posted by Fabien MARTY (fab) on 2008-05-21T10:47:38.000+0000

I just commited into SVN trunk a new option in Frontend_Page backend :

<pre class="highlight">
     * ====> (array) memorize_headers :
     * - an array of strings corresponding to some HTTP headers name. Listed headers
     *   will be stored with cache datas and "replayed" when the cache is hit

Can you try it ?

Posted by Geoff Speicher (gspeicher) on 2008-05-22T12:36:54.000+0000

This patch fixes two issues in rev 9496:

  1. correctly spell "strtolower"
  2. don't truncate header contents that contains a colon

Posted by Fabien MARTY (fab) on 2008-05-22T12:58:13.000+0000

your patch is added to my source tree (thanks)

SVN is down but I will commit it soon

Posted by Fabien MARTY (fab) on 2008-05-24T14:34:37.000+0000

fixed in SVN trunk

Posted by Geoff Speicher (gspeicher) on 2008-05-26T18:36:41.000+0000

works for me, thanks. (i didn't test it for "redirect" which is what this issue was primarily meant to address, so maybe the original author could verify that this works for him as well.)

might still be nice to have a "standard" set of preserved headers, or at least a well-documented set of headers that are generally desirable to preserve. cache troubleshooting is bad enough without having to locate issues related to unexpected/varying HTTP response headers...

Posted by David Berlioz (quazardous) on 2008-06-03T01:02:53.000+0000


Great job ;p

just one thing : the way it's implemented (split header on ':') makes impossible to deal 404 header (in ex) ...

best regard

Posted by David Berlioz (quazardous) on 2008-06-03T01:07:19.000+0000


for the default set of header, maybe a "keep all headers" option would do it...

Posted by Fabien MARTY (fab) on 2008-06-03T10:16:06.000+0000

can you provide an example ?

<pre class="highlight">

to send a 404 header, you don't use this :

header("Status: 404 Not Found"); 


Posted by David Berlioz (quazardous) on 2008-06-03T23:46:45.000+0000


a quick search on g***** says :

header("HTTP/1.0 404 Not Found");

and ...

header("Status: 404 Not Found");

the 2nd form seams to have some compatibility issue

Posted by David Berlioz (quazardous) on 2008-06-04T03:45:33.000+0000


sorry for me it does not work.

I m in MVC mode and the headers are never stored !

[code] public function _flush($data) { if ($this->_cancel) { return $data; } $contentType = null; $storedHeaders = array(); header('Pragma: public'); if (headers_sent()) { //never here because the headers are not sent.... $buffer.='sent'; $headersList = headers_list(); foreach($this->_specificOptions['memorize_headers'] as $key=>$headerName) { $buffer.='m='.$headerName.';'; foreach ($headersList as $headerSent) { $buffer.=$headerSent.'-';

                $tmp = split(':', $headerSent);
                $headerSentName = trim(array_shift($tmp));
                if (strolower($headerName) == strtolower($headerSentName)) {
                    $headerSentValue = trim(implode(':', $tmp));
                    $storedHeaders[] = array($headerSentName, $headerSentValue);

    $array = array(
        'data' => $data,
        'headers' => $storedHeaders
    return $data;


and if I can put an advise : looping on the headers to store and over looping on the header sent is a lack of time. if you want to store 10 headers and if they are 20 headers sent you loop 200 times... it's 180 too many.

1st step : create a temporary array of wanted header in strtolower format

2nd step : loop over header list (without checking if it's sent or not) if(eregi('^([^:])[:]', $headerLine, $regs) ) $headerSentName=strtolower($regs[1]); else { /* special cases */ } and check with in_array in the wanted header ()...

and storing the whole header is easyer than all the split stuff.... (and maybe there can be multiple occurencies one special header)

best regard

Posted by Geoff Speicher (gspeicher) on 2008-06-04T06:13:36.000+0000

Regarding HTTP Status header: the problem applies only to PHP3 (at least according to the link you provided). Clearly PHP3 is not supported by Zend Framework and we should therefore prefer "Status: 404 Not Found" to the alternative.

Regarding your MVC example not working: it's a chicken and egg problem. You have to manually construct the list of headers you want to preserve. I too originally thought it would be nice to have the ability to automatically store all of the headers using headers_list(), but after giving it some thought I don't know if it's a good idea. There are some headers that should usually not be stored, such as Date, Server, X-Powered-By, and Set-Cookie, to name a few.

Regarding inefficiency of the nested loop in the implementation: you're absolutely correct. One way to improve it without using eregi() is to first iterate over _specificOptions['memorize_headers'] to force keys to lowercase, then iterate over headersList, and for each header do the split + strtolower() and use array_key_exists() to check for the key in _specificOptions['memorize_headers']. I don't think there is any way to send multiple occurrences of a header, as PHP is advertised to replace rather than append. I would make and post a patch but svn is down and I don't have up-to-date sources...

Posted by David Berlioz (quazardous) on 2008-06-05T01:14:56.000+0000

I ve found multiple occurrencies of Cache-Control: ...

I think it's not the goal of the cache layer to add header rules. The cache layer must just mimic the page engine...

Posted by David Berlioz (quazardous) on 2008-06-05T01:18:08.000+0000

here is what works with me.... (9566 on snapshot).

it's ereg free and uses explode in place of split... and it stores the whole header ;p

maybe it could be improved with an ereg pattern filter in place of just a fixed string match...

Posted by Wil Sinclair (wil) on 2008-09-02T10:38:59.000+0000

Updating for the 1.6.0 release.

Have you found an issue?

See the Overview section for more details.


© 2006-2018 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.