|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2003-05-27 16:38 UTC] kop at meme dot com
I lied. I developed on php 4.1.2 (Apache 1.3.27) but I see from the documentation there's no fix in future releases. This request could also be catagorized under: Network -> HTTP Related There's no way to use php to send multiple web pages (mime multipart/mixed messages) in response to a single http 1.1 request, as is needed to do things like generate a "Please wait" page while a long database query is running. Bugzilla is an example of an application which uses this technique to generate a "Please wait" message. Note that this is a w3 approved usage of multipart/mixed. See: http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html The immediate problem is that the header() function does nothing (but issue warnings) once output is generated by a php script. This 'extra safety feature' breaks a useful functionality. To retain a completely general ability to mess with http headers, header() should be able to output at any time, and the output of header() should be dependent upon execution order. (Clearly, there are issues surrounding the empty lines that delimit http headers from content. Perhaps these could be auto-generated as php knows whether content has been output.) Alternately, there could be a way to prevent php from generating any headers, leaving all http header generation up to the php script. But it's nice to have php "do headers" so the programmer doesn't have to know everything about everything. An appealing solution is to have a "begin_mime_part([content_type]);" function. Content type would default to "text/html". This function must be used before any output is generated, as with header(). header() may be called anytime after a call to begin_mime_part(), the resultant headers would apply to the part. The first time begin_mime_part() is called it would generate the content boundary string (a good one, not like in my example below) and output a Content-type: of mime/multipart, as well as a content boundary and a Content-type: header for the mime part. Begin_mime_part() _may_ also be called at any time during script execution, at which point it will output the content boundary, flush(), and another Content-Type: header.. Scripts that call begin_mime_part() must (transparently to the php coder) output the content boundary when the script exits. Here's my sample php script to generate a "please wait" page, that doesn't work. (Untested, of necessity.) <?php /* Example of how to do a "please wait" message while a web page loads. * * May 27, 2003 * * Karl O. Pinc <kop@meme.com> * * The idea is to send two complete web pages in response to a single * client request. The first page has the "please wait" message, the * second is the data we want to deliver. We send two pages by returning * multipart mime document, each page being a separate part. * * For this page to work with apache/php the php short_open_tag configuration * directive must be set to "off", so the xml declaration is passed to the * client. Put "php_flag short_open_tag off" (in a <Directory> directive?) * in /etc/httpd/conf/httpd.conf or a .htaccess file. * * Note that this page relies on the w3.org site for the * xhtml dtd declaration. If you want to be stand-alone, copy * the document to your own server and adjust the URLs in the doctype * declaration. (The xmlns namespace in the "head" tag is a string * identifying the namespace, not a document.) * * Technique from "The Linux Journal, Issue 82", "Web Servers and * Dynamic Content", http://www.linuxjournal.com/article.php?sid=4386, the * section titled "Pushing Continual Updates to the Browser". */ // (Recall, header() _must_ be called before any output is sent. Check // those require()-s! You may want to convert them to include()-s.) // Have the server tell the client we'll be sending a multipart mime document. header('Content-;Type:multipart/x-;mixed-;replace;boundary=SoMeRaNdOmTeXt'); header('--SoMeRaNdOmTeXt'); header('Content-type: text/html'); ?> <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/css" href="markup.css"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> <head> <title>Test page -- waiting</title> </head> <body> <p> Please wait while our computer does something important sounding.... </p> </body> </html> <?php // Finish up the first page, and send it. header('--SoMeRaNdOmTeXt', TRUE); flush(); // Wait 5 seconds, so we can read the first page. sleep(5); // Start the second page. header('Content-type: text/html', TRUE); ?> <?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/css" href="markup.css"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> <head> <title>Test page</title> </head> <body> <p> All done. Ain't you glad you waited? </p> </body> </html> <?php // Finish up the second page and send it. header('--SoMeRaNdOmTeXt', TRUE); ?> PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Tue Dec 16 21:00:02 2025 UTC |
Thank you for pointing out that interesting technique (at least I was not aware of it). There's not much magic in the header function - it's just like "print", but it allows to overwrite the HTTP headers that are sent to the browser _before_ your HTML page. "Headers" in the middle of the HTML page are no headers in this sence, they are just normal text. After replacing the "-;" in the Linux Journal article with "-", the C code can be translated directly into PHP: <?php $Boundary = "SoMeRaNdOmTeXt"; header("Content-Type: multipart/x-mixed-replace; boundary=$Boundary"); print "-$Boundary\n"; for($i=1; $i<=10; $i++) { print "Content-type: text/html\n\n"; print "<HTML><HEAD></HEAD><BODY><H3>Update #$i</H3></BODY></HTML>\n"; print "\n-$Boundary\n"; flush(); sleep(1); } print "Content-type: text/html\n\n<HTML><HEAD></HEAD>" ."<BODY><H3>That's all kids!</H3></BODY></HTML>\n"; flush(); ?>