How do I prepend file to beginning? - php

In PHP if you write to a file it will write end of that existing file.
How do we prepend a file to write in the beginning of that file?
I have tried rewind($handle) function but seems overwriting if current content is larger than existing.
Any Ideas?

$prepend = 'prepend me please';
$file = '/path/to/file';
$fileContents = file_get_contents($file);
file_put_contents($file, $prepend . $fileContents);

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++;
}
?>

$filename = "log.txt";
$file_to_read = #fopen($filename, "r");
$old_text = #fread($file_to_read, 1024); // max 1024
#fclose(file_to_read);
$file_to_write = fopen($filename, "w");
fwrite($file_to_write, "new text".$old_text);

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.

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.

$file = fopen('filepath.txt', 'r+') or die('Error');
$txt = "/n".$string;
fwrite($file, $txt);
fclose($file);
This will add a blank line in the text file, so next time you write to it you replace the blank line. with a blank line and your string.
This is the only and best trick.

Related

Create new txt files from each line of a txt file

I have a various txt files like ex: dictionary , each new line is term and then description. pipe delimited.
I have wrote simple script that actually reads each line and then creates (fwrite) new txt file named after term and description as a text of that file.
It works but I'm wondering if there is a better approach, one that takes special characters into account, buffer perhaps, Not sure where to start.
$file = fopen("test.txt", "r") or exit("Unable to open file!");
// Output a line of the file until the end is reached
while(!feof($file))
{
$line = fgets($file);
// making all lowercase - optional
$line = strtolower($line);
// take the first value before delimiter
$var = substr( $line, 0, strpos( $line, '|' ) );
// remove some characters - optional ( depends on a file structure and contents )
$var = str_replace("-", "", $var);
// what txt should be written into a each new file
$txt = str_replace("|", "", $line);
// name the file
$myfile = fopen("$var.txt", "w") or die("Unable to open file!");
// write
fwrite($myfile, $txt);
//close each
fclose($myfile);
}
//close
fclose($file);
UPDATE
$file = fopen("test.txt", "r") or exit("Unable to open file!");
// Output a line of the file until the end is reached
while(!feof($file))
{
$line = fgets($file);
// #sorak fix
$line = fgets($file);
$name = preg_replace('/[^0-9a-zA-Z]/', '',
explode('|', $line)[0]);
// making it lowercase - optional for each
$line = strtolower($line);
$name = strtolower($name);
// what txt should be written into a each new file
$txt = str_replace("|", " ", $line);
// name the file
$myfile = fopen("$name.txt", "w") or die("Unable to open file!");
// write
fwrite($myfile, $txt);
// action echo
echo "$myfile - $name - $txt </br>";
//close each
fclose($myfile);
}
//close
fclose($file);
Since last update contained some duplicate code lines/bugs that caused skipping every other line :) I'm posting new fixed and bit upgraded version.
// this utility is for creating multiple names.txt files from separate lines in original.txt file
// format for original file is: is name|text
// increase memory limit to 32M
ini_set('memory_limit','32M');
// increase 1440 seconds = 24 minutes
ini_set('max_execution_time', 1440);
$file = fopen("original.txt", "r");
if ($file) {
while (($line = fgets($file)) !== false) {
// #sorak fix
//$line = fgets($file);
$name = preg_replace('/[^0-9a-zA-Z]/', '',
explode('|', $line)[0]);
// making it lowercase - optional for each
$line = strtolower($line);
$name = strtolower($name);
$filename = $name . ".txt";
// what text should be written into a each new file
// change pipe separator if needed
$txt = str_replace("|", " ", $line);
// set values
$myfile = fopen($filename, "a") or die("Unable to open file!");
$dir = "/example.com/could_be_dynamic_folder_name";
// write
fwrite($myfile, $txt);
// chmod($dir,0777); optional if creation of dir is from GET/other value and not in the same parent
// action echo
echo "$myfile </br>";
echo "$dir/$filename </br>";
echo "$txt </br></br>";
// chmod
chmod($dir,0777);
chmod("$dir/$filename",0666); // remember to set this script to 0666
}
fclose($file);
} else {
// error echo
echo "something went wrong, error";
}
Works like a charm now. Case closed.
$line = fgets($file);
$name = preg_replace('/[^0-9a-zA-Z]/', '',
explode('|', $line)[0]);
Explode makes splitting up the string easier, and with the [0] we grab the first piece. That preg_replace instruction just removes all characters that aren't letters or numbers.

How to insert string before last line?

