PHP check if file contains a string
Asked Answered
R

6

48

I'm trying to see if a file contains a string that is sent to the page. I'm not sure what is wrong with this code:

?php
    $valid = FALSE;
    $id = $_GET['id'];
    $file = './uuids.txt';

    $handle = fopen($file, "r");

if ($handle) {
    // Read file line-by-line
    while (($buffer = fgets($handle)) !== false) {
        if (strpos($buffer, $id) === false)
            $valid = TRUE;
    }
}
fclose($handle);

    if($valid) {
do stufff
}
Runofthemill answered 30/1, 2012 at 3:33 Comment(2)
What if you var_dump($buffer, $id); instead of comparing them by if?Coxa
If you have an error, please mention it.Assr
M
100

Much simpler:

<?php
    if( strpos(file_get_contents("./uuids.txt"),$_GET['id']) !== false) {
        // do stuff
    }
?>

In response to comments on memory usage:

<?php
    if( exec('grep '.escapeshellarg($_GET['id']).' ./uuids.txt')) {
        // do stuff
    }
?>
Murex answered 30/1, 2012 at 3:36 Comment(9)
Much simpler but more memory consumingCoxa
Don't have to load whole text to memory.Hardship
@Coxa How about now?Murex
@In response to comments on memory usage not working for meVanettavang
1st example will not work if the string to be searched is in the first or last line of the file.Flack
@FilipeYaBaPolido: Please elaborate further on your comment above.Danged
@ChrysUgwu that won't work on all machines. It will most notably not work on Windows.Knightly
@Danged sure, create a file with 10 strings, apply that code, it will miss the 1st string and the last one.Flack
For grep solution -c option could be added to suppress normal output and instead print a count of matching lines, 0 for none, and positive integer if found anything.Collen
H
28

For larger files, this code is more efficient (as it reads line by line, instead of entire file at once).

$handle = fopen('path_to_your_file', 'r');
$valid = false; // init as false
while (($buffer = fgets($handle)) !== false) {
    if (strpos($buffer, $id) !== false) {
        $valid = TRUE;
        break; // Once you find the string, you should break out the loop.
    }      
}
fclose($handle);
Hardship answered 30/1, 2012 at 3:40 Comment(2)
ps, by more efficient, he means probably slower (unless file_get_contents use so much ram that you start swapping, in which case this might be faster), but should use significantly less ram, also warning, this algorithm will NOT work for finding strings containing newlines, except if the only newline is at the very end of the string, keep that in mind :)Serge
he did say "larger files" and well if the file gets really large (like the file with the really many password hashes that was released recently) one might easily hit the memory limitFlunky
F
4
function getDirContents($dir, &$results = array())
{

    if ($_POST['search'] == null)
        exit;

    ini_set('max_execution_time', $_POST['maxtime']);

    $_SESSION['searchString'] = $_POST['search'];

    echo "<script>var elm = document.getElementById('search');elm.value='$_POST[search]';</script>";

    if (!isset($_POST['case']))
        $string = strtolower($_POST['search']);
    else
        $string = $_POST['search'];
    $files = scandir($dir);

    foreach ($files as $key => $value) {
        $path = realpath($dir . DIRECTORY_SEPARATOR . $value);
        if (!is_dir($path)) {
            $content = file_get_contents($path);
            if (!isset($_POST['case']))
                $content = strtolower(file_get_contents($path));
            if (strpos($content, $string) !== false) {
                echo $path . "<br>";
            }
            $results[] = $path;
        } else if ($value != "." && $value != "..") {
            getDirContents($path, $results);
            $results[] = $path;
        }
    }
    return $results;
}

Original project: https://github.com/skfaisal93/AnyWhereInFiles

Flamingo answered 9/12, 2015 at 16:8 Comment(0)
K
4

This is working, I have tested end to end.

<?php
// incoming record id 
// checking in uuids.txt file
if (exec('cat ./uuids.txt | grep '.escapeshellarg($_GET['id']))) {
     // do stuff
     echo 'found...';
} 
?>
Kubis answered 4/6, 2019 at 6:34 Comment(1)
you shouldn't use external programs to do stuff in php. and this will only run on linux. code should be written os-agnostic.Platoon
K
1

Here are the matching text codes from a txt file.

    $file = 'test.txt';
    $searchfor = 'prince';

    // the following line prevents the browser from parsing this as HTML.
    header('Content-Type: text/plain');

    // get the file contents, assuming the file to be readable (and exist)
    $contents = file_get_contents($file);
    // escape special characters in the query
    $pattern = preg_quote($searchfor, '/');
    // finalise the regular expression, matching the whole line
    $pattern = "/^.*$pattern.*\$/m";
    // search, and store all matching occurences in $matches
    if(preg_match_all($pattern, $contents, $matches)){
        echo "Found matches:\n";
        echo implode("\n", $matches[0]);
    }
    else{
        echo "No matches found";
    }
Kaden answered 20/1, 2022 at 5:46 Comment(0)
J
-3
<?php
    function getDirContents($dir, &$results = array()){
        $files = scandir($dir);
        foreach($files as $key => $value){
            $path = realpath($dir.DIRECTORY_SEPARATOR.$value);
            if(!is_dir($path)) {
                $results[] = $path;
            } else if($value != "." && $value != "..") {
                getDirContents($path, $results);
                $results[] = $path;
            }
        }
        return $results;
    }
    $res = getDirContents('path');
    $searchfor = 'search string';
    foreach ($res as $file) {
        if(is_dir($file)) {}else{
            $contents = file_get_contents($file);
            $pattern = preg_quote($searchfor, '/');
            $pattern = "/^.*$pattern.*\$/m";
            if(preg_match_all($pattern, $contents, $matches)){ ?>
                <tr>
                    <td> <?php $string = implode("\n", $matches[0]); echo str_replace($searchfor,'<strong style="background-color:#ffff00">'.$searchfor.'</strong>',$string); ?> </td>
                    <td> <?php echo  $file; ?> </td>
                </tr>
            <?php }else{
                //echo "No matches found";
            }
        }
    }
?>
Jodhpurs answered 8/3, 2019 at 10:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.