Palguno Wicaksono
Palguno Wicaksono

Reputation: 43

Add text to specific line without removing the exist line in php

I'm trying to add only last name if first name is same

data.txt

Alice Sandy
Alice Nanami
James Watt
Alice Monica
Johann Gauss

to result.txt

Alice Sandy Nanami Monica
James Watt
Johann Gauss

I try with this code

$resultFile = "result.txt";
$search     = "Alice";
$lineNumber = false;
if ($handle = fopen($result, "r")) {
    $count = 0;
    while (($line = fgets($handle, 4096)) !== FALSE and !$lineNumber) {
        $count++;
        $lineNumber = (strpos($line, $search) !== FALSE) ? $count : $lineNumber;
        $isExist = (strpos($line, $search) !== FALSE) ? "yup" : "no";
    }
fclose($handle);
}
if($isExist=="yup"){
    $lines = file($resultFile);
    $lines[$lineNumber] = $lines[$lineNumber].' '.$lastName;
    file_put_contents($result, implode('', $lines));
}else{
    $fullName = $firstName.' '.$lastName;
    $fileOpen = fopen($result, "a");
    fwrite($fileOpen,$fullName);
    fclose($fileOpen);
    $addBreaker = "\n";
    $splResult = new SplFileObject($resultFile, 'a');
    $splResult->fwrite($addBreaker);
}

But it give error offset (I'm using PHP 7) and the result is untidy

Alice Sandy Nanami
 Monica
James Watt

Johan Gauss

Thanks for help

Upvotes: 1

Views: 126

Answers (2)

mickmackusa
mickmackusa

Reputation: 47874

Use file() to collect the file contents as an array of lines. My snippet starts from there with $lines.

Iterate the array and makes each line modifiable by reference. (&)

Locate the first occurring needle match that not only exists in the line but matches the whole first word so that you don't get false-positive matching.

Then declare the first match as a reference variable (=&) and continue iterating the array. Any subsequent matches will have the delimiting space and second word appended to the reference variable. Then immediate unset the line to be purged from the document.

When done, re-implode the data and stuff the content into the result file.

This is clean, readable, and only needs one loop.

Code: (Demo)

// $lines = file('result.txt', FILE_IGNORE_NEW_LINES);
$lines = [
    'Alice Sandy',
    'Alice Nanami',
    'James Watt',
    'Alice Monica',
    'Johann Gauss',
    'Cooper Alice',
];

$needle = 'Alice';
foreach($lines as $index => &$line) {
    if ($needle === strstr($line, ' ', true)) { // check whole first word
        if (!isset($firstOccurrence)) {
            $firstOccurrence =& $line;
        } else {
            $firstOccurrence .= strstr($line, ' ');
            unset($lines[$index]);
        }
    }
}
var_export($lines);
// file_put_contents('result.txt', implode(PHP_EOL, $lines));

Output:

array (
  0 => 'Alice Sandy Nanami Monica',
  2 => 'James Watt',
  4 => 'Johann Gauss',
  5 => 'Cooper Alice',
)

P.s if you want to know if any rows were changed you could check if the original array is === the new array after looping, or you could just use a boolean flag variable in the else condition.

Upvotes: 0

JSowa
JSowa

Reputation: 10572

Another apporach instead of replacing lines would be save every line to an array and then iterate over array and save to the new file. You can also use the same file as an $outputFile.

$inputFile = 'names.txt';
$outputFile = 'result.txt';

$names = [];

if ($handle = fopen($inputFile, "r")) {
    $count = 0;
    while (($line = fgets($handle, 4096)) !== FALSE) {
        $count++;
        $lineNames = explode(' ', $line);
        $names[$lineNames[0]][] = trim($lineNames[1]);
    }
    fclose($handle);
}

$handle = fopen($outputFile, 'w');
foreach ($names as $firstName => $lastNames) {
    fwrite($handle, $firstName . ' ' . implode(' ', $lastNames) . PHP_EOL);
}

Two additional notes:

  1. Don't use string as boolean value.

    $isExist = (strpos($line, $search) !== FALSE) ? "yup" : "no";

Use just following condition. It's enough

$isExist = (strpos($line, $search) !== FALSE)
  1. If you read lines from file you copy also new lines char, although you can't see them quite well in the output. You should trim all whitespace characters before inserting/replacing etc. to avoid old structure of file.

Upvotes: 1

Related Questions