2

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);
}
Jared Farrish
  • 48,585
  • 17
  • 95
  • 104
Rob Myrick
  • 859
  • 11
  • 28
  • 2
    Why is your indentation so messed up? Your code is not readable. – Lightness Races in Orbit Feb 25 '12 at 18:49
  • 1
    The way you're indenting (or, *not indenting*) code blocks is almost guaranteed to cause bugs, problems, etc. **ESPECIALLY** something like `if(long chain of checks){if(another long chain){doSomethingMurkyByTheTimeYouHaveGottenHere();}}` all on one line. This is a bad habit to get into. Separate your code into human-readable blocks of code. – Jared Farrish Feb 25 '12 at 18:55
  • Also: `if ((isset($query)) && (empty($query)))` should be (IMO) `if (isset($query) && empty($query))`. You don't need `()` around every condition clause. – Jared Farrish Feb 25 '12 at 18:58
  • Also, I took out the markup to make it easier to understand. – Jared Farrish Feb 25 '12 at 18:59
  • Hi Jared, the code is actually indented in my files, but I always have problems getting the code into this website. Is there a simpler way that I could copy/paste the code in one step? – Rob Myrick Feb 25 '12 at 19:08
  • I've run into that problem before, where the whitespace is collapsed (and I haven't figured out how to handle it per se). You might search for or raise an issue on http://meta.stackoverflow.com. – Jared Farrish Feb 25 '12 at 19:33

2 Answers2

3

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.
TigOldBitties
  • 1,331
  • 9
  • 15
  • Thanks, TigOldBitties...ha. I did have to add another ((isset($query)) conditional for it to wait for input, but your answer did the trick – Rob Myrick Feb 25 '12 at 19:01
  • I don't agree using `$_REQUEST` instead of `$_GET` or `$_POST`. There is a [reason to separate the two](http://stackoverflow.com/a/1924958/451969). In other words, `GET` requests should provide a resource, and `POST` should conduct some type of deterministic action (`INSERT`, `DELETE`, etc.). Would you allow a login to come through `GET`? This would be a so-called "special reason", but IMO it's better to understand why each exist and not rely on a crutch like `$_REQUEST` except when fully understood. – Jared Farrish Feb 25 '12 at 19:28
  • Obviously there is a reason for separating the two. But in this case it does not apply. Hence the recomandation. – TigOldBitties Feb 25 '12 at 19:37
1

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.

raina77ow
  • 103,633
  • 15
  • 192
  • 229