How to open a file and remove the last line? - php

I am looking to open up a file, grab the last line in the file where the line = "?>", which is the closing tag for a php document. Than I am wanting to append data into it and add back in the "?>" to the very last line.
I've been trying a few approaches, but I'm not having any luck.
Here's what I got so far, as I am reading from a zip file. Though I know this is all wrong, just needing some help with this please...
// Open for reading is all we can do with zips and is all we need.
if (zip_entry_open($zipOpen, $zipFile, "r"))
{
$fstream = zip_entry_read($zipFile, zip_entry_filesize($zipFile));
// Strip out any php tags from here. A Bit weak, but we can improve this later.
$fstream = str_replace(array('?>', '<?php', '<?'), '', $fstream) . '?>';
$fp = fopen($curr_lang_file, 'r+');
while (!feof($fp))
{
$output = fgets($fp, 16384);
if (trim($output) == '?>')
break;
}
fclose($fp);
file_put_contents($curr_lang_file, $fstream, FILE_APPEND);
}
$curr_lang_file is a filepath string to the actual file that needs to have the fstream appended to it, but after we remove the last line that equals '?>'
Ok, I actually made a few changes, and it seems to work, BUT it now copies the data in there twice... arggg, so each line in the file is now in there 2 times :(
Ok, removed the fwrite, though now it is appending it at the bottom, just below the ?>
OMG, I just need everything up to the last line, isn't there a way to do this??? I don't need "?>"

A simple way with the file on the filesystem:
<?php
$path = "file.txt";
$content = file($path); // Parse file into an array by newline
$data = array_pop($content);
if (trim($data) == '?>') {
$content[] = 'echo "... again";';
$content[] = "\n$data";
file_put_contents($path, implode($content));
}
Which does..
$ cat file.txt
<?php
echo 'Hello world';
?>
$ php test.php
$ cat file.txt
<?php
echo 'Hello world';
echo "... again";
?>

It's copying each line twice because of your line that says:
#fwrite($fp, $output);
You're just reading the file to find the end tag, there's no need to write the line you've read as you read.

I would add a new <? YOUR CODE ?> after the last line...
Or if you have the new PHP code to add in $code this could be done with a regular expression
$output = preg_replace('\?>','?>'.$code,$output)

Related

PHP Replace all values in the third column in a csv file

I am trying to replace some hyperlinks in a csv file, like this one:
[https://assets.suredone.com/683987/media-pics/6164307j-gabriel-61643-proguard-steel-shock-absorber-for-select-chevrolet-gmc-models.jpg. Here is my code:][1]. Here is my code:
<?php
$in_file = 'gabriel-images-urls.csv';
$out_file = 'results.csv';
$fd = fopen($in_file, "r");
$new_array= array();
$toBoot= array();
while ($data = fgetcsv($fd)) {
echo '<pre>';
if (strpos($data[2],'media-pics') !== false) {
$data[2]=str_replace('media-pics','media-photos',$data[2]);
fputcsv($fd, $data);
// echo $output;
}
}
?>
The new link for example must look like this:[1]https://assets.suredone.com/683987/media-photos/6164307j-gabriel-61643-proguard-steel-shock-absorber-for-select-chevrolet-gmc-models.jpg. The goal is he "media-pics" substring to be replaced with "media-photos". At this point nothing happens in the file. I think this is because the file is open only for reading but I am not sure.
Can you not simply do a string replacement on the whole file rather than attempting to load and process each line of the file using fgetcsv?
<?php
$srcfile='gabriel-images-urls.csv';
$outfile='results.csv';
$csvdata=file_get_contents( $srcfile );
$moddata=str_replace('media-pics','media-photos',$csvdata);
file_put_contents( $outfile, $moddata );
?>

php getting lines of text from a text file based on a # delimiter at the beginning of each sentence

I have a text file
test.txt
and in the file it has lines that begin with '#'
example
#this is a test
#this is another test
this is not a test
When I run my php script I need it to only grab the lines with the '#' and then remove it so it doesn't show in the echo.
So the output would be....
this is a test
this is another test
I'm just learning php but this is what I have... It reads one line...
<?php
$f=fopen("alertmon_user.txt", "r");
// is this where I need to set the conditions?
echo fgets($f);
fclose($f);
?>
What can I add to this to make this work? Am I on the right track?
Read the file line by line and check if line starts with #.
$handle = fopen("alertmon_user.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
if(substr($line, 0, 1) === "#") {
//process line here
echo $line . "</br>"; // add </br> for new line
}
}
fclose($handle);
} else {
// error opening the file.
}
Update : To remove # from line.
If you want to remove # from line then use substr method.
for example.
$updatedLine = substr($line, 1, strlen($line));
echo $updatedLine . "</br>";
Hope it'll help.

Write to file using SplFileObject()

I'm trying to edit a file by line using SplFileObject(). I can choose the line of the file I want to edit. But how do I then write a $string to that line?
Here is my code to get the line:
<?php
$file = new SplFileObject('myfile.txt');
$file->seek(9999); // Seek to line no. 10,000
echo $file->current(); // Print contents of that line
?>
How do I insert a string on that line?
Note, I don't want to overwrite the file, I simply want to insert a $string at a given line.
This isn't probably the best solution as it will read the whole file and store it in a string. But since there are no other answers you can use this as your last resource.
$ouput = '';
$file = new SplFileObject("your_file.xxx", 'r');
while (!$file->eof()) {
$line = $file->fgets();
if($line == 'your_condition'){
$line = 'replace this line';
}
$output .= $line;
}
$file = null;
$file = new SplFileObject("your_file.xxx", 'w+');
$file->fwrite($output);

Get only one line from a web page

Hi, I have this file test1.php and in the other file test.php I have this
php code running:
<?php
$file = "http://inviatapenet.gethost.ro/sop/test1.php";
$line = '0';
if($f = fopen($file, 'r')){
$line = fgets($f); // read until first newline
fclose($f);
}
echo $line;
?>
The idea is to get just the second line of the web page test1.php.
Second Line
I've tried to change the $line = '2'; but no affect, it just displays the first line.
I need Help.
You can use file which reads a file into an array, you can then grab whichever line you want by using the index you want.
For example:
data.txt:
line one
line two
line three
line four
PHP code:
$file = file('data.txt');
echo $file[1]; // echo line number 2, remember arrays start at 0!
Updated PHP code for new versions (5.4):
echo file('data.txt')[1];
This should work. Obviously, change only the value of $linetofetch:
<?php
// Write here the number of the line you want to fetch.
$linetofetch = 2;
$file = "http://inviatapenet.gethost.ro/sop/test1.php";
$currentline = 1;
if($f = fopen($file, 'r')){
while ($currentline <= $linetofetch) {
$line = fgets($f); // read until first newline
$currentline++;
}
fclose($f);
}
echo $line;
?>

PHP: Read Specific Line From File

I'm trying to read a specific line from a text file using php.
Here's the text file:
foo
foo2
How would I get the content of the second line using php?
This returns the first line:
<?php
$myFile = "4-24-11.txt";
$fh = fopen($myFile, 'r');
$theData = fgets($fh);
fclose($fh);
echo $theData;
?>
..but I need the second.
Any help would be greatly appreciated
$myFile = "4-24-11.txt";
$lines = file($myFile);//file in to an array
echo $lines[1]; //line 2
file — Reads entire file into an array
omg I'm lacking 7 rep to make comments. This is #Raptor's & #Tomm's comment, since this question still shows up way high in google serps.
He's exactly right. For small files file($file); is perfectly fine. For large files it's total overkill b/c php arrays eat memory like crazy.
I just ran a tiny test with a *.csv with a file size of ~67mb (1,000,000 lines):
$t = -microtime(1);
$file = '../data/1000k.csv';
$lines = file($file);
echo $lines[999999]
."\n".(memory_get_peak_usage(1)/1024/1024)
."\n".($t+microtime(1));
//227.5
//0.22701287269592
//Process finished with exit code 0
And since noone mentioned it yet, I gave the SplFileObject a try, which I actually just recently discovered for myself.
$t = -microtime(1);
$file = '../data/1000k.csv';
$spl = new SplFileObject($file);
$spl->seek(999999);
echo $spl->current()
."\n".(memory_get_peak_usage(1)/1024/1024)
."\n".($t+microtime(1));
//0.5
//0.11500692367554
//Process finished with exit code 0
This was on my Win7 desktop so it's not representative for production environment, but still ... quite the difference.
If you wanted to do it that way...
$line = 0;
while (($buffer = fgets($fh)) !== FALSE) {
if ($line == 1) {
// This is the second line.
break;
}
$line++;
}
Alternatively, open it with file() and subscript the line with [1].
I would use the SplFileObject class...
$file = new SplFileObject("filename");
if (!$file->eof()) {
$file->seek($lineNumber);
$contents = $file->current(); // $contents would hold the data from line x
}
you can use the following to get all the lines in the file
$handle = #fopen('test.txt', "r");
if ($handle) {
while (!feof($handle)) {
$lines[] = fgets($handle, 4096);
}
fclose($handle);
}
print_r($lines);
and $lines[1] for your second line
$myFile = "4-21-11.txt";
$fh = fopen($myFile, 'r');
while(!feof($fh))
{
$data[] = fgets($fh);
//Do whatever you want with the data in here
//This feeds the file into an array line by line
}
fclose($fh);
This question is quite old by now, but for anyone dealing with very large files, here is a solution that does not involve reading every preceding line. This was also the only solution that worked in my case for a file with ~160 million lines.
<?php
function rand_line($fileName) {
do{
$fileSize=filesize($fileName);
$fp = fopen($fileName, 'r');
fseek($fp, rand(0, $fileSize));
$data = fread($fp, 4096); // assumes lines are < 4096 characters
fclose($fp);
$a = explode("\n",$data);
}while(count($a)<2);
return $a[1];
}
echo rand_line("file.txt"); // change file name
?>
It works by opening the file without reading anything, then moving the pointer instantly to a random position, reading up to 4096 characters from that point, then grabbing the first complete line from that data.
If you use PHP on Linux, you may try the following to read text for example between 74th and 159th lines:
$text = shell_exec("sed -n '74,159p' path/to/file.log");
This solution is good if your file is large.
You have to loop the file till end of file.
while(!feof($file))
{
echo fgets($file). "<br />";
}
fclose($file);
Use stream_get_line: stream_get_line — Gets line from stream resource up to a given delimiter
Source: http://php.net/manual/en/function.stream-get-line.php
You could try looping until the line you want, not the EOF, and resetting the variable to the line each time (not adding to it). In your case, the 2nd line is the EOF. (A for loop is probably more appropriate in my code below).
This way the entire file is not in the memory; the drawback is it takes time to go through the file up to the point you want.
<?php
$myFile = "4-24-11.txt";
$fh = fopen($myFile, 'r');
$i = 0;
while ($i < 2)
{
$theData = fgets($fh);
$i++
}
fclose($fh);
echo $theData;
?>
I like daggett answer but there is another solution you can get try if your file is not big enough.
$file = __FILE__; // Let's take the current file just as an example.
$start_line = __LINE__ -1; // The same with the line what we look for. Take the line number where $line variable is declared as the start.
$lines_to_display = 5; // The number of lines to display. Displays only the $start_line if set to 1. If $lines_to_display argument is omitted displays all lines starting from the $start_line.
echo implode('', array_slice(file($file), $start_line, lines_to_display));
I searched for a one line solution to read specific line from a file.
Here my solution:
echo file('dayInt.txt')[1]

Categories