!DOCTYPE Problem

B

Bruce A. Julseth

I have a PHP page that fails when I have a <!DOCTYPE but works without it.

Right after the <!DOCTYPE is some PHP code where I call a PHP function that
tests for the user being logged on. If the user is not logged on, I call
header("Location: Login.php"). I'm getting a header already sent error
message if I have the <!DOCTYPE. If the <!DOCTYPE is missing, the login.php
page is loaded.

Is there a way to circumvent this problem without removing the <!DOCTYPE?

Thanks...

Bruce
 
C

cwdjrxyz

I have a PHP page that fails when I have a <!DOCTYPE but works without it..

Right after the <!DOCTYPE is some PHP code where I call a PHP function that
tests for the user being logged on. If the user is not logged on, I call
header("Location: Login.php"). I'm getting a header already sent error
message if I have the <!DOCTYPE. If the <!DOCTYPE is missing, the login.php
page is loaded.

Is there a way to circumvent this problem without removing the <!DOCTYPE?

If everything else in the php code is correct, omit the Doctype at the
very top of the page and start with the php which may be an include if
you are going to use this for several pages. Then use the php to write
the Doctype near the end of the php code. If you do absolutely
anything before the header conversation between the server and
browser, then it is too late to mess with the header exchange. To
check the page at the W3C validator, go to the page and right click,
select to view source code, and copy. Then paste this in the box for
direct code input at the W3C validator rather than using a url.
Sometime a url pasted in will work correctly for a php page, sometimes
not, and sometimes you use header exchange to generate any one of
several possible pages, depending on what is found. A html page that
has some php usually should have the extension .php rather than .html
or .xhtml.
 
C

cwdjrxyz

If everything else in the php code is correct, omit the Doctype at the
very top of the page and start with the php which may be an include if
you are going to use this for several pages. Then use the php to write
the Doctype near the end of the php code. If you do absolutely
anything before the header conversation between the server and
browser, then it is too late to mess with the header exchange. To
check the page at the W3C validator, go to the page and right click,
select to view source code, and copy. Then paste this in the box for
direct code input at the W3C validator rather than using a url.
Sometime a url pasted in will work correctly for a php page, sometimes
not, and sometimes you use header exchange to generate any one of
several possible pages, depending on what is found. A html page that
has some php usually should have the extension .php rather than .html
or .xhtml.

Perhaps an example of how you write the Doctype in the php at the very
top of the page will help. My example will write one of two possible
Doctypes depending on what the header exchange finds - xhtml 1.1 or
html 4.01 strict. Your other code of course will be different from
mine, depending on exactly what you are doing with the php in the
header exchange.

<?php
$charset = "UTF-8";
function fix_code($buffer) {
return (preg_replace("!\s*/>!", ">", $buffer));
}
if (stristr($_SERVER[HTTP_ACCEPT], "application/xhtml+xml") ||
stristr($_SERVER["HTTP_USER_AGENT"],"W3C_Validator") )
{
$mime = "application/xhtml+xml";
$prolog_type = "<?xml version=\"1.0\" encoding=\"$charset\" ?>\n<!
DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/
TR/xhtml1/DTD/xhtml11.dtd\">\n<html xmlns=\"http://www.w3.org/1999/
xhtml\" xml:lang=\"en\">\n";
header("Content-Type: $mime;charset=$charset");
header("Vary: Accept");
print $prolog_type;
}
else
{
$mime = "text/html";
ob_start("fix_code");
$prolog_type = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//
EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n<html lang=\"en\">
\n";
header("Content-Type: $mime;charset=$charset");
header("Vary: Accept");
print $prolog_type;
}
?>

Writing a code with php is much like writing code with docuent.write
using JavaScript, but there are enough differences to get you into
trouble if you are not careful.
 
B

Bruce A. Julseth

If everything else in the php code is correct, omit the Doctype at the
very top of the page and start with the php which may be an include if
you are going to use this for several pages. Then use the php to write
the Doctype near the end of the php code. If you do absolutely
anything before the header conversation between the server and
browser, then it is too late to mess with the header exchange. To
check the page at the W3C validator, go to the page and right click,
select to view source code, and copy. Then paste this in the box for
direct code input at the W3C validator rather than using a url.
Sometime a url pasted in will work correctly for a php page, sometimes
not, and sometimes you use header exchange to generate any one of
several possible pages, depending on what is found. A html page that
has some php usually should have the extension .php rather than .html
or .xhtml.

Perhaps an example of how you write the Doctype in the php at the very
top of the page will help. My example will write one of two possible
Doctypes depending on what the header exchange finds - xhtml 1.1 or
html 4.01 strict. Your other code of course will be different from
mine, depending on exactly what you are doing with the php in the
header exchange.

