output to file

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View

Another bafflement....

   header("Content-type: application/octet-stream");
   header("Content-Disposition: attachment; filename=$fileName");
   header("Pragma: no-cache");
   header("Expires: 0");

[   create $string ]

   echo $string;

Thought this was supposed to write the $filename yet it displays
on the screen.

What wrong?

Re: output to file

On Dec 1, 2:17=A0pm, bco...@nyx.net (blanche cohen) wrote:
Quoted text here. Click to load it

Make sure you're not sending the other headers earlier in the
execution path:


Re: output to file

Quoted text here. Click to load it

ah....so if any other headers were sent at any time, these headers
are ignored. Is there a way to "erase" headers? I would have thought
that a subsequent header block would have taken precedence....guess not.


Re: output to file

Quoted text here. Click to load it

No, subsequent headers should raise a warning (you *do* have warnings turned
on) advising that headers have already been sent. The is usally caused by
some content being output. A prior echo perhaps. Even something simple like
some whitespace before the very first <?php in your file.

Re: output to file

Quoted text here. Click to load it

According to the webpage Matt pointed me to, use of header() does
overwrite previous version.

Yes, I am getting the warnings.

I just put together a very simple 4 line program that consists of
the headers and a string with tabs that should produce an excel

function dump_database() {
   header("Content-type: application/octet-stream");
   header("Content-Disposition: attachment; filename=Data.xls");
   header("Pragma: no-cache");
   header("Expires: 0");
   echo "hello\tworld\tobvious, right?\t\r\n";

This is called by

<? include("dump.php");

This displays on the screen but does NOT create a file, any file.

I'm baffled. Previous routines with the header create an excel file. Why
not this one?

Re: output to file

Blanche wrote:
Quoted text here. Click to load it

As rf said - if you get the warning, the headers have already been sent
and further requests cannot go.  Check your files VERY CAREFULLY for
whitespace outside the <?php ... ?> tags.

The warning is there for a purpose!

Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.

Re: output to file

[snip for length]

Quoted text here. Click to load it

[editorial comment or rant, take your pick]

If php is so dependent on positional syntax, I'm disappointed and
surprised.  This is not the dark ages of programming languages.

More important, reading the documentation on header() explicitly
states that subsequent use of header() overrides previous use. To
me, that means it shouldn't matter. I still don't understand the
"whitespace outside the <? ?> tags" issue.

[end comment]

Re: output to file

Quoted text here. Click to load it

Reading the documentation on header() on php.net explicitly states,
in the Description section, "Remember that header() must be called
before any actual output is sent, either by normal HTML tags, blank
lines in a file, or from PHP".

That list probably ought to include (invisible) BOMs from a file
using UTF-8 as a character set, often placed there by editors.  I
do think perhaps PHP could use an option to ignore (or at least not
copy) BOMs.

The documentation on php.net doesn't say that subsequent use of
header() overrides previous use unconditionally.  It won't if the
second parameter (replace) is false, in which case a duplicate
header is created (there are a few good reasons for this in some
situations).  And the header() function won't work if the boundary
between headers and body has already been sent, replacement or not.

Quoted text here. Click to load it

If you put *ANYTHING* outside the <? ?> tags, it is sent to the
browser without change, presuming it contains HTML, Javascript,
or whatever.  Most HTML pages function fine as a PHP page without
change even if there isn't any PHP in it.

If you send non-header output, then any headers up to that point
are sent, followed by a blank line, followed by the non-header
output.  At this point, you can't have any more headers.  The
boundary between headers and body has already been sent, and it
cannot be called back.  There is no provision in the HTTP protocol
for "footers".

In much the same way, you can't let a telephone call go unanswered
after you've picked up a ringing phone and said "Hello".  It's too
late and you can't change the past.

Re: output to file

Quoted text here. Click to load it

thanks for the info and analogy. explains much more than the docs.

Re: output to file

On Wed, 02 Dec 2009 00:34:43 -0600, Gordon Burditt wrote:
Quoted text here. Click to load it

It kind of depends on the OS. SOME will ignore BOMs. Some won't. (IIRC
Windows does and I know *nix host don't. Which might lead to a case
where a particular .php file might work just fine on someone's local
test system and get a header error on the production host, or vice
versa, depending on which is which.)

