By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,141 Members | 1,266 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,141 IT Pros & Developers. It's quick & easy.

Writing data to HTML file BEFORE the </body> tag.

P: n/a
Hello:
I have the following code in a PHP file. An HTML form passes user
comment data to the PHP, which then appends the user comments to the
end of the HTML file on which the form is located. This PHP code
works: the HTML file with added comments displays correctly in my
browser. However, appending text to the very end of the HTML file
creates what is, strictly speaking, invalid code.

I am looking for a way to tell PHP to write data to the file JUST
BEFORE the </bodytag. I have read about fseek(), but don't know for
sure if the number of characters (or HTML tags) after my "user
comments" section is going to remain constant.

Being extremely new to PHP, all I know is that I need to move the file
pointer backwards from the end of the HTML file until just before </
body>. I would appreciate any help in doing this.

<HTML>
<HEAD></HEAD>
<BODY>
<?
$name = $_POST['name'];
$website = $_POST['website'];
$message = $_POST['message'];
$timestamp = $_POST['timestamp'];
$fp = fopen(basename($_SERVER[HTTP_REFERER]), 'a');
if (!$fp)
{
echo "There was an error. Please try again later.";
exit;
}
else
{
$outputstring = "<hr>" .$timestamp. "<br>" .$name. "<br>" .$message.
";
fwrite($fp, $outputstring, strlen($outputstring));
fclose($fp);
echo "<BR>Comment posted successfully.<BR>Click <a href='next'>here</
Ato continue.";
}
?>
</BODY>
</HTML>
Aug 1 '08 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Shawn wrote:
[...] which then appends the user comments to the end of the HTML file on
which the form is located.
Learn to use a database. I mean it: it'll save you sanity in the long run.

The PHP manual has some examples on SQLite. Even if you're new to PHP, I
strongly suggest you read them.
Cheers,
--
----------------------------------
Iván Sánchez Ortega -ivan-algarroba-sanchezortega-punto-es-

Cambio mujer de 40 por dos de 20.
Aug 1 '08 #2

P: n/a
..oO(Shawn)
>I have the following code in a PHP file. An HTML form passes user
comment data to the PHP, which then appends the user comments to the
end of the HTML file on which the form is located. This PHP code
works: the HTML file with added comments displays correctly in my
browser. However, appending text to the very end of the HTML file
creates what is, strictly speaking, invalid code.

I am looking for a way to tell PHP to write data to the file JUST
BEFORE the </bodytag. I have read about fseek(), but don't know for
sure if the number of characters (or HTML tags) after my "user
comments" section is going to remain constant.
You want to insert data into the middle of a file. This means you have
to recreate the entire file. Usually you would read it into memory,
write all of its data to a new empty file until you reach the insert
position, then write the new data, then the rest of the original file.
After that you replace the old file with the new one.

You could do this with file() and looping through the resulting array
until you reach the "</body>" line. Another way would be to load the
entire file with file_get_contents() into a string. Then use string
functions to prepend "</body>" with your new content, finally use
file_put_contents() to write it all back to disk.

But there are a lot of other problems:
><HTML>
<HEAD></HEAD>
This code is invalid anyway. There's no document type declaration and
the 'title' element is missing.
><BODY>
<?
Don't use short open tags. They are unreliable and will be turned off by
default in the coming PHP 6. Use the correct <?php instead.
>$name = $_POST['name'];
$website = $_POST['website'];
$message = $_POST['message'];
$timestamp = $_POST['timestamp'];
No error checking that these $_POST values really exist?
>$fp = fopen(basename($_SERVER[HTTP_REFERER]), 'a');
Holy sh*t... The HTTP referrer is not only totally unreliable, but also
easy to fake. This opens a _huge_ security hole here - an attacker could
easily manipulate _any_ file your web server is allowed to write to and
inject arbitrary code!

