• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 277
  • Last Modified:

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.

0
EGormly
Asked:
EGormly
  • 7
  • 7
1 Solution
 
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

  • 7
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now