-1

I have a PHP code that reads multiple txt files and search for user request for a word if the word exist the code will display the the requested word with the line number and the file name.

the code work perfect but the problem is in the line number because the system take all the txt file and combine it in one file and continue counting the line number .

what i want is to make the system start from the first line in each file

example :

word محلي exist in 7 files on the same line 13 the system display this :

  • the word محلّي exist on line [13] in 4-4-2017.txt
  • the word محلّي exist on line [77] in arabic text.txt
  • the word محلّي exist on line [175] in XXXX10-4-2017.txt
  • the word محلّي exist on line [240] in XXXX5-4-2017.txt
  • the word محلّي exist on line [302] in XXXX6-4-2017.txt
  • the word محلّي exist on line [367] in XXXX7-4-2017.txt
  • the word محلّي exist on line [431] in XXXX-08-04-2017.txt

yet this word exist on all these file on line 13

code:

<?php

$line = 1; 

if(isset($_POST["search"]))
{
    $search =$_POST['name'];
foreach(glob($_SERVER['DOCUMENT_ROOT']."/readfiletest/*.txt") as $txts)
  {
    $myFileLink = fopen($txts, 'r');

    while(!feof($myFileLink)) 
    { 
     $myFileContents = fgets($myFileLink);
     if( preg_match_all('/('.preg_quote($search,'/').')/i', $myFileContents, $matches))
     {

        foreach($matches[1] as $match)
        {
           echo "the word  $match exist on line [$line] in  ";

        }
        echo basename ($txts) . "<br>".PHP_EOL;
     //++$line;
     }

     ++$line;

    }


  fclose($myFileLink);

  }
}

?>


<html>
    <head>
    </head>
    <meta http-equiv="Content-Language" content="ar-sa">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <body>
     <form action="index.php" method="post">
          <p>enter your string <input type ="text"  id = "idName"  name="name" /></p>
          <p><input type ="Submit" name ="search" value= "Search" /></p>
    </form>
    </body>
</html>
Mohammad hayajneh
  • 623
  • 2
  • 11
  • 32
Rany Fahed
  • 39
  • 3
  • 11
  • $line = 1; remove this line from the begning and add inside the foreach loop before $myFileLink = fopen($txts, 'r'); – Alam Darji Dec 28 '17 at 09:59
  • @AlamDarji thank you for your help . if i want to just display the requested word one time like a title and then the places where it exist how to do it ? – Rany Fahed Dec 28 '17 at 10:06

1 Answers1

0

Change Your PHP Code to this. Hope this will help.

<?php 
$line = 1;
if(isset($_POST["search"]))
{
    $search =$_POST['name'];
    echo "the word  $search exist on <br><br>";
    foreach(glob($_SERVER['DOCUMENT_ROOT']."/readfiletest/*.txt") as $txts)
    {
        $myFileLink = fopen($txts, 'r');
        while(!feof($myFileLink)) 
        {
            $files[] = basename($txts);
            $myFileContents = fgets($myFileLink);
            if( preg_match_all('/('.preg_quote($search,'/').')/i', $myFileContents, $matches))
            {
                foreach($matches[1] as $match)
                {
                    //echo "line [$line] in  ";
                    $lines[str_replace(" ", "_", basename($txts))][] = $line;
                }
                //echo basename($txts) . "<br>".PHP_EOL;
            }
            ++$line;
        }
    fclose($myFileLink);
    }
}
?>

and in the body add this

<?php if(isset($_POST["search"]) && !empty($files)): ?>
<table border="1">
    <thead>
        <tr>
            <td>File Name</td>
            <td>Line No.</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <?php foreach ($files as $name): ?>
                <td><?= $name; ?></td>
                <td><?= implode(', ', $lines[str_replace(" ", "_", $name)]); ?></td>
            <?php endforeach ?>
        </tr>
    </tbody>
</table>
<?php endif; ?>
Alam Darji
  • 275
  • 3
  • 13
  • your code work perfect but it still display error in some lines. after i search for this string the system display : the word النظام exist on line [57] in 4-4-2017.txt line [58] in 4-4-2017.txt line [62] in line [62] in 4-4-2017.txt ============= the last line is malformed – Rany Fahed Dec 28 '17 at 10:31
  • It might me matching the word twice in the last line {line [62] in line [62] in 4-4-2017.txt } – Alam Darji Dec 28 '17 at 10:48
  • yes you were right .. i have a question if i have more than 1000 file is this code will work ? – Rany Fahed Dec 28 '17 at 11:04
  • but it will not be very slow in reading and matching for string ?? – Rany Fahed Dec 28 '17 at 11:12
  • depending upon the number of files in the folder it will take time but it will work absolutely fine. – Alam Darji Dec 28 '17 at 11:15
  • can you help me with this question if i want after the search to display all the files with line numbers in a table ...like the table column header will be the file name and the rows will be the line number – Rany Fahed Dec 28 '17 at 11:24
  • I don't think that is possible as the number of occurrence of the string matching will be different for different file and that will cause a problem in the structure of the table. – Alam Darji Dec 28 '17 at 11:39
  • oh okk now it make sense ... but how to display the result in a good format ? – Rany Fahed Dec 28 '17 at 11:46
  • Displaying the searches result in table it's not possible. – Alam Darji Dec 28 '17 at 11:48
  • Just wait for some time will give it a try. – Alam Darji Dec 28 '17 at 11:56
  • @ Alam Darji you mean the body of the HTML ? because i tried your code it did not workk it display the result in bade shape.... also it display these error : **Notice: Undefined index: arabic text2.txt in C:\xampp\htdocs\readfiletest\index.php on line 50 Warning: implode(): Invalid arguments passed in C:\xampp\htdocs\readfiletest\index.php on line 50** – Rany Fahed Dec 28 '17 at 12:49
  • Yes body of the HTML... try giving borders to the table
    – Alam Darji Dec 28 '17 at 12:53
  • answer updated. check please these two lines changed. { $lines[str_replace(" ", "_", basename($txts))][] = $line; } and { = implode(', ', $lines[str_replace("_", " ", $name)]); ?> } – Alam Darji Dec 28 '17 at 13:31