18.16. Modifying a File in Place Without a Temporary File

Problem

You want to change a file without using a temporary file to hold the changes.

Solution

Read the file into memory, make the changes, and rewrite the file. Open the file with mode r+ (rb+, if necessary, on Windows) and adjust its length with ftruncate( ) after writing out changes:

// open the file for reading and writing 
$fh = fopen('pickles.txt','r+')         or die($php_errormsg);

// read the entire file into $s
$s = fread($fh,filesize('pickles.txt')) or die($php_errormsg);

// ... modify $s ...

// seek back to the beginning of the file and write the new $s
rewind($fh);
if (-1 == fwrite($fh,$s))                { die($php_errormsg); }

// adjust the file's length to just what's been written
ftruncate($fh,ftell($fh))               or die($php_errormsg);

// close the file
fclose($fh)                             or die($php_errormsg);

Discussion

The following code turns text emphasized with asterisks or slashes into text with HTML <b> or <i> tags:

$fh = fopen('message.txt','r+')         or die($php_errormsg);

// read the entire file into $s
$s = fread($fh,filesize('message.txt')) or die($php_errormsg);

// convert *word* to <b>word</b>
$s = preg_replace('@\*(.*?)\*@i','<b>$1</b>',$s);
// convert /word/ to <i>word</i>
$s = preg_replace('@/(.*?)/@i','<i>$1</i>',$s);

rewind($fh);
if (-1 == fwrite($fh,$s))                { die($php_errormsg); }
ftruncate($fh,ftell($fh))               or die($php_errormsg);
fclose($fh)                             or die($php_errormsg);

Because adding HTML tags makes the file grow, the entire file has to be read into memory ...

Get PHP Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.