100. Finally, to keep my subjects permanently locked in a mindless
    trance, I will provide each of them with free unlimited Internet
    --Peter Anspach's list of things to do as an Evil Overlord

Re: output to file

On Thu, 03 Dec 2009 15:19:53 -0600, Peter H. Coffin wrote:
Quoted text here. Click to load it

It's actually configuration, rather than OS, specific. PHP will only
strip BOMs (and use them to determine script encoding) if compiled with
--enable-zend-multibyte and if the detect_unicode configuration option
hasn't been disabled.[1]

Non-multibyte builds of PHP (which is the usual configuration) just
handle the BOM like any other non-script content and output it, as plenty
of people have already noted in this thread.


[1] http://au2.php.net/ini.core#ini.detect-unicode

Re: output to file

On Fri, 4 Dec 2009 03:27:56 +0000 (UTC), Adam Harvey wrote:
Quoted text here. Click to load it

Excellent clarification. Thank you.

61. If my advisors ask "Why are you risking everything on such a mad
    scheme?", I will not proceed until I have a response that satisfies
    them.  --Peter Anspach's list of things to do as an Evil Overlord

Re: output to file

Quoted text here. Click to load it

Blanche, you are missing one whole bucket full of information about how HTTP
actually works, and how PHP outputs the data stream that ends up as a page
at a browser.

There is nothing complex about the data stream.

The headers come first, in plain text.

Next comes a single blank line meaning [end of headers].

Next comes the data for that HTTP request, the actual page the server reads
from a .html file, or the data you build using PHP. Once again in plain text

Here is what a response looks like, and yes, it is actual text, readable by
you and me. This is real, live data. This is what one of my PHP scripts
sends down.

Date: Wed, 02 Dec 2009 05:05:22 GMT
Server: Apache/2.2.11 (Win32) PHP/5.2.9-1
X-Powered-By: PHP/5.2.9-1
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: private
Pragma: no-cache
Content-Length: 4342
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

"http://www.w3.org/TR/html4/strict.dtd ">
<link rel="stylesheet" type="text/css" href="all.css">
<link rel="stylesheet" type="text/css" href="print.css" media="print">
[followed by the rest of the page]

Note the blank line in the middle. The delimiter line.

That's the first thing to realize. The entire HTTP response is simply a
"text file".

The second and most major thing to realise is that from PHPs point of view
it *is* very much like a file. You "write" something to the response "file",
using echo or print or header or whatever and it's gone. Written. Sent off
to the browser. Just as if you wrote it to a real disk file, or a printer,
or a modem or whatever. You can't write a bunch of stuff  to a printer and
then a bit later decide to go back two pages and write some extra stuff to
that page. That page is already in the pick up the paper slot.

I don't output any of my own headers on this abovementioned page. I let PHP
write its defaults for me. The very first thing my script writes out is that
doctype. Now, PHP is quite aware that *I* have not used the header function
to write my own headers so it knows it has to write its own default set for
me. And every HTTP response requires headers, otherwise it's not an HTTP

When I write that doctype line PHP does a hurry up and writes its default
headers, the blank line that delimits the headers, and then my doctype line.

Now, what would happen if I were to use header to attempt to send another
header? Conceivably nothing. PHP could simply write that out to the response
"file" and carry on. But it would not be a header. It would be the next line
of the HTML page, the one after my doctype, and would probably trigger the
browser to decide the <body> element should be opened and it would display
that "header" on the viewport.

However as I said elsewhere PHP won't do that. It helps you find your errors
by noticing this and refusing to send the "header", and it gives you that
warning. That is the purpose that warning is there, and a very valid one.
Imagine the amount of debugging you would have to do if PHP did not tell you
you had made this error.

Now do you see what is going on?

And it's not just PHP. Any language, process or whatever that is sending
HTTP responses via a web server will have exactly the same issues. It's just
the way it works.

The very first thing you learn when writing your own headers is to do it
*first*, before any other bit of "content" goes out. If you don't you will
trigger the default headers, as above, and get that warning.

