如何确定文件文本搜索是否返回不匹配?

I have created a piece of code that checks files for a user-submitted string within a set of files. The code searches a directory, returns the file, then searches for the string in the file. The user will input the custom string through an input field and then clicking a submit button.

I have successfully been able to create a condition where, if the user does not enter any information, the output will say, "Your search produced no results". However, I have not been able to figure out how to create a condition where, if the user enters a string that isn't found within the files, that the output will also be, "Your search produced no results".

The code for the existing conditional I have as of now is this:

if ((isset($query)) && (empty($query))) {
    echo "Your search produced no results";
}

The code that searches for the files and also searches for the string is found here (this is the entire PHP file, actually, and it includes the conditional I posted above.) I need help on how to create another conditional that throws a message if the user-input isn't found in any of the files.

If this seems unclear, I apologize and will clarify any information you need if you think it will help.

Calling Code

$query = $_POST['query'];

if ((isset($query)) && (empty($query))) {
    echo "Your search produced no results.";

}
else {
    find_files('.');
}

find_files()

function find_files($seed)
{
    if (! is_dir($seed))
        return false;

    $files = array();
    $dirs = array($seed);

    while(NULL !== ($dir = array_pop($dirs)))
    {
        if($dh = opendir($dir))
        {
            while( false !== ($file = readdir($dh)))
            {
                if($file == '.' || $file == '..') continue;

                $path = $dir . '/' . $file;

                if (is_dir($path)) {
                    $dirs[] = $path;
                }
                else {
                    if (preg_match('/^.*\.(php[\d]?|js|txt)$/i', $path)) { 
                        check_files($path);
                    }
                }
            }
        }

        closedir($dh);
    }
}

check_files()

function check_files($this_file) 
{
    $query = $_POST['query'];

    $str_to_find = $query;

    if(!($content = file_get_contents($this_file))) {
        echo("Could not check $this_file");
    }
    else {
        if (stristr($content, $str_to_find)) {
            echo("$this_file -> contains $str_to_find");
        }
    }

    unset($content);
}

If the query is not empty the find_files function is simply executed with no instructions of doing something if it returns false, hence you need to evaluate the result of calling find_files. For example you could do:

if ((isset($query)) && (empty($query))) {
    echo "<p style=\"color:darkgray; font-family:arial\">Your search produced no results</p>";
}
elseif (!find_files('.'))
{
    echo "<p style=\"color:darkgray; font-family:arial\">Your search produced no results</p>";
}

with the condition that you update you find_files function to return false for all cases that fail.

or you could update the find_files function to return a string in case of errors and a string empty for succesful execution

if ((isset($query)) && (empty($query))) {
    echo "<p style=\"color:darkgray; font-family:arial\">Your search produced no results</p>";
}
else 
{
    $result = find_files('.');
    if (!empty($result))
    {
        echo "<p style=\"color:darkgray; font-family:arial\">".$result."</p>";
    }
}

A couple of notes regarding your code that will improve the readability and code quality:

  • proper indentation will save a lot of time spent in maintenance;
  • when using if else imbrications ALWAYS use curly braces even if it is only one instructions. Improves readability and avoids errors.
  • when accessing a variable declared outside a function (in procedural code) use global keyword. For example for accessing the query variable inside the check_files function use global $query; instead of retrieving the variable again from the post.
  • use $_REQUEST instead of $_POST or $_GET unless there is a special reason for doing otherwise. Unifies code, makes for more readable code and changing from GET to POST or vice-versa can be done without changing code.

You may make your find_files function to return a boolean value: true if at least one matching file was found, false otherwise. Then update your if condition:

if ((isset($query)) && (empty($query)) && !find_files('.')) {
    echo "<p style=\"color:darkgray...";
}

Because && is lazily evaluated, find_files will be called only if $query isn't empty.