search, insert & write on a new line of text file using PHP - php

i have problems in searching a string in a file, insert a new line after the searched string and write on the new added line. currently i am using below code from examples and discussion i found:-
$target = '<18>';
$put = 'Enter';
$file = 'line.txt';
$filename = $file;
$string_i_am_looking_for = $target;
$lines = file( $filename , FILE_IGNORE_NEW_LINES );
$lines[$string_i_am_looking_for] = $put;
file_put_contents( $filename , implode( "\n", $lines ) );
text file:-
<17>
<18>
<19>
<20>
at first action, i was able to put the $put in the text file.
<17>
<18>Enter
<19>
<20>
but, when i change the $target = "<20>", i was not able to write after the new $target. It will appear next to the first line. And when i reload the page more and more, it will keep on writing on the first line. Below is the result:-
<17>EnterEnterEnterEnterEnter
<18>Enter
<19>
<20>

Word Enter is not new line in any manner. You have to replace it with \r\n or \n (depends on file new line character).
$target = '<18>';
$put = "\r\n";
$file = 'line.txt';

Try This
$target = '<20>';
$put = 'Enter';
$file = 'line.txt';
$filename = $file;
$string_i_am_looking_for = $target;
$lines = file( $filename , FILE_IGNORE_NEW_LINES );
$key = array_search($string_i_am_looking_for,$lines);
$toSearch = $target.$put;
if(!in_array($toSearch,$lines)) {
$lines[$key] = $target.$put;
}
file_put_contents( $filename , implode( "\n", $lines) );

Related

I want to delete a line in txt file

