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.

EGormlyAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

MMDeveloperCommented:
Before someone starts posting suggestions, what version of PHP and what platform (unix, windows, etc)?
0
EGormlyAuthor Commented:
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)
0
MMDeveloperCommented:
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

0
Starting with Angular 5

Learn the essential features and functions of the popular JavaScript framework for building mobile, desktop and web applications.

EGormlyAuthor Commented:
it returned..

Array ( )
0
MMDeveloperCommented:
what did you replace this line with

$searchFiles->doSearch('C:\Inetpub\wwwroot', "te");
0
EGormlyAuthor Commented:
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.
0
MMDeveloperCommented:
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

0
MMDeveloperCommented:
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

0
EGormlyAuthor Commented:
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 ( ) )
0
MMDeveloperCommented:
I'm so sorry, this has been such a sloppy post for me. I'd been trying to make this code untested but now that I run the code after modifications I see small issues with it. Unless this code below you have a problem with, this is my last version.
<?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: " . $file . "<br />";
                $fp = fopen($file, "r");
                if (!$fp) {
                        $this->log[] = "I was not permitted to open file: " . $file . "<br />";
                }
                else {
                        $this->log[] = "attempting to read file: " . $file . "<br />";
                        $contents = fread($fp, filesize($file));
                        fclose($fp);
 
                        if (!$contents) {
                                $this->log[] = "I was not permitted to read the file: " . $file . "<br />";
                        }
                        else {
                                $this->log[] = "searching file contents: " . $file . "<br />";
                                if (eregi($this->stringMatch, $contents)) {
                                        $this->log[] = "match!: " . $file . "<br />";
                                        $this->results[] = $file;
                                }
                                else {
                                        $this->log[] = "no matches in file: " . $file . "<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";
}
?>

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
MMDeveloperCommented:
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.
0
EGormlyAuthor Commented:
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!!


0
EGormlyAuthor Commented:
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!
0
EGormlyAuthor Commented:
opps I forgot to ask how to send this page the variable to search on...
should I ask a new question?
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
PHP

From novice to tech pro — start learning today.