Search code examples
phpfile-get-contentsstr-replace

How do I edit multiple .txt files with different names in a folder?


I have a folder that contains several .txt files called :

A500_1.txt

A500_2.txt

A700_1.txt

A700_2.txt

A900_1.txt

...

In each of the .txt files there is :

PRXC1_|TB|CCAAO9-RC|9353970324463|24.99

PRXC1_|TB|CFEXK4-RC|9353970294766|84.99

PRXC1_|TB|CFEXK4-RC|9353970294773|84.99

...

I'd like you to :

  • if the filename starts with A500_ replace "TB" with "MD"

  • if the filename starts with A700_ replace "TB" by "JB"

  • if the filename senter code heretarts with A900_ replace "TB" with "LD"

I wrote this function but it just creates me an empty A500_2.TXT file at the root of the project and displays :

Warning: file_get_contents(A500_2.TXT): failed to open stream:

Where's my error?

<?php

function processFile( $path ) {

   $dir    = './test/';
   $allFiles = scandir($dir);

   foreach($allFiles as $file) {

       $filename = basename( $file );

        if ( ! in_array($file,array(".","..")))
      { 

       //read the entire string
       $str = file_get_contents( $file );

       // var_dump($str);

       // replace something in the file string
       if ( strpos( $filename, 'A500_' ) === 0 ) {

           $str = str_replace( 'TB', 'MD', $str );

       } else if ( strpos( $filename, 'A700_' ) === 0 ) {

           $str = str_replace( 'TB', 'JB', $str );

       } else if ( strpos( $filename, 'A900_' ) === 0 ) {

           $str = str_replace( 'TB', 'LD', $str );

       } else {
           // Return false if we don't know what to do with this file
           return false;
       }

       //write the entire string    
       $writeResult = file_put_contents( $file, $str );

       //return true after a file is written successfully, or false on failure
       return $writeResult >= 0;

  }
  }
}

if(processFile( './test/' )) echo "good!";
?>

Solution

  • Both the file_get_contents warning and the blank file being created are down to the same problem - scandir returns just the filename, not a relative path to the currently running script.

    I'd guess that you're expecting it to return relative paths, which is why you're calling basename at the top of your loop. As it is, your $file and $filename arguments are going to always be set to the same thing.

    The quickest solution will be to prepend $file with the scanned directory name before processing anything else:

    $file = $dir . $file;
    

    This should fix both the read and write calls.