30-03-2005, 14:00
|
#2 (permalink)
|
|
Barney army!
Join Date: Mar 2003
Location: London
Posts: 692
|
I've had a bit of spare time, so here's a nice class that encapsulates what you want to do (feel free to reuse it wherever you like). It looks lengthier than it is because of the comments and doc tags but these should help you understand the class.
I've broken down the functionality so you can provide a file to search (and it will just search for the search string in that file), or a directory, in which case it will recursively scan through the directory and sub-directories and look for the search term in each file it finds.
PHP Code:
/**
* FileSystemStringSearch
* Searches a file or directory of files for a search string
*/
class FileSystemStringSearch
{
// MEMBERS
/**
* @var string $_searchPath path to file/directory to search
*/
var $_searchPath;
/**
* @var string $_searchString the string to search for
*/
var $_searchString;
/**
* @var array $_searchResults holds search result information
*/
var $_searchResults;
// CONSTRUCTOR
/**
* Class constructor
* @param string $searchPath path to file or directory to search
* @param string $searchString string to search for
* @return void
*/
function FileSystemStringSearch($searchPath, $searchString)
{
$this->_searchPath = $searchPath;
$this->_searchString = $searchString;
$this->_searchResults = array();
}
// MANIPULATORS
/**
* Checks path is valid
* @return bool
*/
function isValidPath()
{
if(file_exists($this->_searchPath)) {
return true;
} else {
return false;
}
}
/**
* Determines if path is a file or directory
* @return bool
*/
function searchPathIsFile()
{
// check for trailing slash
if(substr($this->_searchPath, -1, 1)=='/' ||
substr($this->_searchPath, -1, 1)=='\\') {
return false;
} else {
return true;
}
}
/**
* Searches given file for search term
* @param string $file the file path
* @return void
*/
function searchFileForString($file)
{
// open file to an array
$fileLines = file($file);
// loop through lines and look for search term
$lineNumber = 1;
foreach($fileLines as $line) {
$searchCount = substr_count($line, $this->_searchString);
if($searchCount > 0) {
// log result
$this->addResult($file, $line, $lineNumber, $searchCount);
}
$lineNumber++;
}
}
/**
* Adds result to the result array
* @param string $lineContents the line itself
* @param int $lineNumber the file line number
* @param int $searchCount the number of occurances of the search term
* @return void
*/
function addResult($filePath, $lineContents, $lineNumber, $searchCount)
{
$this->_searchResults[] = array('filePath' => $filePath,
'lineContents' => $lineContents,
'lineNumber' => $lineNumber,
'searchCount' => $searchCount);
}
/**
* Takes a given string (usually a line from search results)
* and highlights the search term
* @param string $string the string containing the search term(s)
* @return string
*/
function highlightSearchTerm($string)
{
return str_replace($this->_searchString,
'<strong>'.$this->_searchString.'</strong>',
$string);
}
/**
* Recursively scan a folder and sub folders for search term
* @param string path to the directory to search
* @return void
*/
function scanDirectoryForString($dir)
{
$subDirs = array();
$dirFiles = array();
$dh = opendir($dir);
while(($node = readdir($dh)) !== false) {
// ignore . and .. nodes
if(!($node=='.' || $node=='..')) {
if(is_dir($dir.$node)) {
$subDirs[] = $dir.$node.'/';
} else {
$dirFiles[] = $dir.$node;
}
}
}
// loop through files and search for string
foreach($dirFiles as $file) {
$this->searchFileForString($file);
}
// if there are sub directories, scan them
if(count($subDirs) > 0) {
foreach($subDirs as $subDir) {
$this->scanDirectoryForString($subDir);
}
}
}
/**
* Run the search
* @return void
*/
function run()
{
// check path exists
if($this->isValidPath()) {
if($this->searchPathIsFile()) {
// run search on the file
$this->searchFileForString($this->_searchPath);
} else {
// scan directory contents for string
$this->scanDirectoryForString($this->_searchPath);
}
} else {
die('FileSystemStringSearch Error: File/Directory does not exist');
}
}
// ACCESSORS
function getResults()
{
return $this->_searchResults;
}
function getResultCount()
{
$count = 0;
foreach($this->_searchResults as $result) {
$count += $result['searchCount'];
}
return $count;
}
function getSearchPath()
{
return $this->_searchPath;
}
function getSearchString()
{
return $this->_searchString;
}
}
Here's some example usage:
PHP Code:
$searcher = new FileSystemStringSearch('/path/to/some/file/or/directory/', 'somesearchterm');
$searcher->run();
if($searcher->getResultCount() > 0) {
echo('<p>Searched "'.$searcher->getSearchPath().'" for string <strong>"'.$searcher->getSearchString().'":</strong></p>');
echo('<p>Search term found <strong>'.$searcher->getResultCount().' times.</strong></p>');
echo('<ul>');
foreach($searcher->getResults() as $result) {
echo('<li><em>'.$result['filePath'].', line '.$result['lineNumber'].'</em>:<br />
'.$searcher->highlightSearchTerm($result['lineContents']).'</li>');
}
echo('</ul>');
} else {
echo('<p>Searched "'.$searcher->getSearchPath().'" for string <strong>"'.$searcher->getSearchString().'":</strong></p>');
echo('<p>No results returned</p>');
}
Just one thing to remember...to search through a directory, make sure the directory path has a trailing slash (or the class will think its a file).
Hope that helps.
__________________
Last edited by Luke Redpath : 31-03-2005 at 02:37.
|
|
|
|