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 ) );
Folder
File1.txt
File2.txt
File3.txt
File4.txt
File5.txt
File6.txt
File7.txt
File8.txt
File9.txt
But whenever I add another file it looks like this
File1.txt
File10.txt //NEW FILE
File2.txt
File3.txt
File4.txt
File5.txt
File6.txt
File7.txt
File8.txt
File9.txt
And mabey I add another file
File1.txt
File10.txt //NEW FILE
File11.txt //NEWER FILE
File2.txt
File3.txt
File4.txt
File5.txt
File6.txt
File7.txt
File8.txt
File9.txt
And as you can guess when I include all these files in one PHP file
It messes up...
Say that file1.txt has the contents :1
File10.txt has the contents :10
File2.txt has the contents :2
File3.txt has the contents :3
And so on
When I include this the order on the page appears as this
1
10
2
3
4
5
And so on
So how do I get the files to appear in number order???
Here is the code I'm working with
<?php
// Add correct path to your countlog.txt file.
$path = 'ChatNumbers.txt';
// Opens countlog.txt to read the number of hits.
$file = fopen( $path, 'r' );
$count = fgets( $file, 1000 );
fclose( $file );
// Update the count
$count = abs( intval( $count ) ) + "1";
// Opens countlog.txt to change new hit number.
$file = fopen( $path, 'w' );
fwrite( $file, $count);
fclose( $file );
$ab = 'Chat_';
$cn = "$count";
$rp = '.html';
$fr = "$ab$cn$rp";
$path = "Chats/$fr";
if (isset($_POST['field1'])) {
$fh = fopen($path,"a+");
$string = $_POST['field1'].'<p></p>';
fwrite($fh,$string); // Write information to the file
fclose($fh); // Close the file
}
?>
And This is how I am currently including my files
<php
foreach (glob("chat/Chats/*.html") as $filename)
{
include $filename;
}
?>
Not the best way to go about all of this I'm sure, but to answer the question, you need to sort (naturally):
$files = glob("chat/Chats/*.html");
natsort($files);
foreach ($files as $filename)
{
include $filename;
}
I want to read a file line by line, but without completely loading it in memory.
My file is too large to open in memory, and if try to do so I always get out of memory errors.
The file size is 1 GB.
You can use the fgets() function to read the file line by line:
$handle = fopen("inputfile.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
// process the line read.
}
fclose($handle);
}
if ($file = fopen("file.txt", "r")) {
while(!feof($file)) {
$line = fgets($file);
# do same stuff with the $line
}
fclose($file);
}
You can use an object oriented interface class for a file - SplFileObject http://php.net/manual/en/splfileobject.fgets.php (PHP 5 >= 5.1.0)
<?php
$file = new SplFileObject("file.txt");
// Loop until we reach the end of the file.
while (!$file->eof()) {
// Echo one line from the file.
echo $file->fgets();
}
// Unset the file to call __destruct(), closing the file handle.
$file = null;
If you want to use foreach instead of while when opening a big file, you probably want to encapsulate the while loop inside a Generator to avoid loading the whole file into memory:
/**
* #return Generator
*/
$fileData = function() {
$file = fopen(__DIR__ . '/file.txt', 'r');
if (!$file) {
return; // die() is a bad practice, better to use return
}
while (($line = fgets($file)) !== false) {
yield $line;
}
fclose($file);
};
Use it like this:
foreach ($fileData() as $line) {
// $line contains current line
}
This way you can process individual file lines inside the foreach().
Note: Generators require >= PHP 5.5
There is a file() function that returns an array of the lines contained in the file.
foreach(file('myfile.txt') as $line) {
echo $line. "\n";
}
The obvious answer wasn't there in all the responses.
PHP has a neat streaming delimiter parser available made for exactly that purpose.
$fp = fopen("/path/to/the/file", "r");
while (($line = stream_get_line($fp, 1024 * 1024, "\n")) !== false) {
echo $line;
}
fclose($fp);
Use buffering techniques to read the file.
$filename = "test.txt";
$source_file = fopen( $filename, "r" ) or die("Couldn't open $filename");
while (!feof($source_file)) {
$buffer = fread($source_file, 4096); // use a buffer of 4KB
$buffer = str_replace($old,$new,$buffer);
///
}
foreach (new SplFileObject(__FILE__) as $line) {
echo $line;
}
One of the popular solutions to this question will have issues with the new line character. It can be fixed pretty easy with a simple str_replace.
$handle = fopen("some_file.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
$line = str_replace("\n", "", $line);
}
fclose($handle);
}
This how I manage with very big file (tested with up to 100G). And it's faster than fgets()
$block =1024*1024;//1MB or counld be any higher than HDD block_size*2
if ($fh = fopen("file.txt", "r")) {
$left='';
while (!feof($fh)) {// read the file
$temp = fread($fh, $block);
$fgetslines = explode("\n",$temp);
$fgetslines[0]=$left.$fgetslines[0];
if(!feof($fh) )$left = array_pop($lines);
foreach ($fgetslines as $k => $line) {
//do smth with $line
}
}
}
fclose($fh);
Be careful with the 'while(!feof ... fgets()' stuff, fgets can get an error (returnfing false) and loop forever without reaching the end of file. codaddict was closest to being correct but when your 'while fgets' loop ends, check feof; if not true, then you had an error.
SplFileObject is useful when it comes to dealing with large files.
function parse_file($filename)
{
try {
$file = new SplFileObject($filename);
} catch (LogicException $exception) {
die('SplFileObject : '.$exception->getMessage());
}
while ($file->valid()) {
$line = $file->fgets();
//do something with $line
}
//don't forget to free the file handle.
$file = null;
}
<?php
echo '<meta charset="utf-8">';
$k= 1;
$f= 1;
$fp = fopen("texttranslate.txt", "r");
while(!feof($fp)) {
$contents = '';
for($i=1;$i<=1500;$i++){
echo $k.' -- '. fgets($fp) .'<br>';$k++;
$contents .= fgets($fp);
}
echo '<hr>';
file_put_contents('Split/new_file_'.$f.'.txt', $contents);$f++;
}
?>
Function to Read with array return
function read_file($filename = ''){
$buffer = array();
$source_file = fopen( $filename, "r" ) or die("Couldn't open $filename");
while (!feof($source_file)) {
$buffer[] = fread($source_file, 4096); // use a buffer of 4KB
}
return $buffer;
}
I have a file xyz.zip and in this file there are two more files test.xml and another abc.zip file that contains test2.xml. When i use this code it only extract xyz.zip file. But i also need to extract abc.zip.
xyz.zip
- test.xml
- abc.zip
- test2.xml
<?php
$filename = "xzy.zip";
$zip = new ZipArchive;
if ($zip->open($filename) === TRUE) {
$zip->extractTo('./');
$zip->close();
echo 'Success!';
}
else {
echo 'Error!';
}
?>
Can somebody please tell me how can i extract everything in zip files? Even abc.zip. So that the output will be in a folder (test.xml and test2.xml).
Thanks
this might help you.
This function will flatten a zip file using the ZipArchive class.
It will extract all the files in the zip and store them in a single destination directory. That is, no sub-directories will be created.
<?php
// dest shouldn't have a trailing slash
function zip_flatten ( $zipfile, $dest='.' )
{
$zip = new ZipArchive;
if ( $zip->open( $zipfile ) )
{
for ( $i=0; $i < $zip->numFiles; $i++ )
{
$entry = $zip->getNameIndex($i);
if ( substr( $entry, -1 ) == '/' ) continue; // skip directories
$fp = $zip->getStream( $entry );
$ofp = fopen( $dest.'/'.basename($entry), 'w' );
if ( ! $fp )
throw new Exception('Unable to extract the file.');
while ( ! feof( $fp ) )
fwrite( $ofp, fread($fp, 8192) );
fclose($fp);
fclose($ofp);
}
$zip->close();
}
else
return false;
return $zip;
}
/*
How to use:
zip_flatten( 'test.zip', 'my/path' );
*/
?>
You should use a recursive function that check all the extracted files and if it finds out one of them is a zip, then call itself again.
function scanDir($path) {
$files = scandir($path);
foreach($files as $file) {
if (substr($file, -4)=='.zip')
unzipRecursive($path, $file);
elseif (isdir($path.'/'.$file))
scanDir($path.'/'.$file);
}
}
function unzipRecursive($absolutePath, $filename) {
$zip = new ZipArchive;
$newfolder = $absolutePath.'/'.substr($file, 0, -4);
if ($zip->open($filename) === TRUE) {
$zip->extractTo($newfolder);
$zip->close();
//Scan the directory
scanDir($newfolder)
} else {
echo 'Error unzipping '.$absolutePath.'/'.$filename;
}
}
I didn't try the code but it's only to debug a little I guess
Hi I do have a text file with size of upto 30MB I would like to read this file using PHP loop script
$lines = file('data.txt');
//loop through each line
foreach ($lines as $line) { \\some function }
Is there any way? I want open it for reading php doesnt allow me to open a 30MB file.
You could read it line by line like this:
$file = fopen("data.txt", "r") or exit("Unable to open file!");
while(!feof($file)) {
// do what you need to do with it - just echoing it out for this example
echo fgets($file). "<br />";
}
fclose($file);
Read line by line using:
$handle = fopen ( "data.txt", "r" );
while ( ( $buffer = fgets ( $handle, 4096 ) ) !== false ) {
// your function on line;
}
If it is suitable for you to read the file piece-by-piece you can try something like this
$fd = fopen("fileName", "r");
while (!feof($fd)) {
$buffer = fread($fd, 16384); //You can change the size of the buffer according to the memory you can youse
//Process here the buffer, piece by piece
}
fclose($fd);