Have a look at the various predefined values in $_SERVER instead, the
elements 'SCRIPT_NAME' or 'PHP_SELF' could be of interest.
>if (!$fp)
{
echo "There was an error. Please try again later.";
exit;
The exit call here will prevent the script from returning a complete
HTML document to the browser. In case of an error you should just stop
or skip the further file processing, but not kill the entire script.
>}
else
{
$outputstring = "<hr>" .$timestamp. "<br>" .$name. "<br>" .$message.
";
You should also have a look at htmlspecialchars(). Your code allows a
user to insert arbitrary markup, which means that your page can be
abused for cross-site scripting attacks (XSS). Even worse: it also
allows easy code injection - the most severe of all security problems.

My suggestion: Drop the idea of a self-modifying script - this calls for
a lot of _serious_ trouble! Instead write the posted messages to another
file (plain text or CSV for example) or to a database. Then use a little
load function to show these messages on your page.

Micha
Aug 1 '08 #3

P: n/a
Michael Fesser wrote:

[...]
But there are a lot of other problems:
You also forgot about race conditions.

I did some hack some years ago, involving a script appending data to a text
file, and I can assure you that, given enough time and load, things will
invariably f**k up.

That's why atomic operations on a database are so cool: they save you from
lots of potential problems when it comes to concurrent programming
languages.
Cheers,
--
----------------------------------
Iván Sánchez Ortega -ivan-algarroba-sanchezortega-punto-es-

Now listening to: Kb - Destination Lounge: New York City (2007) - [10] El
Musica (main mix) (6:52) (0.000000%)
Aug 1 '08 #4

P: n/a
..oO(Ivn Snchez Ortega)
>Michael Fesser wrote:

[...]
>But there are a lot of other problems:

You also forgot about race conditions.
Indeed.

<excuse mode="blockbuster">
The OP will already be held responsible if attackers take over his
server and abuse it for spreading a virus, which will infect the entire
network, overload every connected system and finally blow up the whole
planet. So I just didn't want to scare him too much. ;-)
</excuse>
>I did some hack some years ago, involving a script appending data to a text
file, and I can assure you that, given enough time and load, things will
invariably f**k up.
You can prevent this with file locking. Might cause other problems,
though. A system which is explicitly designed for parallel accesses
like a DBMS for example is definitely the better choice in such cases.
>That's why atomic operations on a database are so cool: they save you from
lots of potential problems when it comes to concurrent programming
languages.
Yep.

Micha
Aug 1 '08 #5

P: n/a
Thanks, guys, for all of the feedback. In the revised code (see
below), I have done the following:

*Added a <!DOCTYPEassignment tag.
*Replaced the PHP short open tag w/ the longer one.
*Added if/else statements for basic form validation (additional
validation will be done from the referring form using javascript).
*Used trim() and htmlspecialchars() to eliminate blank space and
prevent website exploitation via cross-site scripting attacks.
*Removed exit calls that would cause termination of script before
required HTML end tags.

Yes, I am aware that I have used deprecated elements in the <hrtag.

Now let's say that I, as suggested, abandon the idea of using fwrite()
to append the user comments to the end of the referring HTML document.
Let's say that I want to put the comments in a database, instead. How
would that be coded? What steps would I need to take?

It may help to know that my host server allows me several MySQL
databases, although I don't know SQL. It may also help to know that I
will eventually have many pages that need to store comments. Is one
database sufficient for this?

Thanks, again.

-------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://
www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>

<BODY>
<?php
$name = htmlspecialchars(trim($_POST['name']), ENT_QUOTES);
$website = trim($_POST['website']);
$message = htmlspecialchars(trim($_POST['message']), ENT_QUOTES);
$timestamp = htmlspecialchars(trim($_POST['timestamp']), ENT_QUOTES);

// Rem: empty() can only be used on a variable, not on the results of
a function.
if (empty($message)) {
echo "<p>Error: a blank comment cannot be submitted.</p>";
}
else {
if (empty($name)) {
echo "<p>Error: comments cannot be submitted
without a name.</p>";
}

else {
$fp = fopen(basename($_SERVER[HTTP_REFERER]), 'a');
if (!$fp) {
echo "<p>There was an error. Please try again
later.</p>";
}
else {
$outputstring = "<div style='color: darkgray; text-align:
left'><hr noshade width='50%' align='left'><small>" .$timestamp.

"</small><br><B>Name:</b<a href='" .$website. "'>" .$name. "</
a><br><b>Comment:</b" .$message. "<br></div>";
fwrite($fp, $outputstring, strlen($outputstring));
fclose($fp);
echo "<p>Your comment was posted successfully.<br>Click <a
href='javascript:history.back()'>here</ato continue.</p>";
}
}
}
?>
</BODY>
</HTML>
Aug 1 '08 #6

P: n/a
Shawn wrote:
Thanks, guys, for all of the feedback. In the revised code (see
below), I have done the following:

*Added a <!DOCTYPEassignment tag.
*Replaced the PHP short open tag w/ the longer one.
*Added if/else statements for basic form validation (additional
validation will be done from the referring form using javascript).
*Used trim() and htmlspecialchars() to eliminate blank space and
prevent website exploitation via cross-site scripting attacks.
*Removed exit calls that would cause termination of script before
required HTML end tags.

Yes, I am aware that I have used deprecated elements in the <hrtag.

Now let's say that I, as suggested, abandon the idea of using fwrite()
to append the user comments to the end of the referring HTML document.
Let's say that I want to put the comments in a database, instead. How
would that be coded? What steps would I need to take?

It may help to know that my host server allows me several MySQL
databases, although I don't know SQL. It may also help to know that I
will eventually have many pages that need to store comments. Is one
database sufficient for this?

Thanks, again.

-------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://
www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>

<BODY>
<?php
$name = htmlspecialchars(trim($_POST['name']), ENT_QUOTES);
$website = trim($_POST['website']);
$message = htmlspecialchars(trim($_POST['message']), ENT_QUOTES);
$timestamp = htmlspecialchars(trim($_POST['timestamp']), ENT_QUOTES);

// Rem: empty() can only be used on a variable, not on the results of
a function.
if (empty($message)) {
echo "<p>Error: a blank comment cannot be submitted.</p>";
}
else {
if (empty($name)) {
echo "<p>Error: comments cannot be submitted
without a name.</p>";
}

else {
$fp = fopen(basename($_SERVER[HTTP_REFERER]), 'a');
if (!$fp) {
echo "<p>There was an error. Please try again
later.</p>";
}
else {
$outputstring = "<div style='color: darkgray; text-align:
left'><hr noshade width='50%' align='left'><small>" .$timestamp.

"</small><br><B>Name:</b<a href='" .$website. "'>" .$name. "</
a><br><b>Comment:</b" .$message. "<br></div>";
fwrite($fp, $outputstring, strlen($outputstring));
fclose($fp);
echo "<p>Your comment was posted successfully.<br>Click <a
href='javascript:history.back()'>here</ato continue.</p>";
}
}
}
?>
</BODY>
</HTML>
For MySQL questions, try comp.databases.mysql. You'll need to learn SQL
syntax (which isn't that hard for the easy stuff, but can be very
powerful). And even if you don't use it on this project, SQL is a very
good thing to know.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
js*******@attglobal.net
==================
Aug 1 '08 #7

This discussion thread is closed

Replies have been disabled for this discussion.