<?php
$charset = "UTF-8";
function fix_code($buffer) {
return (preg_replace("!\s*/>!", ">", $buffer));
}
if (stristr($_SERVER[HTTP_ACCEPT], "application/xhtml+xml") ||
stristr($_SERVER["HTTP_USER_AGENT"],"W3C_Validator") )
{
$mime = "application/xhtml+xml";
$prolog_type = "<?xml version=\"1.0\" encoding=\"$charset\" ?>\n<!
DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/
TR/xhtml1/DTD/xhtml11.dtd\">\n<html xmlns=\"http://www.w3.org/1999/
xhtml\" xml:lang=\"en\">\n";
header("Content-Type: $mime;charset=$charset");
header("Vary: Accept");
print $prolog_type;
}
else
{
$mime = "text/html";
ob_start("fix_code");
$prolog_type = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//
EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n<html lang=\"en\">
\n";
header("Content-Type: $mime;charset=$charset");
header("Vary: Accept");
print $prolog_type;
}
?>

Writing a code with php is much like writing code with docuent.write
using JavaScript, but there are enough differences to get you into
trouble if you are not careful.

Thanks for the suggestion as well as the sample code.. Appreciate you
taking the time. I'm sure it will fix my problem..

Bruce
 
H

Harlan Messinger

Bruce said:
I have a PHP page that fails when I have a <!DOCTYPE but works without it.

Right after the <!DOCTYPE is some PHP code where I call a PHP function that
tests for the user being logged on. If the user is not logged on, I call
header("Location: Login.php"). I'm getting a header already sent error
message if I have the <!DOCTYPE. If the <!DOCTYPE is missing, the login.php
page is loaded.

Correct. You're starting to serve the page and then suddenly changing
your mind in midstream. The proper order of execution is: Confirm that
this is the page to be served, and *then* serve it.

More details: The server has to send the HTTP headers before it sends
the body of the response, so the instant you send any characters at all
to the client, the server has to precede it with the headers. Trying to
change the headers after they've already been sent is an error condition.

The solution is to put the DOCTYPE declaration after the code that
conditionally redirects to the login page.

I'm wondering if you put the DOCTYPE at the top because you've read that
"the DOCTYPE has to be the first thing on the page". It has to be the
first thing (except white space) on the page that the *client* sees. To
the server, it's just text.
 
B

Bruce A. Julseth

Harlan Messinger said:
Correct. You're starting to serve the page and then suddenly changing your
mind in midstream. The proper order of execution is: Confirm that this is
the page to be served, and *then* serve it.

More details: The server has to send the HTTP headers before it sends the
body of the response, so the instant you send any characters at all to the
client, the server has to precede it with the headers. Trying to change
the headers after they've already been sent is an error condition.

The solution is to put the DOCTYPE declaration after the code that
conditionally redirects to the login page.

I'm wondering if you put the DOCTYPE at the top because you've read that
"the DOCTYPE has to be the first thing on the page". It has to be the
first thing (except white space) on the page that the *client* sees. To
the server, it's just text.

I "Thought" I had tested the case where I put the DOCTYPE after my PHP code
BUT apparently I didn't do an adequate job. Your suggestion off moving the
DOCTYPE after my php code seems to working, as expected...

Bruce
 
C

cwdjrxyz

I "Thought" I had tested the case where I put the DOCTYPE after my PHP code
BUT apparently I didn't do an adequate job. Your suggestion off moving the
DOCTYPE after my php code seems to working, as expected...

In your case, you only have one possible Doctype after the header
exchange code in php, so you may equally well write the Doctype within
the php section at the top of the page or just after the php section.
In the code I showed you, the header exchange can result in one of two
different Doctypes, and thus you need to write the Doctype in the php
section using conditional statements. In fact you can write nearly the
entire html page using php. Many times this will just create more work
for you because of all of the extra quotes required for the html code
to be written with php. However there are sometimes advantages. In
xhtml 1.1 served correctly as application/xhtml+xml, a JavaScript
document.write is not allowed because it could introduce an xml error
when the page is parsed as xml by the browser. This often will result
in only an error code and not a view of the page. However, if you feel
the need to use a JavaScript document.write on the html portion of the
page, you often can solve the problem by inserting a php section and
doing about the same thing in php. Then the writing will be done on
the server resulting in some html code that will be downloaded to the
browser which can parse it as xml and determine that you are not
attempting to slip it something forbidden in xml, such as something
that is not closed.
 
J

Jonathan N. Little

Bruce said:
I have a PHP page that fails when I have a <!DOCTYPE but works without it.

Right after the <!DOCTYPE is some PHP code where I call a PHP function that
tests for the user being logged on. If the user is not logged on, I call
header("Location: Login.php"). I'm getting a header already sent error
message if I have the <!DOCTYPE. If the <!DOCTYPE is missing, the login.php
page is loaded.

Is there a way to circumvent this problem without removing the <!DOCTYPE?

Yes put the PHP *before* the doctype. Even whitespace sent before the
header() command will cause an error unless you use output buffering.
Typical construction:

<?php
$redirect='http://www.example.com/someWhereElse.php';

if( some condition to require redirect ) {
header("Location: $redirect");
}
// else continue with this page...
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
....
 
H

Harlan Messinger

cwdjrxyz said:
In your case, you only have one possible Doctype after the header
exchange code in php, so you may equally well write the Doctype within
the php section at the top of the page or just after the php section.

Correct. The DOCTYPE doesn't have to appear after PHP. It *can* be the
first line of a PHP page that doesn't alter headers. It just can't be
written before any PHP code that alters headers.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,170
Latest member
Andrew1609
Top