Search code examples
phptextlines

Find string and replace multiple values in a large text file using PHP


I am trying to replace certain values in large text file having approx. 60,000 lines. First time code executes fine and replacing values but in next time it skips line numbers and append new values at end of file.

I am a beginner in coding, so I might need extended guidance.

Lines I need to change :

  1. MaxBytes[192.168.1.1]: 10000. This 1000 may be any number but IP address will be unique here. I need to change it MaxBytes[192.168.1.1]: 20000 (Assigned number);

  2. <TR><TD>Max Speed:</TD> <TD>200</TD></TR> This 200 may be any number. I am tracing <TR><TD>IP Address:</TD><TD>192.168.1.1</TD></TR> line and replacing next line since IP address is unique here.I need to change it to <TR><TD>Max Speed:</TD> <TD>500</TD></TR>

Sample Example.txt:

MaxBytes[192.168.1.1]: 10000
 <TABLE>
   <TR><TD>IP Address:</TD><TD>192.168.1.1</TD></TR>
   <TR><TD>Max Speed:</TD> <TD>300</TD></TR>
 </TABLE>

MaxBytes[192.168.1.2]: 30000
 <TABLE>
   <TR><TD>IP Address:</TD><TD>192.168.1.1</TD></TR>
   <TR><TD>Max Speed:</TD> <TD>300</TD></TR>
 </TABLE>

MaxBytes[192.168.1.3]: 10000
 <TABLE>
   <TR><TD>IP Address:</TD><TD>192.168.1.1</TD></TR>
   <TR><TD>Max Speed:</TD> <TD>200</TD></TR>
 </TABLE>

Here is the codes I am using

<?php
$dir = "Example.txt";
$search = "<TR><TD>IP Address:</TD><TD>192.168.1.1</TD></TR>";
$replacement = "   <TR><TD>Max Speed:</TD> <TD>500</TD></TR>";
$maxbytes = "MaxBytes[192.168.1.1]: ";
$new_line = "MaxBytes[192.168.1.1]: \r";
$newmaxbytes = "MaxBytes[192.168.1.1]: 20000";


///// Change Max Speed
function find_line_number_by_string($dir, $search, $case_sensitive=false ) {
        $line_number = '';
        if ($file_handler = fopen($dir, "r")) {
           $i = 0;
           while ($line = fgets($file_handler)) {
              $i++;
              //case sensitive is false by default
              if($case_sensitive == false) {    
                $search = strtolower($search); 
                $line = strtolower($line);      
              }
              //find the string and store it in an array
              if(strpos($line, $search) !== false){
                $line_number .=  $i.",";
              }
           }
           fclose($file_handler);
        }else{
            return "File not exists, Please check the file path or dir";
        }
        //if no match found
        if(count($line_number)){
            return substr($line_number, 0, -1);
        }else{
            return "No match found";
        }
    }

$line_number = find_line_number_by_string($dir, $search);
echo $line_number;

$lines = file($dir, FILE_IGNORE_NEW_LINES);
$lines[$line_number] = $replacement;
file_put_contents($dir , implode("\n", $lines));

///// Change MaxBytes

$contents = file_get_contents($dir);
$new_contents= "";
if( strpos($contents, $maxbytes) !== false) { // if file contains ID
    $contents_array = preg_split("/\\r\\n|\\r|\\n/", $contents);
    foreach ($contents_array as &$record) {    // for each line
        if (strpos($record, $maxbytes) !== false) { // if we have found the correct line
            $new_contents .= $new_line; // change record to new record
        }else{
            $new_contents .= $record . "\r";
        }
    }

file_put_contents($dir, $new_contents, LOCK_EX);

$fhandle = fopen($dir,"r");
$content = fread($fhandle,filesize($dir));
$content = str_replace($maxbytes, $newmaxbytes, $content);
$fhandle = fopen($dir,"w");
fwrite($fhandle,$content);
fclose($fhandle);

}else{}

?>

Solution

  • There is something not fully understandable in your question and code, of course it can be written in more optimal way.
    However considering the current code you share, I suppose this changed variant the one you need.

    <?php
    $dir = "Example.txt";
    $search = "<TR><TD>IP Address:</TD><TD>192.168.1.1</TD></TR>";
    $replacement = "   <TR><TD>Max Speed:</TD> <TD>10000</TD></TR>";
    $maxbytes = "MaxBytes[192.168.1.1]: ";
    $new_line = "MaxBytes[192.168.1.1]: \r";
    $newmaxbytes = "MaxBytes[192.168.1.1]: 20000";
    
    
    ///// Change Max Speed
    function find_line_number_by_string($dir, $search, $case_sensitive=false ) {
        $line_number = [];
        if ($file_handler = fopen($dir, "r")) {
            $i = 0;
            while ($line = fgets($file_handler)) {
                $i++;
                //case sensitive is false by default
                if($case_sensitive == false) {
                    $search = strtolower($search);
                    $line = strtolower($line);
                }
                //find the string and store it in an array
                if(strpos($line, $search) !== false){
                    $line_number[] =  $i;
                }
            }
            fclose($file_handler);
        }else{
            return "File not exists, Please check the file path or dir";
        }
    
        return $line_number;
    }
    
    $line_number = find_line_number_by_string($dir, $search);
    var_dump($line_number);
    
    
    $lines = file($dir, FILE_IGNORE_NEW_LINES);
    if(!empty($line_number)) {
        $lines[$line_number[0]] = $replacement;
    }
    
    file_put_contents($dir , implode("\n", $lines));
    
    ///// Change MaxBytes
    
    $contents = file_get_contents($dir);
    $new_contents= "";
    if( strpos($contents, $maxbytes) !== false) { // if file contains ID
        $contents_array = preg_split("/\\r\\n|\\r|\\n/", $contents);
        foreach ($contents_array as &$record) {    // for each line
            if (strpos($record, $maxbytes) !== false) { // if we have found the correct line
                $new_contents .= $new_line; // change record to new record
            }else{
                $new_contents .= $record . "\n";
            }
        }
    
        file_put_contents($dir, $new_contents, LOCK_EX);
    
        $fhandle = fopen($dir,"r");
        $content = fread($fhandle,filesize($dir));
        $content = str_replace($maxbytes, $newmaxbytes, $content);
        $fhandle = fopen($dir,"w");
        fwrite($fhandle,$content);
        fclose($fhandle);
    
    }else{}
    
    ?>
    

    If it does not works the way you need, please contact me, I'll update the answer..