Source for file Find.php
Documentation is available at Find.php
// +----------------------------------------------------------------------+
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2005 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Author: Sterling Hughes <sterling@php.net> |
// +----------------------------------------------------------------------+
define('FILE_FIND_VERSION', '@package_version@');
// to debug uncomment this string
// define('FILE_FIND_DEBUG', '');
* Commonly needed functions searching directory trees
* @author Sterling Hughes <sterling@php.net>
* Search specified directory to find matches for specified pattern
* @param string $pattern a string containing the pattern to search
* @param string $dirpath a string containing the directory path
* @param string $pattern_type a string containing the type of
* pattern matching functions to use (can either be 'php',
* @return array containing all of the files and directories
* matching the pattern or null if no matches
* @author Sterling Hughes <sterling@php.net>
function &glob($pattern, $dirpath, $pattern_type = 'php')
$pe = PEAR ::raiseError (" Cannot open directory $dirpath" );
$match_function = File_Find::_determineRegex ($pattern, $pattern_type);
// empty string cannot be specified for 'php' and 'perl' pattern
if ($pattern || ($pattern_type != 'php' && $pattern_type != 'perl')) {
while (false !== ($entry = @readdir($dh))) {
if ($match_function($pattern, $entry) &&
$entry != '.' && $entry != '..') {
if (0 == count($matches)) {
* Map the directory tree given by the directory_path parameter.
* @param string $directory contains the directory path that you
* @return array a two element array, the first element containing a list
* of all the directories, the second element containing a list of all the
* @author Sterling Hughes <sterling@php.net>
/* if called statically */
if (!isset ($this) || !is_a($this, "File_Find")) {
return $obj->maptree ($directory);
/* clear the results just in case */
/* strip out trailing slashes */
$this->_dirs = array ($directory);
while (count($this->_dirs)) {
* Map the directory tree given by the directory parameter.
* @param string $directory contains the directory path that you
* @param integer $maxrecursion maximun number of folders to recursive
* @return array a multidimensional array containing all subdirectories
* and their files. For example:
* @author Mika Tuupola <tuupola@appelsiini.net>
/* strip trailing slashes */
while (false !== ($entry = @readdir($dh))) {
if ($entry != '.' && $entry != '..') {
while (list ($key, $val) = each($retval)) {
$path = $directory . "/" . $val;
if ($maxrecursion == 0 || $count < $maxrecursion) {
* Search the specified directory tree with the specified pattern. Return
* an array containing all matching files (no directories included).
* @param string $pattern the pattern to match every file with.
* @param string $directory the directory tree to search in.
* @param string $type the type of regular expression support to use, either
* 'php', 'perl' or 'shell'.
* @param bool $fullpath whether the regex should be matched against the
* full path or only against the filename
* @param string $match can be either 'files', 'dirs' or 'both' to specify
* the kind of list to return
* @return array a list of files matching the pattern parameter in the the
* directory path specified by the directory parameter
* @author Sterling Hughes <sterling@php.net>
function &search($pattern, $directory, $type = 'php', $fullpath = true , $match = 'files')
unset ($files, $directories);
$match_function = File_Find::_determineRegex ($pattern, $type);
// check if empty string given (ok for 'shell' method, but bad for others)
if ($pattern || ($type != 'php' && $type != 'perl')) {
while (list (,$entry) = each($data)) {
if ($match_function($pattern,
$fullpath ? $entry : basename($entry))) {
* Determine whether or not a variable is a PEAR error
* @param object PEAR_Error $var the variable to test.
* @return boolean returns true if the variable is a PEAR error, otherwise
return PEAR ::isError ($var);
* internal function to build singular directory trees, used by
* @param string $directory name of the directory to read
* @param string $separator directory separator
function _build ($directory, $separator = "/")
$pe = PEAR ::raiseError ("Cannot open directory");
while (false !== ($entry = @readdir($dh))) {
if ($entry != '.' && $entry != '..') {
$entry = $directory. $separator. $entry;
* internal function to determine the type of regular expression to
* use, implemented by File_Find::glob() and File_Find::search()
* @param string $type given RegExp type
* @return string kind of function ( "eregi", "ereg" or "preg_match") ;
function _determineRegex ($pattern, $type)
$match_function = 'File_Find_match_shell';
$match_function = 'preg_match';
$match_function = 'eregi';
$match_function = 'ereg';
* Package method to match via 'shell' pattern. Provided in global
* scope, because it should be called like 'preg_match' and 'eregi'
* and can be easily copied into other packages
* @author techtonik <techtonik@php.net>
* @return mixed bool on success and PEAR_Error on failure
// {{{ convert pattern to positive and negative regexps
PEAR ::raiseError ("Mask string contains errors!");
list ($positive, $negative) = explode("|", $pattern);
PEAR ::raiseError ("File-mask string contains errors!");
print (" Method: $type\nPattern: $pattern\n Converted pattern:" );
if (isset ($negative)) print_r($negative);
* function used by File_Find_match_shell to convert 'shell' mask
* into pcre regexp. Some of the rules (see testcases for more):
* escaping all special chars and replacing
* also adding ^ and $ as the pattern matches whole filename
* @author techtonik <techtonik@php.net>
* @return string pcre regexp for preg_match
// get array of several masks (if any) delimited by comma
// do not touch commas in char class
$premasks = preg_split("|(\[[^\]]+\])|", $mask, -1 , PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY );
foreach($premasks as $pm) {
if (!isset ($masks[$pi])) $masks[$pi] = "";
if ($pm{0 } == '[' && $pm{strlen($pm)-1 } == ']') {
// strip commas from character class
// if empty string given return *.* pattern
if (strlen($mask) == 0 ) return "!^.*$!";
// convert to preg regexp
print (" regexMask step one(implode): $regexmask" );
print (" \nregexMask step two(addcslashes): $regexmask" );
print (" \nregexMask step three(* ? -> .* .?): $regexmask" );
// a special case '*.' at the end means that there is no extension
$regexmask = preg_replace("!\.\*\\\.(\||$)!", "[^\.]*$1", $regexmask);
// it is impossible to have dot at the end of filename
$regexmask = preg_replace("!\\\.(\||$)!", "$1", $regexmask);
// and .* at the end also means that there could be nothing at all
// (i.e. no dot at the end also)
$regexmask = preg_replace("!\\\.\.\*(\||$)!", "(\\\\..*)?$1", $regexmask);
print (" \nregexMask step two and half(*.$ \\..*$ .$ -> [^.]*$ .?.* $): $regexmask" );
// if no extension supplied - add .* to match partially from filename start
if (strpos($regexmask, "\\.") === FALSE ) $regexmask .= ".*";
// file mask match whole name - adding restrictions
$regexmask = preg_replace("!(\|)!", '^'. "$1". '$', $regexmask);
$regexmask = '^'. $regexmask. '$';
print (" \nregexMask step three(^ and $ to match whole name): $regexmask" );
// wrap regex into ! since all ! are already escaped
$regexmask = " !$regexmask!i";
print (" \nWrapped regex: $regexmask\n" );
Documentation generated on Mon, 11 Mar 2019 15:56:37 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|