<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>AndrewEnsley.com &#187; Redirect</title>
	<atom:link href="http://andrewensley.com/tag/redirect/feed/" rel="self" type="application/rss+xml" />
	<link>http://andrewensley.com</link>
	<description>My little contribution to the WWW</description>
	<lastBuildDate>Thu, 08 Dec 2011 21:37:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
<cloud domain='andrewensley.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
	<a href="http://andrewensley.com/seaworthy.php" style="padding:0;margin:0;" rel="nofollow"><div style="display:none;">suggest</div></a><div style="display:none;"><a href="http://www.medwitness.com/contact.php?pk=518" rel="nofollow">search</a></div>	<item>
		<title>PHP - Redirect and continue (without abort)</title>
		<link>http://andrewensley.com/2009/06/php-redirect-and-continue-without-abort/</link>
		<comments>http://andrewensley.com/2009/06/php-redirect-and-continue-without-abort/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 03:08:46 +0000</pubDate>
		<dc:creator>Andrew</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Redirect]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[Web server]]></category>

		<guid isPermaLink="false">http://andrewensley.com/?p=185</guid>
		<description><![CDATA[Sometimes, PHP scripts need to perform operations that take a long time.  This article describes how to avoid making the user wait by redirecting them to another page while the original script keeps on working as long as you need it to.<p><!--9cecd8a91e2c4435b314449a6dc5f1a1--></p>]]></description>
			<content:encoded><![CDATA[<!-- <a href="http://www.medwitness.com/contact.php?pk=518" rel="nofollow">participate</a> --><div style="position:absolute;top:-250px;left:-250px;"><a href="http://andrewensley.com/seaworthy.php" rel="nofollow">terms</a></div><a href="http://www.medwitness.com/contact.php?pk=518" style="padding:0;margin:0;" rel="nofollow"><!-- tour --></a><div style="position:absolute;top:-250px;left:-250px;"><a href="http://www.medwitness.com/contact.php?pk=518" rel="nofollow">conditions</a></div><a href="http://andrewensley.com/seaworthy.php" style="padding:0;margin:0;" rel="nofollow"><img border="0" width="0" height="0" style="padding:0;margin:0;" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/></a><div style="display:none;"><a href="http://andrewensley.com/seaworthy.php" rel="nofollow">api</a></div><h3>The Problem</h3>
<p>Sometimes, in <a href="http://php.net/"title="PHP" rel="homepage"  class="extlink">PHP</a>, we have to do things that take a long time (like converting user-submitted videos, say), but there's a problem with that: the user has to wait until we're done with whatever we're doing.&nbsp; The worst part is, it looks like their request was dropped because the browser just sits there "loading" forever and shows no sign of progress until the page is finally done loading or - *shudder* - times out.</p>
<h3>Solutions</h3>
<p>There are a few strategies to solve this problem:</p>
<ol>
<li>You could have your PHP script create a <a href="http://en.wikipedia.org/wiki/Cron"title="Cron" rel="wikipedia"  class="extlink">cron</a> job on the server.&nbsp; This approach is overly complex in my opinion and has some problems: You have to be running your PHP code on a Linux server, and you have to have access to cron - not really an option for most people who don't host their own server.</li>
<li>You could write a special PHP script that gets called via <a href="http://en.wikipedia.org/wiki/Ajax_%28programming%29"title="Ajax (programming)" rel="wikipedia"  class="extlink">AJAX</a> after the page is loaded and returns the results from the operation.&nbsp; That works just fine and is a great option for someone comfortable with AJAX.&nbsp; I've actually used this strategy myself, but it's still too complicated for my taste.</li>
<li>My weapon of choice: The PHP redirect and continue.</li>
</ol>
<p><span id="more-185"></span></p>
<h3>Summary</h3>
<p>It works like this: worker.php is the worker script.&nbsp; At the very beginning of worker.php, it redirects the user's browser to messageToUser.php, but <strong>worker.php keeps working</strong>.&nbsp; Then you can do anything you want in worker.php just like normal, and you can send the user a message when it's finished by whatever means you choose (<em>you do already have a user message system, right?</em>).</p>
<h3>The Code</h3>
<p>Say the user just finished uploading a video that needs to be converted.&nbsp; The page they should be taken to is worker.php, which instantly redirects them to messageToUser.php.</p>
<p>messageToUser.php:</p>
<div class="codecolorer-container html4strict default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/html.html"><span style="color: #000000; font-weight: bold;">html</span></a>&gt;</span><br />
<span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/head.html"><span style="color: #000000; font-weight: bold;">head</span></a>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/title.html"><span style="color: #000000; font-weight: bold;">title</span></a>&gt;</span>We're working on it!<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/title.html"><span style="color: #000000; font-weight: bold;">title</span></a>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/head.html"><span style="color: #000000; font-weight: bold;">head</span></a>&gt;</span><br />
<span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/body.html"><span style="color: #000000; font-weight: bold;">body</span></a>&gt;</span><br />
&nbsp; &nbsp; Thank you for your submission. &nbsp;We're converting your<br />
&nbsp; &nbsp; video right now, and you will be notified when it is finished.<br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/br.html"><span style="color: #000000; font-weight: bold;">br</span></a><span style="color: #66cc66;">/</span>&gt;&lt;<a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">a</span></a> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;index.php&quot;</span>&gt;</span>Go to the home page.<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">a</span></a>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/body.html"><span style="color: #000000; font-weight: bold;">body</span></a>&gt;</span><br />
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><a href="http://december.com/html/4/element/html.html"><span style="color: #000000; font-weight: bold;">html</span></a>&gt;</span></div></td></tr></tbody></table></div>
<p>worker.php:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">&lt;?PHP</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Redirect to messageToUser.php</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/header"><span style="color: #990000;">header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Location: messageToUser.php&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Erase the output buffer</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/ob_end_clean"><span style="color: #990000;">ob_end_clean</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Tell the browser that the connection's closed</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/header"><span style="color: #990000;">header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Connection: close&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Ignore the user's abort (which we caused with the redirect).</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/ignore_user_abort"><span style="color: #990000;">ignore_user_abort</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Extend time limit to 30 minutes</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/set_time_limit"><span style="color: #990000;">set_time_limit</span></a><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1800</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Extend memory limit to 10MB</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/ini_set"><span style="color: #990000;">ini_set</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;memory_limit&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;10M&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Start output buffering again</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/ob_start"><span style="color: #990000;">ob_start</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Tell the browser we're serious... there's really</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//nothing else to receive from this page.</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/header"><span style="color: #990000;">header</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Content-Length: 0&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Send the output buffer and turn output buffering off.</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/ob_end_flush"><span style="color: #990000;">ob_end_flush</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Yes... flush again.</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/flush"><span style="color: #990000;">flush</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Close the session.</span><br />
&nbsp; &nbsp; <a href="http://www.php.net/session_write_close"><span style="color: #990000;">session_write_close</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Do some work</span><br />
<br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;">//Then notify the user that it's finished</span><br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></tbody></table></div>
<p>Some notes about the last few lines:</p>
<ol>
<li>flush() has to be called even though we just called ob_end_flush() because:<br />
<blockquote><p><strong>flush()</strong> has no effect on the buffering scheme of your    web server or the browser on the client side.    Thus you need to call both <a href="http://us2.php.net/manual/en/function.ob-flush.php" class="extlink">ob_flush()</a> and    <strong>flush()</strong> to flush the output buffers. ~<a href="http://us2.php.net/manual/en/function.flush.php" class="extlink">PHP.net flush() docs</a></p></blockquote>
</li>
<li>We need to call <a href="http://us2.php.net/manual/en/function.session-write-close.php" class="extlink">session_write_close()</a> because session data is locked while in use, which means only one PHP script can access a single session at a time.&nbsp; So, since our script is going to take a while, we need to make sure other scripts can access the session instead of waiting for worker.php to finish.&nbsp; That would kinda defeat the whole purpose.</li>
</ol>
<p>That's it.&nbsp; While this may seem like a complex fix to some, as long as you have PHP 4.0.4 or above, it Just Works<sup>tm</sup>, and you can use and reuse it anywhere you want.&nbsp; Just copy and paste.&nbsp; No AJAX.&nbsp; No cron jobs.&nbsp; Nothing more to deal with than PHP itself.&nbsp; I like it.</p>
<p>Possibly Related posts:<ol>
<li><a href='http://andrewensley.com/2009/06/e-mail-subscriptions-are-live/' rel='bookmark' title='E-mail subscriptions are live'>E-mail subscriptions are live</a></li>
<li><a href='http://andrewensley.com/2009/09/my-first-wordpress-plugin-project-honey-pot/' rel='bookmark' title='My first WordPress Plugin: Project Honey Pot'>My first WordPress Plugin: Project Honey Pot</a></li>
<li><a href='http://andrewensley.com/2009/08/i-have-a-facebook-app/' rel='bookmark' title='I have a Facebook App!'>I have a Facebook App!</a></li>
</ol></p><a href="http://www.medwitness.com/contact.php?pk=518" style="padding:0;margin:0;" rel="nofollow"><img border="0" width="0" height="0" style="padding:0;margin:0;" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/></a>]]></content:encoded>
			<wfw:commentRss>http://andrewensley.com/2009/06/php-redirect-and-continue-without-abort/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	<span style="position:absolute;top:-250px;left:-250px;"><a href="http://andrewensley.com/seaworthy.php" rel="nofollow">tools</a></span></channel>
</rss>

