EGormly
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.
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.
Before someone starts posting suggestions, what version of PHP and what platform (unix, windows, etc)?
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"
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);
}
}
?>
ASKER
it returned..
Array ( )
Array ( )
what did you replace this line with
$searchFiles->doSearch('C: \Inetpub\w wwroot', "te");
$searchFiles->doSearch('C:
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\MailSer ver\mail\m ywebsite.c om\user\in box', "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.
$searchFiles->doSearch('C:
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:
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)?
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);
?>
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.
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";
}
?>
ASKER
Results:
looking at entry: .
looking at entry: ..
looking at entry: 200809231018285919-0000000 2.txt
created path: C:\Inbox\20080923101828591 9-00000002 .txt
looking at entry: 200809240951057314-0000000 2.txt
created path: C:\Inbox\20080924095105731 4-00000002 .txt
looking at entry: 200810021029294444-0000000 2.txt
created path: C:\Inbox\20081002102929444 4-00000002 .txt
looking at entry: 200810031516338396-0000000 2.txt
created path: C:\Inbox\20081003151633839 6-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-0000000 2.txt
created path: C:\Inbox\20080923101828591 9-00000002 .txt
looking at entry: 200809240951057314-0000000 2.txt
created path: C:\Inbox\20080924095105731 4-00000002 .txt
looking at entry: 200810021029294444-0000000 2.txt
created path: C:\Inbox\20081002102929444 4-00000002 .txt
looking at entry: 200810031516338396-0000000 2.txt
created path: C:\Inbox\20081003151633839 6-00000002 .txt
no resultssearchFiles Object ( [baseDir:private] => C:\Inbox [stringMatch:private] => the [results] => Array ( ) )
looking at entry: .
looking at entry: ..
looking at entry: 200809231018285919-0000000
created path: C:\Inbox\20080923101828591
looking at entry: 200809240951057314-0000000
created path: C:\Inbox\20080924095105731
looking at entry: 200810021029294444-0000000
created path: C:\Inbox\20081002102929444
looking at entry: 200810031516338396-0000000
created path: C:\Inbox\20081003151633839
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-0000000
created path: C:\Inbox\20080923101828591
looking at entry: 200809240951057314-0000000
created path: C:\Inbox\20080924095105731
looking at entry: 200810021029294444-0000000
created path: C:\Inbox\20081002102929444
looking at entry: 200810031516338396-0000000
created path: C:\Inbox\20081003151633839
no resultssearchFiles Object ( [baseDir:private] => C:\Inbox [stringMatch:private] => the [results] => Array ( ) )
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
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.
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!!
This is AWESOME, you are saving me a dozen or so hours with my kids....
Thank you so much!!
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!
Works great and I can tweak it for other stuff.
A great addition to my personal library!
ASKER
opps I forgot to ask how to send this page the variable to search on...
should I ask a new question?
should I ask a new question?