Link to home
Start Free TrialLog in
Avatar of EGormly
EGormlyFlag for United States of America

asked on

Simple PHP local directory text file search

I have  "IceWarp" running on my email server and I need a simple php script that will search selected directories full of text files and return results as text file links (links to the text file)

I know it sounds simple, but I can't seem to find anything of use that is not a search engine (google) or MySQL based solution. I cannot install MySQL so database indexing is out...

I only need the script to check text files for word matches and display them.
It would be nice if it had a cache but it is not needed.

The script needs to be able to check multiple directories and subdirectories.
I can create this in about 5 minutes in VBScript, but unfortunately I know nothing of php and my hands are tied on what to use.

Avatar of MMDeveloper
MMDeveloper
Flag of United States of America image

Before someone starts posting suggestions, what version of PHP and what platform (unix, windows, etc)?
Avatar of EGormly

ASKER

windows... it's running the latest versionof IceWarp.. as far as PHP I am not sure most lilkey the latest version (or the most recent to the latest)
this runs fine on a windows server we have at work here.

it recursively searches "C:\Inetput\wwwroot" for all .txt files containing the case-insensitive string "te"
<?php
$searchFiles = new searchFiles();
$searchFiles->doSearch('C:\Inetpub\wwwroot', "te");
print_r($searchFiles->results);
 
class searchFiles {
 
	private $baseDir		= "";
	private $stringMatch		= "";
	public  $results		= array();
 
	public function searchFiles() {
		//sit pretty
	}
 
	public function doSearch($baseDir, $stringMatch) {
		$this->baseDir = $baseDir;
		$this->stringMatch = $stringMatch;
 
		$this->traverseDirectory($baseDir);
	}
 
	private function traverseDirectory($dir) {
		$ignore = array (
				".",
				".."
			);
		$d = dir($dir);
		while (($entry = $d->read()) !== false) {
			if (!in_array($entry, $ignore)) {
				$ePath = $d->path . "\\" . $entry;
				if (is_file($entry)) {
 
					if (eregi(".txt", $entry)) {
						$this->searchFile($ePath);
					}
				}
				elseif (is_dir($entry)) {
					$this->traverseDirectory($ePath);
				}
				else {}
			}
		}
	}
 
	private function searchFile($file) {
		$fp = fopen($file, "r");
		$contents = fread($fp, filesize($file));
		fclose($fp);
 
		if (eregi($this->stringMatch, $contents)) {
			$this->results[] = $file;
		} else {}
		unset($contents);
	}
}
?>

Open in new window

Avatar of EGormly

ASKER

it returned..

Array ( )
what did you replace this line with

$searchFiles->doSearch('C:\Inetpub\wwwroot', "te");
Avatar of EGormly

ASKER

just a folder that had some text files.. I changed "te" to "the" to make sure I would get a result.

$searchFiles->doSearch('C:\Program Files\ProgramMaker\MailServer\mail\mywebsite.com\user\inbox', "the");

That folder is valid and was copied directly from explorer toolbar.
Is it an execute issue?  I would imagine an error would return an error and a result would have beem formatted differently.

Just coming back as :
Array ( )

and nothing else is extremley odd.. no?

I also tried changing it to a new folder with two test text files both containing the key word.
$searchFiles->doSearch('C:\inbox', "the");

and I got the same result.
ok I put some debugging info in this one... see what this one says.

can you paste the output here (or attach as a .txt file)?
<?php
class searchFiles {
 
        private $baseDir                = "";
        private $stringMatch            = "";
        public  $results                = array();
 
        public function searchFiles() {
                //sit pretty
        }
 
        public function doSearch($baseDir, $stringMatch) {
                $this->baseDir = $baseDir;
                $this->stringMatch = $stringMatch;
 
                $this->traverseDirectory($baseDir);
        }
 
        private function traverseDirectory($dir) {
                $ignore = array (
                                ".",
                                ".."
                        );
                $d = dir($dir);
                while (($entry = $d->read()) !== false) {
			echo "looking at entry: " . $entry . "<br />";
                        if (!in_array($entry, $ignore)) {
                                $ePath = $d->path . "\\" . $entry;
				echo "created path: " . $ePath . "<br />";
                                if (is_file($entry)) {
					echo $entry . " is a file<br />";
                                        if (eregi(".txt", $entry)) {
                                                $this->searchFile($ePath);
                                        }
                                }
                                elseif (is_dir($entry)) {
					echo $entry . " is a directory<br />";
                                        $this->traverseDirectory($ePath);
                                }
                                else {}
                        }
                }
        }
 
        private function searchFile($file) {
		echo "attempting to open file: " . $entry . "<br />";
                $fp = fopen($file, "r");
		if (!$fp) {
			echo "I was not permitted to open file: " . $entry . "<br />";
		}
		else {
			echo "attempting to read file: " . $entry . "<br />";
			$contents = fread($fp, filesize($file));
			fclose($fp);
			
			if (!$contents) {
				echo "I was not permitted to read the file: " . $entry . "<br />";
			}
			else {
				echo "searching file contents: " . $entry . "<br />";
				if (eregi($this->stringMatch, $contents)) {
					echo "match!: " . $entry . "<br />";
					$this->results[] = $file;
				} 
				else {
					echo "no matches in file: " . $entry . "<br />";
				}
				unset($contents);
			}
		}
        }
}
 
