PDA

View Full Version : PHP: Insert text at beginning of file


Wyatt
2008-01-08, 21:20
I'm writing a quick and dirty liveblog plugin for my WordPress blog, and I'm a bit stuck at the moment.

Basically what I'm planning to do, rather than access the database every time I want to update the post (therefore making the process a little slower), I want to update a file on my server called liveblog.txt with the most recent updates at the top. I'll then use a PHP include to plug the file into my post and a little javascript to reload the page at a set interval (I'm thinking 30 seconds, but I might up that a bit).

So far, I've thought of two straightforward ways to do this:

1) Open the file and write to the start of it, then close it again. This seems like the obvious choice, but I can't figure out how to do that in PHP. The fopen() documentation (http://us.php.net/fopen) only talks about appending to the end or overwriting the file and writing from the beginning.

2) Open the file and load its contents into a variable. Then, append the entire variable onto the variable that stores the new entry. Finally, overwrite the file with the contents of the variable.

I know I can pull off #2 fairly easily, but I'd really rather go with #1 if it's at all possible. That involves a lot less processing at run-time, which leaves a lot less room for error.

Is there any way for me to write to the front of a file without overwriting anything? Is there a better option than either of these that I'm overlooking?

ast3r3x
2008-01-08, 22:25
I really don't think this is a better idea than having it connect to the database and write the stuff out, especially if your database is running on the same server.

On a related note for #2, if you have access to PHP 5, it doesn't get much simpler than this…

<?php
$filename = 'test.txt';
$somecontent = "some content\n";

$file = file_get_contents($filename);
file_put_contents($filename, $somecontent.$file);
?>

Brad
2008-01-08, 23:49
On a related note for #2, if you have access to PHP 5, it doesn't get much simpler than this…

<?php
$filename = 'test.txt';
$somecontent = "some content\n";

$file = file_get_contents($filename);
file_put_contents($filename, $somecontent.$file);
?>

Do be careful with the above approach, however, because it requires you to load the entire contents of the file in memory. Small files should work fine, but larger files may cause problems.

At to fcgriz's point #1, writing to anywhere but the end of a file is not currently possible with PHP, to the best of my knowledge. You could exec out to the system (usually a bad idea) or you could use two files, reading from one and writing to the other, and then swap them when you're finished the read/write loop. Or if you're just using small files, do what ast3r3x suggested.

That said, don't underestimate the power and speed of relational databases. They've been designed and optimized for decades to get queries and insertions down efficiently and safely. Rewriting a text file on the server will almost certainly be slower than calling out to the database for an insert or update.

Wyatt
2008-01-09, 07:10
I really don't think this is a better idea than having it connect to the database and write the stuff out, especially if your database is running on the same server.

On a related note for #2, if you have access to PHP 5, it doesn't get much simpler than this…
The database is on a separate server, and Word Press tends to be slow on my site to begin with.

My host also doesn't give me access to PHP 5. I really, really wish they would, but I'm stuck with PHP 4. (Luckily, they do give me MySQL 5.)

My concern with using a database isn't so much for the writing process (I would prefer to use a database for that), but rather for the visitors reading the liveblog. If I get anywhere near a meaningful amount of traffic (which I don't expect for Macworld, but I want to be prepared), I'm afraid the site will slow to a crawl when every user is querying the database server every 30-60 seconds. Like I mentioned earlier in this post, WP is pretty slow to begin with, and I'm fairly certain it's because of the database server. The site is pretty quick when I'm working with static pages, even with a lot of PHP, but it gets slow from time-to-time when using the database.

Yonzie
2008-01-09, 08:37
How about this (it's a bit complicated, but wth...):
Every time your site is accessed, PHP checks timestamp of the last DB entry and the timestamp of the file. If the file is out of date, it rebuilds it, otherwise it just includes it.
Or... Check the timestamp of the file and if it hasn't been updated this minute, recreate it. This means you only get DB traffic once per minute.

Brad
2008-01-09, 09:03
If I get anywhere near a meaningful amount of traffic (which I don't expect for Macworld, but I want to be prepared), I'm afraid the site will slow to a crawl when every user is querying the database server every 30-60 seconds.
Have you considered rolling in flat-file database query caching with something like ADODB? That will get you the benefits of true database storage with significantly reduced query time (if database access really is the bottleneck).

Also, have you done any benchmarking to verify that it actually is the database that's the bottleneck? A quick and dirty way to do that would be to find where your code is calling out to the DB and log the microtime() before and after it.

ghoti
2008-01-09, 09:36
There is no direct way to add to the beginning of a file, independently of language used - this simply isn't a function of any operating system I know. Any library or framework providing that feature will always have to read in the current content of the file and then write out the new stuff plus the old one.

One way to solve your problem would be to append to the end of the file when writing, and when including the file reading it into an array and then sending it to the user in reverse order. That would of course mean you would need a simple way to separate entries, but since you're liveblogging perhaps each line could be one entry.

Databases tend to be slow on shared hosting (because you share the same db with ten million other people), file access is much faster. Depending on your needs, a little handwritten pseudo-db would probably be the fastest and easiest solution.

Wyatt
2008-01-09, 09:39
Have you considered rolling in flat-file database query caching with something like ADODB? That will get you the benefits of true database storage with significantly reduced query time (if database access really is the bottleneck).
I'll have to look into that. I don't really know anything about it, though, and I'm afraid I won't have time to write something before the Macworld keynote. (I basically have Saturday and Monday afternoon to work on this.)

Also, have you done any benchmarking to verify that it actually is the database that's the bottleneck? A quick and dirty way to do that would be to find where your code is calling out to the DB and log the microtime() before and after it.
Now that's an excellent idea. I'll have to try that out tonight when I get home.

ast3r3x
2008-01-09, 12:04
If you are using wordpress, that is what will kill your site with a lot of traffic not making an extra database call. Wordpress doesn't handle traffic well, period.

If you are going to do something like this though, why not use php's sqllite? It's pretty damn easy if you know SQL.