oyed
oyed

Reputation: 570

PHP fetching a .txt file and editing a single line

This is my code:

$string2 = file_get_contents('maps/' . $region . '.txt');
$string2 = explode("\n", $string2);
foreach($string2 as $value2) {
   $string2 = unserialize($value2);
   if($string2['x_pos'] == ($x2 + 4) && $string2['y_pos'] == ($y2 + 8)) {
      $length2 = strlen($string2['amount']);
      $new_amount = ($string2['amount'] + 0) - ($resource_quantity + 0);
      $changed = substr_replace($value2, $new_amount, 123, $length2);
      file_put_contents('maps/' . $region . '.txt', $changed);
      break 1;
   }
}

What I want the code to do is to open the file, read each line until it finds the line it wants and then re-save the file with the edited line. The problem is, that it works, but it only saves it with the edited line, and gets rid of all of the other lines.

I want to keep with the method I've used (file_get_contents & file_put_contents) really, unless there is an incredibly easier way to do it. Can someone please help? I've been searching for some time and cannot find what I'm looking for.

Upvotes: 2

Views: 549

Answers (3)

DaveRandom
DaveRandom

Reputation: 88647

The best way to break a file by line is with file(). Here is what I would do (FIXED):

<?php

  // This exactly the same effect as your first two lines
  $fileData = file("maps/$region.txt");

  foreach ($fileData as $id => $line) {
    // This is probably where your problem was - you were overwriting
    // $string2 with your value, and since you break when you find the
    // line, it will always be the line you were looking for...
    $line = unserialize($line);
    if ($line['x_pos'] == ($x2 + 4) && $line['y_pos'] == ($y2 + 8)) {
      $amountLen = strlen($line['amount']);
      // Sorry, adding zero? What does this achieve?
      $new_amount = $line['amount'] - $resource_quantity;
      // Modify the actual line in the original array - by catching it in
      // $changed and writing that variable to file, you are only writing
      // that one line to file.
      // I suspect substr_replace is the wrong approach to this operation
      // since you seem to be running it on PHP serialized data, and a
      // more sensible thing to do would be to modify the values in $line
      // and do:
      // $fileData[$id] = serialize($line);
      // ...however, since I can;t work out what you are actually trying
      // to achieve, I have fixed this line and left it in.
      $fileData[$id] = substr_replace($fileData[$id], $new_amount, 123, $amountLen);
      break;
    }
  }

  file_put_contents("maps/$region.txt", $fileData);

?>

Upvotes: 1

gidanmx2
gidanmx2

Reputation: 469

Try to use this: http://php.net/file (Reads entire file into an array)

Upvotes: 1

Jon
Jon

Reputation: 437336

You need to move the write operation after the loop and have it write everything you read from the file. The way you currently have it, it's replacing all the contents with just $changed (which is just one line).

The above, in addition to improving the code a bit, leads us to:

$filename = 'maps/' . $region . '.txt';
$lines = file($filename);
foreach($lines as &$line) { // attention: $line is a reference
    $obj = unserialize($line);
    if(/* $obj satisfies your criteria*/) {
        $line = /* modify as you need */;
        break;
    }
}

file_put_contents($filename, implode("\n", $lines));

Upvotes: 4

Related Questions