$searchFiles = new searchFiles();
$searchFiles->doSearch('C:\Inbox', "the");
 
 
if (count($searchFiles->results) > 0) {
	echo "<ol>";
	foreach ($searchFiles->results as $k => $v) {
		echo '<li><a href="' . $v . '">' . $v . "</a></li>\n";
	}
	echo "</ol>";
}
else {
	echo "no results";
}
 
print_r($searchFiles);
?>

Open in new window

ok I see what happened... below is a fixed version...

I had an idea during making the last half of my original code and failed to update a function to reflect the code change.
<?php
class searchFiles {
 
        private $baseDir                = "";
        private $stringMatch            = "";
        public  $results                = array();
	public 	$log			= array();
 
        public function searchFiles() {
                //sit pretty
        }
 
        public function doSearch($baseDir, $stringMatch) {
                $this->baseDir = $baseDir;
                $this->stringMatch = $stringMatch;
 
                $this->traverseDirectory($baseDir);
        }
 
        private function traverseDirectory($dir) {
                $ignore = array (
                                ".",
                                ".."
                        );
                $d = dir($dir);
                while (($entry = $d->read()) !== false) {
                        $this->log[] = "looking at entry: " . $entry . "<br />";
                        if (!in_array($entry, $ignore)) {
                                $ePath = $d->path . $entry;
                                $this->log[] = "created path: " . $ePath . "<br />";
                                if (is_file($ePath)) {
                                        $this->log[] = $entry . " is a file<br />";
                                        if (eregi(".txt", $entry)) {
                                                $this->searchFile($ePath);
                                        }
                                }
                                elseif (is_dir($ePath)) {
                                        $this->log[] = $entry . " is a directory<br />";
                                        $this->traverseDirectory($ePath);
                                }
                                else {}
                        }
                }
        }
 
        private function searchFile($file) {
                $this->log[] = "attempting to open file: " . $entry . "<br />";
                $fp = fopen($file, "r");
                if (!$fp) {
                        $this->log[] = "I was not permitted to open file: " . $entry . "<br />";
                }
                else {
                        $this->log[] = "attempting to read file: " . $entry . "<br />";
                        $contents = fread($fp, filesize($file));
                        fclose($fp);
 
                        if (!$contents) {
                                $this->log[] = "I was not permitted to read the file: " . $entry . "<br />";
                        }
                        else {
                                $this->log[] = "searching file contents: " . $entry . "<br />";
                                if (eregi($this->stringMatch, $contents)) {
                                        $this->log[] = "match!: " . $entry . "<br />";
                                        $this->results[] = $file;
                                }
                                else {
                                        $this->log[] = "no matches in file: " . $entry . "<br />";
                                }
                                unset($contents);
                        }
                }
        }
}
 
$searchFiles = new searchFiles();
$searchFiles->doSearch('C:\\', "the");
 
 
if (count($searchFiles->results) > 0) {
        echo "<ol>";
        foreach ($searchFiles->results as $k => $v) {
                echo '<li><a href="' . $v . '">' . $v . "</a></li>\n";
        }
        echo "</ol>";
}
else {
        echo "no results";
}
?>

Open in new window

Avatar of EGormly

ASKER

Results:

looking at entry: .
looking at entry: ..
looking at entry: 200809231018285919-00000002.txt
created path: C:\Inbox\200809231018285919-00000002.txt
looking at entry: 200809240951057314-00000002.txt
created path: C:\Inbox\200809240951057314-00000002.txt
looking at entry: 200810021029294444-00000002.txt
created path: C:\Inbox\200810021029294444-00000002.txt
looking at entry: 200810031516338396-00000002.txt
created path: C:\Inbox\200810031516338396-00000002.txt
looking at entry: subfolder
created path: C:\Inbox\subfolder
no resultssearchFiles Object ( [baseDir:private] => C:\Inbox [stringMatch:private] => the [results] => Array ( ) )


There are definately many "the" in the text files.
I also changed it to reflect other manually found (and placed) words and I don't get anything.

Also, there is a subfolder called "subfolder" that has text files with the search word and that doesn't show like the root folder does.

Note: i get these reults without a subfolder:

looking at entry: .
looking at entry: ..
looking at entry: 200809231018285919-00000002.txt
created path: C:\Inbox\200809231018285919-00000002.txt
looking at entry: 200809240951057314-00000002.txt
created path: C:\Inbox\200809240951057314-00000002.txt
looking at entry: 200810021029294444-00000002.txt
created path: C:\Inbox\200810021029294444-00000002.txt
looking at entry: 200810031516338396-00000002.txt
created path: C:\Inbox\200810031516338396-00000002.txt
no resultssearchFiles Object ( [baseDir:private] => C:\Inbox [stringMatch:private] => the [results] => Array ( ) )
ASKER CERTIFIED SOLUTION
Avatar of MMDeveloper
MMDeveloper
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
what had happened was originally it was using


is_file($entry) however I later built a 'path' and called it $ePath but failed ot update the 2 if statements to use ePath, so it would find the first level files/folders but wouldn't traverse them or search them.


I dont know what the deal is with me today, I usually nail it on the head on the first or second go'round. I'm so ashamed, heh.
Avatar of EGormly

ASKER

why in the world would you apologize...
This is AWESOME, you are saving me a dozen or so hours with my kids....

Thank you so much!!


Avatar of EGormly

ASKER

Fantastic Solution, better than I'd hoped for.
Works great and I can tweak it for other stuff.

A great addition to my personal library!
Avatar of EGormly

ASKER

opps I forgot to ask how to send this page the variable to search on...
should I ask a new question?