I saw using fseek to insert string before last line this question, but this isn't solving my problem. I not use "?>" tag. Php version PHP 5.4
example line1
example line2
//i need insert here
lastline $eg};
My code is working but this is adding empty lines after all lines :
$filename = 'example.php';
$arr = file($filename);
if ($arr === false) {
die('Error' . $filename);
}
array_pop($arr);
file_put_contents($filename, implode(PHP_EOL, $arr));
/// I'm deleting last line here
$person = "my text here\n";
file_put_contents($filename, $person, FILE_APPEND);
$person = "andherelastline";
file_put_contents($filename, $person, FILE_APPEND);
//and then add again here
$file = "tmp/saf.txt";
$fc = fopen($file, "r");
while (!feof($fc)) {
$buffer = fgets($fc, 4096);
$lines[] = $buffer;
}
fclose($fc);
//open same file and use "w" to clear file
$f = fopen($file, "w") or die("couldn't open $file");
$lineCount = count($lines);
//loop through array writing the lines until the secondlast
for ($i = 0; $i < $lineCount- 1; $i++) {
fwrite($f, $lines[$i]);
}
fwrite($f, 'Your insert string here'.PHP_EOL);
//write the last line
fwrite($f, $lines[$lineCount-1]);
fclose($f);

Splitting a text file in half using PHP?

I want to take one text file, split it in half, and put one half in one file, then the remaining half in the next. How would one accomplish this?
an example would be: split.php?n=file.txt
$file = $_GET['n'];
$i = 1;
$fp = fopen("./server/php/files/".$file,'a+');
$fs = filesize("./server/php/files/".$file);
$lengthhalf = $fs / 2;
while(! feof($fp)) {
$contents = fread($fp,$lengthhalf);
file_put_contents('./server/php/files/[2]'.$file,$contents);
$i++;
}
This does the work, without reading the whole file (or half of it) at once in memory:
function split_in_halves($file, $half1, $half2) {
$size = filesize($file);
$fd = fopen($file, 'rb');
stream_copy_to_stream($fd, fopen($half1, 'wb'), $size/2);
stream_copy_to_stream($fd, fopen($half2, 'wb'));
}
split_in_halves('foo', '[1]foo', '[2]foo');

Lock the file while reading and writing

I have a file which stores some value. Users can add stuff to that file and the counter in that file is updated. But if two users open the file, they'll get the same counter ($arr['counter']). What should I do? Maybe can I lock the file for one user and release the lock after he updates the counter and add some stuff back to the file? Or PHP already locks the file once is opened and I don't need to worry? Here's my current code:
$handle = fopen($file, 'r');
$contents = fread($handle, filesize($file));
fclose($handle);
$arr = json_decode($contents);
//Add stuff here to $arr and update counter $arr['counter']++
$handle = fopen($file, 'w');
fwrite($handle, json_encode($arr));
fclose($handle);
PHP has the flock function which will lock the file before writing to it, example,
$handle = fopen($file, 'r');
$contents = fread($handle, filesize($file));
fclose($handle);
$arr = json_decode($contents);
//Add stuff here to $arr and update counter $arr['counter']++
$handle = fopen($file, 'w');
if(flock($handle, LOCK_EX))
{
fwrite($handle, json_encode($arr));
flock($handle, LOCK_UN);
}
else
{
// couldn't lock the file
}
fclose($handle);

read and write file with newline php

I have a php file with the following info
One
Two
Three
Now i want to split them into an array, so i used:
$filehandle = fopen($filename, 'rb');
$line_of_text = fgets($filehandle);
$array = explode("\n", $line_of_text);
But it is not working.
They are written in the file like this:
$filehandle = fopen($textfile, 'a');
fputs($filehandle, $line . "\r\n");
fclose($filehandle);
So how do i read them into an array?.
Thanks.
I think you are looking for file(). However, it should be noted that this will leave all your array elements with a trailing CRLF sequence on them.
Alternatively (all these will strip the trailing CRLF):
$array = explode("\r\n", file_get_contents($filename));
...or...
$fp = fopen($filename, 'r');
$filecontents = fread($fp, filesize($filename));
$array = explode("\r\n", $filecontents);
...or...
$fp = fopen($filename, 'r');
$array = array();
while (($line = fgets($fp)) !== FALSE) $array[] = trim($line);
You should use the file function
file — Reads entire file into an array
$your_array = file ("filename", FILE_IGNORE_NEW_LINES); // add the flag to strip newlines

Categories