开发者

Will all code after redirect header in PHP always get executed?

So I know the general rule of thumb is after doing a header redirect in PHP, you should call exit() to avoid having extra code running, but I want to know if you put code after the redirect header, if it will always run?

I was doing some research on various ways of tracking referrals in Google Analytics and came across this post: Google Analytics Tips & Tricks – Tracking 301 Redirects in Google Analytics

It recommends doing something like this:

<?
Header( “HTTP/1.1 301 Moved Permanently” );
Header( “Location: http://www.new-url.com” );
?>

开发者_JS百科<script type=”text/javascript”>
var gaJsHost = ((“https:” == document.location.protocol) ? “https://ssl.” : “http://www.”);
document.write(unescape(“%3Cscript src=’” + gaJsHost + “google-analytics.com/ga.js’ type=’text/javascript’%3E%3C/script%3E”));
</script>
<script type=”text/javascript”>
try {
var pageTracker = _gat._getTracker(“UA-YOURPROFILE-ID”);
pageTracker._trackPageview();
} catch(err) {}</script>

From the way I've always understood the header() function, it's up to the browser and it can run the redirect whenever it wants to. So there's no guarantee the JavaScript would actually begin or finish executing prior to the redirect occurring.

PHP's documentation for the header() function indicates the reason for exiting after a redirect is to "make sure that code below does not get executed when we redirect." That doesn't sound like they guarantee all following code will run, just that it could happen.

Regardless, I found a different way to actually manage the tracking, but I wanted to see if I could find out how exactly header() worked in this situation..

Thanks for your help.


Using the header function in PHP only adds to the headers of the response returned by the server. It does not immediately send any data and does not immediately terminate the connection. Any code after the header call will be executed.

In particular, it's a good idea to add a response body even after doing a 301 redirect so that clients that do not support the redirect also get some descriptive response. Infact according to the HTTP 1.1 specification Section 10.3.2 -

Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s). If the 301 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.


It's a race condition. Once the redirect header is sent to the browser, the browser will close the current connection and open a new one for the redirect URL. Until that original connection is closed and Apache shuts down the script, your code will continue to execute as before.

In theory, if there was a sufficiently fast connection between the client/server, and there was no buffering anywhere in the pipeline, issuing the header would cause the script to be terminated immediately. In reality, it can be anywhere between "now" and "never" for the shutdown to be initiated.


The HTML after your Location line doesn't run inside PHP; it would run in the browser. It's up to the browser whether or not to execute the Javascript that you've included on that page; PHP has nothing to do with it.

To me, the PHP docs imply that any PHP below the header() when you send a redirect will continue to run. But it 'runs' in the PHP interpreter, dumping JS to the browser. There's no relation between what it says in the PHP docs and whether or not the JS gets run by the browser.


EDIT:

Well, as Anupam Jain pointed out, looks like that browsers do not terminate connection without getting the response body and it sounds sensible. So i rethinked my answer

That doesn't sound like they guarantee all following code will run

Exactly More likely it's a warning in case there is some sensible code that shouldn't be executed. A private page contents for example. So, beside sending header you have to also make sure that no sensitive content were sent and exit looks like quite robust solution. So, I'd phrase it as "make sure that sensible code below does not get executed when we redirect."

So there's no guarantee the JavaScript would actually begin or finish executing prior to the redirect occurring.

Exactly It seems it has nothing to do with script execution but rather with browser's will to execute anything after getting 3xx response. I think I'm gonna test it, but you can test it as well too.


I have noticed that the code does still execute and multiple headers based on if statements can cause a "redirect loop error". i made it a habit to now add in die("Redirecting..."); after every header redirect and have not see the problem persist.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