11

In PHP, how can I open everyfile, all text files, in a directory and merge them all into one text file.

I don't know how to open all files in a directory, but I would use the file() command to open the next file and then a foreach to append each line to an array. like so:

$contents = array();
$line = file(/*next file in dir*/);
foreach($lines as line){
   array_push($line, $contents);
}

Then I would write that array to a new text file one I've reached no more files in the directory.

if you have a better way of doing this then please let me know.

Or if you can help me implement my solution especially the opening the next file in the dir, please let me know!

Django Johnson
  • 1,383
  • 3
  • 21
  • 40
  • Start by reading about [`opendir` function](http://php.net/manual/en/function.opendir.php) - and the related ones. – Aleks G Jun 06 '13 at 21:25

4 Answers4

12

OrangePill's answer is WRONG.

It returns an empty file and a compile ERROR. The problem was that he used fread (reads bytes) instead of fget (reads lines)

This is the working answer:

  //File path of final result
    $filepath = "mergedfiles.txt";

    $out = fopen($filepath, "w");
    //Then cycle through the files reading and writing.

      foreach($filepathsArray as $file){
          $in = fopen($file, "r");
          while ($line = fgets($in)){
                print $file;
               fwrite($out, $line);
          }
          fclose($in);
      }

    //Then clean up
    fclose($out);

    return $filepath;

Enjoy!

Rod
  • 419
  • 5
  • 3
2

The way that you are doing it is going to consume a lot of memory because it has to hold the contents of all of the files in memory ... this approach may be a little better

First off get all of the files you are going to want

  $files = glob("/path/*.*");

Then open an output file handle

  $out = fopen("newfile.txt", "w");

Then cycle through the files reading and writing.

  foreach($files as $file){
      $in = fopen($file, "r");
      while ($line = fread($in)){
           fwrite($out, $line);
      }
      fclose($in);
  }

Then clean up

  fclose($out);
Orangepill
  • 24,500
  • 3
  • 42
  • 63
  • Thank you, could you help me with two more things? Before I close the file, how could I remove any duplicate words / lines (each line contains one word) and then alphabetise the lines? – Django Johnson Jun 06 '13 at 21:44
  • if you are on a unix/linux machine after you perform the above you could run it through `exec("sort newfile.txt | uniq > newfile.sorted.txt'");` – Orangepill Jun 06 '13 at 21:48
  • 1
    I just tried the script and it is writing a blank text file. Nothing is in the text file. Here is the code in my index.php file: `` – Django Johnson Jun 06 '13 at 21:52
  • the `/*.*` must match a file mask that is readable by the webserver. I'm pretty sure the root file system is not. If you wanted to read the files ending in .txt in the current directory then you would pass in `./*.txt` – Orangepill Jun 06 '13 at 21:55
  • What if I don't know the file extension. Well, I do know. There are multiple file extensions. They are: `.10, .50, .60, .70, .80, .95, .20, .35, .55, .40, .0, .1, .2, .txt, .30, and .90` – Django Johnson Jun 06 '13 at 22:01
  • what directory are they in ... the same as the script or in their own directory. like a words directory? – Orangepill Jun 06 '13 at 22:03
  • same as the script index.php – Django Johnson Jun 06 '13 at 22:10
  • Then you will want to do `*.??` or find another way to populate the $files array with the name of the files. – Orangepill Jun 06 '13 at 22:16
  • Still getting a blank text file. My code is the same as above except `$files = glob("/*.*");` is now `$files = glob("./*.??");` – Django Johnson Jun 06 '13 at 22:22
  • Here is the entire index.php file that is in the same dir as the files: http://pastebin.com/RZxiZvC8. The echo also is never happening. – Django Johnson Jun 06 '13 at 22:25
  • `print_r($files);` after the assignment and try `__DIR__."/*.??"` – Orangepill Jun 06 '13 at 22:28
  • like `$files = glob("__DIR__."/*.??");` ? – Django Johnson Jun 06 '13 at 22:32
  • That doesn't seem right as the second " is not escaped. How else did you want me to do it? – Django Johnson Jun 06 '13 at 22:39
  • I'm encountering this error "fread() expects exactly 2 parameters, 1 given" i just copy the code and change the files – Albert Feb 06 '19 at 08:44
2

Try this:

<?php
//Name of the directory containing all files to merge
$Dir = "directory";


//Name of the output file
$OutputFile = "filename.txt";


//Scan the files in the directory into an array
$Files = scandir ($Dir);


//Create a stream to the output file
$Open = fopen ($OutputFile, "w"); //Use "w" to start a new output file from zero. If you want to increment an existing file, use "a".


//Loop through the files, read their content into a string variable and write it to the file stream. Then, clean the variable.
foreach ($Files as $k => $v) {
    if ($v != "." AND $v != "..") {
        $Data = file_get_contents ($Dir."/".$v);
        fwrite ($Open, $Data);
    }
    unset ($Data);
}


//Close the file stream
fclose ($Open);
?>
Attgun
  • 21
  • 5
0

Try below code and enjoy!!!

/* Directory Name of the files */
$dir = "directory/subDir";
/* Scan the files in the directory */
$files = scandir ($dir);
/* Loop through the files, read content of the files and put then OutFilename.txt */
$outputFile = "OutFilename.txt";
foreach ($files as $file) {
    if ($file !== "." OR $file != "..") {
        file_put_contents ($outputFile, file_get_contents ($dir."/".$file),  FILE_APPEND);
    }
}