madusanka
madusanka

Reputation: 163

php unable to open file when open and write into file

i try to read a text file line by line and if any line contain "/" then i need to write them into separate file. example line

CA,T2B,Calgary (Forest Lawn / Dover / Erin Woods),Alberta,AB,Calgary,,,,51.0209,-113.981,6

i need to write this as 4 lines, like

CA,T2B,Calgary,Alberta,AB,Calgary,,,,51.0209,-113.981,6
CA,T2B, Forest Lawn ,Alberta,AB,Calgary,,,,51.0209,-113.981,6
CA,T2B, Dover,Alberta,AB,Calgary,,,,51.0209,-113.981,6
CA,T2B, Erin Woods,Alberta,AB,Calgary,,,,51.0209,-113.981,6

what i've tried so far is

$file = fopen("test.txt", "r");

while (!feof($file)) {
  $my_string = fgets($file);
  $special_chars = array("/");
  if (array_intersect(str_split($my_string), $special_chars)) {
    echo fgets($file) . "<br />";
    $myfile = fopen("fileWithFL.txt", "w") or die("Unable to open file!");
    fwrite($myfile, fgets($file));
    fclose($myfile);
  }else{
    echo fgets($file) . "<br />";
    $myfile = fopen("fileWithoutFL.txt", "w") or die("Unable to open file!");
    fwrite($myfile, fgets($file));
    fclose($myfile);
  }
}

fclose($file);

[file i try to read][1] file i get from "CA.zip"

how can i do this? thank you!

Upvotes: 0

Views: 150

Answers (3)

kmoser
kmoser

Reputation: 9308

You're repeatedly opening and closing fileWithFL.txt and fileWithoutFL.txt, which is inefficient. Better to just open them once before you loop through the input file.

You're also using fgets(), which makes it difficult to parse the input file. Since the input file seems to be in CSV format, you should use fgetcsv().

As for detecting rows that contain multiple cities, I'm looking for the presence of /, splitting on ( or /), removing any trailing ), and trimming the resulting name. That should give you all the cities in a neat array.

$file = fopen("test.txt", "r");

$file_with_fl = fopen("fileWithFL.txt", "w+");
$file_without_fl = fopen("fileWithoutFL.txt", "w+");

while ($a = fgetcsv($file)) {
    if ( FALSE == strpos( $a[2], '/' ) ) {
        fputcsv( $file_without_fl, $a );
    } else {
        $cities = preg_split( '/[\(\/]/', $a[2] ); // Split on '(' and '/'
        foreach ( $cities as $city ) {
            $city = trim(preg_replace('/\)/', '', $city)); // Remove trailing ')' and trim leading and trailing spaces
            $a[2] = $city;
            fputcsv( $file_with_fl, $a );
        }
    }
}

Checking for failure of fopen() and fputcsv() left as an exercise for the reader.

Upvotes: 1

Jerson
Jerson

Reputation: 1745

Not the best answer but its works

  $line = file_get_contents("test.txt");
  $body = "";

  if(false !== strpos($line,"/")) {
    $split = preg_split("/[()]+/", $line,-1, PREG_SPLIT_NO_EMPTY);
    $contains = explode("/",$split[1]);
    $last = explode(",",$split[0]);
    $lastvalue = end($last);
    $search = array_search($lastvalue,$last);
    unset($last[$search]);
    $merge = implode(", ", $last);
    $body .= $merge . $split[2] . " ";

    foreach($contains as $contain) {
      $body .= $split[0] . "," . $contain . $split[2] . " ";
    }

    if(file_put_contents("fileWithFL.txt",$body) !== false) {
      echo $body;
    } else {
      echo "failed";
    }

  } else {

    if(file_put_contents("fileWithoutFL.txt",$line) !== false) {
      echo $line;
    } else {
      echo "failed";
    }

  }

Output :

 CA, T2B,Alberta,AB,Calgary,,,,51.0209,-113.981,6 CA,T2B,Calgary ,Forest Lawn ,Alberta,AB,Calgary,,,,51.0209,-113.981,6 CA,T2B,Calgary , Dover ,Alberta,AB,Calgary,,,,51.0209,-113.981,6 CA,T2B,Calgary , Erin Woods,Alberta,AB,Calgary,,,,51.0209,-113.981,6

Upvotes: 0

Michel
Michel

Reputation: 4157

You can use file_put_contents(file, string, FILE_APPEND) to add a line to the end of a file. The rest is just processing the Calgary (Forest Lawn / Dover / Erin Woods) part of your string.

$string = 'CA,T2B,Calgary (Forest Lawn / Dover / Erin Woods),Alberta,AB,Calgary,,,,51.0209,-113.981,6';

//test if string needs processing
//if not, write straight to new file
if(strpos($string,'/') === false){
    file_put_contents("fileWithoutFL.txt" , $string , FILE_APPEND);
    }

//process
else{
     //get all the parts split by comma
     //$parts[2] is the one you need processing
   $parts = explode(',',$string);

     //clean up $part[2], replacing ( , ) with *
     //then split on the *
   $com=explode('*',str_replace(['(','/',')'],'*',$parts[2]));

     //loop $com, creating new arrays by replacing $part[2] in the original array
   foreach($com as $val){
      if($val == '')continue;
        //replace $part[2] cleaning up spaces
      $parts[2] = trim($val);
        //make a new line
      $write = implode(',',$parts);
        //write to the new file
      file_put_contents("fileWithoutFL.txt" , $write , FILE_APPEND);
      }
   }

Now you can read every line of the original file and output to the new file. (Tip: use SplFileObject)

$file = new SplFileObject("fileWithFL.txt");
while (!$file->eof()) {
   $string = $file->fgets();
   // ... process here with previous code
  
 }
$file = null;

Upvotes: 1

Related Questions