tags:

views:

95

answers:

4

In PHP if you write to a file it will write end of that existing file. but how do we prepend a file to write in the beginning of that file??

I have tried rewind($handle) function but seems over writing if current content is larger than existing...

Any Ideas??

+2  A: 
$prepend = 'prepend me please';

$file = '/path/to/file';

$fileContents = file_get_contents($file);

file_put_contents($file, $prepend . $fileContents);
alex
Alex there is a correction $fileContents = file_get_contents($file);
mathew
@matthew Whoops, thanks for picking that up.
alex
Alex one more question..if this is a large file then read/write may take more time right??
mathew
If the file is huge you could always use streams (ie. fread and fwrite) and a temporary file.
GWW
@matthew It may. The [docs](http://www.php.net/manual/en/function.file-put-contents.php) say calling `file_put_contents()` is identical to using `fopen()` and similar. If performance becomes a problem, you can always look into Deceze's suggestion (in the comments to your question).
alex
Oh noes I've been unaccepted! :P
alex
A: 

When using fopen() you can set the mode to set the pointer (ie. the begginng or end.

$afile = fopen("file.txt", "r+");

'r' Open for reading only; place the file pointer at the beginning of the file.

'r+' Open for reading and writing; place the file pointer at the beginning of the file.

Zane Edward Dockery
still it will overwrite beginning line
mathew
+2  A: 

The file_get_contents solution is inefficient for large files. This solution may take longer, depending on the amount of data that needs to be prepended (more is actually better), but it won't eat up memory.

<?php

$cache_new = "Prepend this"; // this gets prepended
$file = "file.dat"; // the file to which $cache_new gets prepended

$handle = fopen($file, "r+");
$len = strlen($cache_new);
$final_len = filesize($file) + $len;
$cache_old = fread($handle, $len);
rewind($handle);
$i = 1;
while (ftell($handle) < $final_len) {
  fwrite($handle, $cache_new);
  $cache_new = $cache_old;
  $cache_old = fread($handle, $len);
  fseek($handle, $i * $len);
  $i++;
}
?>
Fraxtil
`file_get_contents()` [docs](http://php.net/manual/en/function.file-get-contents.php) does say this: "...is the preferred way to read the contents of a file into a string. It will use memory mapping techniques if supported by your OS to enhance performance."
alex
@alex It still means it'll read the whole thing into memory all at once. Fraxtil's method is using very little memory, but a lot of steps. It depends on the circumstances which one is more efficient...
deceze
@deceze Thanks for the info.
alex
Great thanks!! it works I was little bit worried about file_get_contents
mathew
A: 

Another (rough) suggestion:

$tempFile = tempnam('/tmp/dir');
$fhandle = fopen($tempFile, 'w');
fwrite($fhandle, 'string to prepend');

$oldFhandle = fopen('/path/to/file', 'r');
while (($buffer = fread($oldFhandle, 10000)) !== false) {
    fwrite($fhandle, $buffer);
}

fclose($fhandle);
fclose($oldFhandle);

rename($tempFile, '/path/to/file');

This has the drawback of using a temporary file, but is otherwise pretty efficient.

deceze