4

If we say that we have a text file containing order numbers or references (1 Number per 1 Line only) what is the best way to find/validate an input (number entered in form for example) against those numbers in a file?

Is there a simple idea to do it? Assume we have thousands of numbers to search through.

Thank you very much.

Ahmad Fouad
  • 3,957
  • 14
  • 45
  • 62
  • Is there anything else in addition to the order number on a line? How large is the file in bytes? Is memory an issue? – Gordon May 12 '11 at 14:03
  • 2
    No. All lines are typical each line contains order reference number like: 43559954541 just example. The file is large, I asusme it contains thousands of numbers/lines. Do you think it is efficient to do it this way ? or better store them in DB for example and do it with mysql? which is quicker way and less memory intensive...? – Ahmad Fouad May 12 '11 at 14:06
  • 2
    yes, you should use a DB for this – soju May 12 '11 at 14:08
  • thousands of numbers... are they somehow ordered ? – Eineki May 12 '11 at 14:10
  • I would recommend loading the numbers from the file into a database and take advantage of the fast indexing that it will provide. – James C May 12 '11 at 15:45

4 Answers4

2

If memory is not an issue (Demo):

if (in_array($number, file('numbers.txt', FILE_IGNORE_NEW_LINES))) {
    // number exists - do something
}

Since file returns an array where each line is one element in the array, you can also use array_search to find the line where it was found or array_keys to find all the lines where it was found.

If memory is an issue (Demo):

foreach(new SplFileObject('numbers.txt') as $line) {
    if ($number == $line) {
        // number exists - do something
        break;
    }
}

When in doubt which to use, benchmark.

Marking CW because there is already several questions asking how to read a file line by line or efficiently.

Community
  • 1
  • 1
Gordon
  • 312,688
  • 75
  • 539
  • 559
  • I tried that but it does not return the number at all even though it exists in seperate line in the numbers.txt. Are you sure this is it? – Ahmad Fouad May 12 '11 at 14:57
  • @Ahmad yes, see demo links above. I've also changed the check from == to ===, so you can use an integer or a numeric string for the search. – Gordon May 12 '11 at 15:27
0
$file = file_get_contents("filename.txt");
if (strpos($file, "search string") === false) {
    echo "String not found!";
}
Explosion Pills
  • 188,624
  • 52
  • 326
  • 405
  • 1
    Not really efficient since it will store all the file content in $file, it should be better to parse the file line by line. – soju May 12 '11 at 14:02
  • What is an efficient way to search through so many lines then? I just want to validate order number against all order numbers in text file. – Ahmad Fouad May 12 '11 at 14:04
  • when the numbers in the file are not in ascending order, searching for 10 would return true for the first number containing that, e.g. 10, 100, 1000, etc. – Gordon May 12 '11 at 14:37
0

If you want to return the line number of the location of the matching number in the file, you can use file() to return the reference file as an array of file lines.

$search_string = '42';
$file_name = 'test_file.txt';
$file = file($file_name);

foreach($file as $line_number=>$number){

if(intval($search_string) == $number){
    $found_on_lines[] = $line_number;
}
}

echo "String ".$search_string;

if(count($found_on_lines)>0){
echo " found on line(s):</br> ";
foreach($found_on_lines as $line){
    echo $line."</br>";
}
}
else{
echo  "not found in file ".$file_name.".";
}

This will output

String 42 found on line(s):
9
256

if your reference file contains the number '42' on lines 9 and 256.

kevtrout
  • 4,934
  • 6
  • 33
  • 33
0

if the numbers are ordered: don't load the whole file into memory. seek to the middle of the file and read the number. if your number is < than the middle, seek the middle of the first half. otherwise seek the middle of the second half...

Binary Search