I use PHP to read a txt file,I read the first line, it is ok.
but when I want to delete the first line.
it fails.....
I can do this code in localhost,but when I boot in server
it fail.....I dont know why...
this is my code:
<?php
$handle = fopen('newfile.txt', "r");
$contents = '';
if ($handle) {
while (!feof($handle)) {
$contents = fgets($handle, 10);
echo $contents;
$filename = 'newfile.txt';
$content = file_get_contents('newfile.txt');
$content = str_replace($contents, '', $content);
file_put_contents('newfile.txt', $content);
exit;
}
fclose($handle);
}
?>
An alternative to the complicated code above ( which I did not check btw ) might be
$file='newfile.txt';
$lines=file( $file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
array_shift( $lines );
file_put_contents( $file, implode( PHP_EOL, $lines ) );
If it is important to display the line that is being removed then:
$file='newfile.txt';
$lines=file( $file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
$sentence = array_shift( $lines );
echo $sentence;
file_put_contents( $file, implode( PHP_EOL, $lines ) );

Delete a specific line in a TXT file

I have a .txt file with millions of lines of text
The code below Delete a specific line (.com domains) in a .txt file. But large files can not do :(
<?php
$fname = "test.txt";
$lines = file($fname);
foreach($lines as $line) if(!strstr($line, ".com")) $out .= $line;
$f = fopen($fname, "w");
fwrite($f, $out);
fclose($f);
?>
I want to remove certain lines and put them in another file
For example, the list of domain names of sites. cut the .com domain and paste it in another file...
Here's an approach using http://php.net/manual/en/class.splfileobject.php and working with a temporary file.
$fileName = 'whatever.txt';
$linesToDelete = array( 3, 5 );
// Working File
$file = new SplFileObject( $fileName, 'a+' );
$file->flock( LOCK_EX );
// Temp File
$temp = new SplTempFileObject( 0 );
$temp->flock( LOCK_EX );
// Wite the temp file without the lines
foreach( $file as $key => $line )
{
if( in_array( $key + 1, $linesToDelete ) === false )
{
$temp->fwrite( $line );
}
}
// Write Back to the main file
$file->ftruncate(0);
foreach( $temp as $line )
{
$file->fwrite( $line );
}
$file->flock( LOCK_UN );
$temp->flock( LOCK_UN );
This may be slow though, but a 40 meg file with 140000 lines takes 2.3 seconds on my windows xampp setup. This could be sped up by writing to a temp file and doing a file move, but I didn't want to step on file permissions in your environment.
Edit: Solution using Rename/Move instead of second write
$fileName = __DIR__ . DIRECTORY_SEPARATOR . 'whatever.txt';
$linesToDelete = array( 3, 5 );
// Working File
$file = new SplFileObject( $fileName, 'a+' );
$file->flock( LOCK_EX );
// Temp File
$tempFileName = tempnam( sys_get_temp_dir(), rand() );
$temp = new SplFileObject( $tempFileName,'w+');
$temp->flock( LOCK_EX );
// Write the temp file without the lines
foreach( $file as $key => $line )
{
if( in_array( $key + 1, $linesToDelete ) === false )
{
$temp->fwrite( $line );
}
}
// File Rename
$file->flock( LOCK_UN );
$temp->flock( LOCK_UN );
unset( $file, $temp ); // Kill the SPL objects relasing further locks
unlink( $fileName );
rename( $tempFileName, $fileName );
It could be because of the large size of the file that its taking too much of space.
When you do file('test.txt'), it reads the entire file into an array.
Instead, you can try using Generators.
GeneratorsExample.php
<?php
class GeneratorsExample {
function file_lines($filename) {
$file = fopen($filename, 'r');
while (($line = fgets($file)) !== false) {
yield $line;
}
fclose($file);
}
function copyFile($srcFile, $destFile) {
foreach ($this->file_lines($srcFile) as $line) {
if(!strstr($line, ".com")) {
$f = fopen($destFile, "a");
fwrite($f, $line);
fclose($f);
}
}
}
}
callingFile.php
<?php
include('GeneratorsExample.php');
$ob = new GeneratorsExample();
$ob->copyFile('file1.txt', 'file2.txt')
While you could use tens of lines of PHP code, one line of shell code will do.
$ grep Bar.com stuff.txt > stuff2.txt
or as PHP
system ("grep Bar.com stuff.txt > stuff2.txt");

How to save unique filename to directory with FPDF?

I would like to save each newly generated PDF file with a unique filename to the "receipts" directory after generating the PDF using the FPDF library... As it is now, the PDF is overwritten each time. Can I append a time-stamp to the PDF filename? Example --->( /receipt_month-day-year-hour-seconds.pdf )
Absolute uniqueness desired, but not super critical.
$pdf->Output('receipts/receipt.pdf', 'F');
An easy (but not foolproof) way of ensuring a filename is unique would be to add a microtime timestamp to the filename. Microtime includes thousanths of a second, so would probably work unless your site has a lot of traffic:
$pdf->Output('receipts/receipt-' . microtime(true) . '.pdf', 'F');
If you want your timestamp to be like receipt_12-26-2017.pdf, then:
$pdf->Output('receipts/receipt_' . date("m-d-Y") . '.pdf', 'F');
If you really want to ensure your filenames are unique per directory, you could do something like this:
<?php
function get_filenames($source_dir, $include_path = FALSE, $_recursion = FALSE)
{
static $_filedata = array();
if ($fp = #opendir($source_dir))
{
// reset the array and make sure $source_dir has a trailing slash on the initial call
if ($_recursion === FALSE)
{
$_filedata = array();
$source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
}
while (FALSE !== ($file = readdir($fp)))
{
if (#is_dir($source_dir.$file) && strncmp($file, '.', 1) !== 0)
{
get_filenames($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE);
}
elseif (strncmp($file, '.', 1) !== 0)
{
$_filedata[] = ($include_path == TRUE) ? $source_dir.$file : $file;
}
}
return $_filedata;
}
else
{
return FALSE;
}
}
function force_unique_filename( $dir_list, $file_name, $x = 2 )
{
/**
* Dir list may be an array of file names, or in the case of
* cURL, the list may be supplied as a string. If an array, we
* just convert the array to a string so it is checked as a string.
*/
if( is_array( $dir_list ) )
{
$dir_list = implode( ' ', $dir_list );
}
while( strpos( $dir_list, $file_name ) !== FALSE )
{
// Use pathinfo to break apart the filename
$info = pathinfo( $file_name );
// Get the file extension of the file
$ext = '.' . $info['extension'];
// Get the name of the file without extension
$file_name = basename( $file_name, $ext );
// Remove the filename suffix before adding a new one
$pattern = '/\(\d+\)/';
$replacement = '';
$file_name = preg_replace( $pattern, $replacement, $file_name );
// Add new filename suffix
$file_name .= '(' . (string) $x . ')' . $ext;
// Increment the number we are using in a filename suffix "($x)"
$x++;
}
return $file_name;
}
// -----------------------------------------------------------------------
// This directory should be an absolute path...
$source_dir = './receipts';
// The desired filename
$filename = 'receipt_' . date("m-d-Y") . '.pdf';
// Get all of the filenames in this directory
$filenames = get_filenames( $source_dir, FALSE, FALSE );
// Get the unique filename
$unique_filename = force_unique_filename( $filenames, $filename );
$pdf->Output('receipts/' . $unique_filename, 'F');

PHP script for generating HTML files stopping early

I am extremely new to PHP and am having some issues with my first script. I am attempting to use this PHP script to generate HTML files for a series of products that only have minor changes between them. I have a .csv spreadsheet with all of the information, an html template and the PHP script I will post below.
Here is the problem I am encountering. When I check the folder where the script is supposed to put my finished HTML files after running the script, there are only 4 files instead of the 36 I want it to make. There are 36 rows of information in the .csv and I can't figure out how to get the script to generate all of the HTML files it should.
Here is my script:
<?php
$base_template = file_get_contents('template.html');
$file_to_read = 'spreadsheet.csv';
ini_set("auto_detect_line_endings", 1);
$filename = '';
if (($handle = fopen($file_to_read, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$Column1 = $data[0];
$Column2 = $data[1];
$Column3 = $data[2];
$Column4 = $data[3];
$Column5 = $data[4];
$Column6 = $data[5];
$Column7 = $data[6];
$filename = preg_replace('/[\s\W]+/','',$Column1);
$filename = substr($filename, 0, 10);
$template = str_replace('{Column1}', $Column1, $base_template);
$template = str_replace('{Column2}', $Column2, $template);
$template = str_replace('{Column3}', $Column3, $template);
$template = str_replace('{Column4}', $Column4, $template);
$template = str_replace('{Column5}', $Column5, $template);
$template = str_replace('{Column6}', $Column6, $template);
$template = str_replace('{Column7}', $Column7, $template);
$file = fopen('generated_html/'.$filename.'.html',"w+");
fwrite($file, $template);
fclose($file);
}
fclose($handle);
}
?>
How can I get the script to generate all of the files I need instead of stopping early?

PHP reading file

I am trying to read a formatted file
name (read this into variable)
10 10 (read into separate variables)
the rest into array
line
line
line
line
to clarify this is for an upload script which i already finished when a user uploads a file formatted like that it reads it in the way described above
$fname = 'test.txt';
$lines = file("$fname", "r");
while($lines as $currenline){
I am trying to put the name, width, height into variables
then the rest into the array
}
will this help
Not 100% sure what you're asking for but maybe this can get you started:
$fname = 'test.txt';
$lines = file("$fname", "r");
foreach($lines as $line) {
$parts = explode(' ', $line);
$name = $parts[0];
$width = $parts[1];
$height = $parts[2];
// Do whatever you want with the line data here
}
It assumes all input lines are well formatted of course.
$fh = fopen( $fname, 'r' );
$name = fgets( $fh );
$dimensions = split( ' ', fgets($fh) );
$length = $dimensions[0];
$width = $dimensions[1];
$lines = array();
while ( $line = fgets( $fh ) $lines[] = $line;
I never tested this, but it should work if your files are constant. The while loop maybe off, and need some re-working if it doesn't work, keeping in mind that fgets returns false if an error occurs or is unable to read the file.
$lines already contains almost what you need, just pull out the relevant pieces.
$fname = 'test.txt';
$lines = file("$fname", "r");
$name = $lines[0];
list($height, $width) = explode(' ', $lines[1]);
$lines = array_slice($lines, 2);
Note this doesn't have any error checking, so you might want to add some.
As suggested in the comments you can also do this using array_shift:
$fname = 'test.txt';
$lines = file("$fname", "r");
$name = array_shift($lines);
list($height, $width) = explode(' ', array_shift($lines));
// $lines now contains only the rest of the lines in the file.

Categories