And note, that content can be anything at all. It can be even a single space
before <?php, as in if the very first line of your .php file is, and I quote
for clarity:
' <?php'

See the space before the <. That'll do it. Even this will do it: '<<?php'.
The first < is content.

As to your remarks about PHP, what else should it do. It's doing exactly
what you are telling it to do. Take that last quoted bit above. Perhaps you
really wanted the very first byte of your HTML page to be a <, followed by
whatever (perhaps a doctype) you generate using PHP. How is PHP to know?
Should it remove that byte? No. Should it remove the space mentioned two
paragraphs up? No. Just as it should not remove anything before the <?php is
the following:

"http://www.w3.org/TR/html4/strict.dtd ">

And as to the fact that header will overwrite what went before (or rather
the browser will accept the last header of a particular type it receives,
forgetting what came before), yes, the manual and what you read is correct,
providing you are still at the "writing of headers" stage. Once any content
has gone out then you can no longer write headers, because that blank
delimiter line has been sent out and you are now writing content. The
headers are long gone down the wire to the browser.

You may find in your wanderings that all of this won't happen if you have
outupt buffering turned on. Don't. That is not fixing your problem, it's
just covering it up and sooner or later it will somehow come back to bite


Re: output to file

[just about everything snipped...]

ah, can I claim senior moment? or perhaps senior days?

Yes, I do know how HTTP works, all to well, I taught it extensively
back in the Dark Ages of the web (94-2002) at the college

but, since I've left that stuff to others for so many years, I
completely spaced it out.

thanks for the reminder --- gotta get my old notes out, altho
your summary is more concise than my teaching notes.

Quoted text here. Click to load it

Re: output to file

Blanche wrote:
Quoted text here. Click to load it

It's not a rant - it's an attempt to get you to pay attention to what
the warnings are telling you!  Do you think Zend went to all the trouble
to keep track of the status, test for content being sent and issue a
warning message just to screw up your output?

This has NOTHING to do with PHP.  It is a restriction of HTML.  There is
nothing PHP or any other language can do to change this.

And whitespace outside the <?php ... ?> tags means just that.
Whitespace is non-printable characters, like spaces, tabs and newlines.
  Outside the <?php ... ?> tags means anything in your file not within
those tags.

This could be leading or trailing spaces or newlines, for instance.

Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.

Re: output to file

Quoted text here. Click to load it



Re: output to file

rf wrote:
Quoted text here. Click to load it

Sorry, you're correct - it is HTTP, not HTML :)


Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.

Re: output to file

Quoted text here. Click to load it

Despite the fact that "Blanche" (the OP) claims to have previously taught
HTML, I believe the lack of <tag>...</tag> notation leads to your
misinterpretation of the "rant" as something offensive to your statements,
rather than a qualification of the OP's viewpoints.

I thought the same thing at first, but the context changed my mind. The OP
was being critical of their own statements and understanding.

Re: output to file

Quoted text here. Click to load it

Aside from your personal beliefs on how HTTP should work--which is
more OT than discussing HTTP in a PHP newsgroup--what is so hard about
this warning message?

2: Cannot modify header information - headers already sent by (output
started at /home/matt/web/header.php:117) (/home/matt/web/test.php:4)

This tells you EXACTLY where to look for the content output that is
prohibiting you from sending further headers...

test.php, line 4 -> where I tried to send a header after the output
has been started
header.php, line 117 -> where the content started that blew up my
later call to header().

Or, if you had bothered to use the function I pointed you to in the
first followup to your question:

if (headers_sent($filename, $linenum))
  echo "$filename : $linenum";

/home/matt/web/header.php : 117

Again, it tells you exactly where to look to fix this.


Re: output to file

Quoted text here. Click to load it

*IF* there has been no content already sent.

Sending content (even a blank line before <?php) cause headers to be send,
and that content to be sent.

Once headers and content have been sent you cannot send any more headers,
for the reason that the client would treat them as content. PHP is being
nice to you by refusing to send them and issuing the warning.

Quoted text here. Click to load it

Then you are sending content before sending your headers. As Jerry said,
check your code.

Quoted text here. Click to load it

White space somewhere. Load the entire thing up to a server somewhere with a
.txt extension and let us look at it.

Site Timeline