|
 |
glob (PHP 4 >= 4.3.0, PHP 5) glob -- Находит файловые пути, совпадающие с шаблоном Описаниеarray glob ( string pattern [, int flags] )
Функция glob() ищет все пути, совпадающие с шаблоном
pattern согласно правилам, используемым
в функции glob() библиотеки libc, которые похожи на правила, используемые
большинством распространённых оболочек. Раскрытие тильды или подстановки
параметров не совершаются.
Возвращает массив, который содержит совпадающие файлы/директории или
FALSE в случае ошибки.
Допустимые флаги:
GLOB_MARK - Добавляет слеш к каждому возвращаемому
предмету
GLOB_NOSORT - Возвращает файлы в таком виде, в
котором они содержатся в директории (без сортировки)
GLOB_NOCHECK - Возвращает шаблон поиска, если
с его помощью не был найден ни один файл.
GLOB_NOESCAPE - Обратные слеши не экранируют
метасимволы
GLOB_BRACE - Раскрывает {a,b,c} для совпадения с
'a', 'b' или 'c'
GLOB_ONLYDIR - Возвращает только директории,
совпадающие с шаблоном
Замечание:
В версиях ниже PHP ниже 4.3.3 GLOB_ONLYDIR был
не
доступен в Windows и других системах, не использующих библиотеку GNU C.
Пример 1.
Удобный способ, как при помощи glob() можно заменить
opendir() и её друзей.
<?php
foreach (glob("*.txt") as $filename) {
echo "$filename size " . filesize($filename) . "\n";
}
?>
|
Результат будет примерно таким:
funclist.txt size 44686
funcsummary.txt size 267625
quickref.txt size 137820 |
|
Замечание: Эта функция не применима для
работы с удаленными файлами, поскольку
файл должен быть доступен через файловую систему сервера.
См. также описание функций opendir(),
readdir(),
closedir() и fnmatch().
glob
c_windows_temp at hotmail dot com
06-Jun-2006 04:53
Note that this function does not list broken symbolic links.
ny_obaATgmxDOTnet
03-Apr-2006 08:51
Case insensitive version of this function for mswin:
// only supported flags are GLOB_NOSORT | GLOB_ONLYDIR
function iglob($pattern, $flags)
{
$path = preg_split(
'#(?<=\A|[\\\\/])((?>[^\\\\/*?]*)[*?](?>[^\\\\/]*))(?=\Z|[\\\\/])#',
$pattern, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
);
foreach ($path as &$n)
if (preg_match('/[*?]/', $n))
{
$re = '';
for ($i = 0, $l = strlen($n); $i < $l; $i++)
switch($n{$i})
{
case '*': $re .= '.*'; break;
case '?': $re .= '.'; break;
default: $re .= sprintf('\x%02x', ord($n{$i}));
}
$n = array(0, "/^$re$/i");
}
else
$n = array(1, $n);
$res = array();
iglob_DFS($path, $flags, '', 0, $res);
if (!($flags & GLOB_NOSORT))
sort($res);
return $res;
}
function iglob_DFS($path, $flags, $parent, $lvl, &$res)
{
$depth = count($path) - 1;
if (($lvl < $depth) && $path[$lvl][0])
$parent .= $path[$lvl++][1];
$files = array();
if ($path[$lvl][0])
$files[] = $path[$lvl][1];
else
if ($d = @opendir(($parent == '') ? '.' : $parent))
{
while (($n = readdir($d)) !== false)
if ($n != '.' && $n != '..')
$files[] = $n;
closedir($d);
}
foreach ($files as $f)
if ($path[$lvl][0] || preg_match($path[$lvl][1], $f))
{
$fullpath = $parent.$f;
if ($lvl == $depth)
{
if (!($flags & GLOB_ONLYDIR) || is_dir($fullpath))
$res[] = $fullpath;
}
else
iglob_DFS($path, $flags, $fullpath, $lvl + 1, $res);
}
}
edogs [at] dogsempire.com
03-Mar-2006 05:34
funny enough, but our testing opendir VS glob
show advantage of opendir by speed
0.00115704536438
and
0.0068039894104
or if to pass 200 times
0.210277080536
vs
1.2976038456
info at urbits dot com
06-Jan-2006 04:26
I have been working towards a CMS-type design that is both modular and quite flat. For example, included files are all one level below the installation folder.
glob() just help me get rid of a lot of opendir() hassle. I wasn't sure if the double asterix would work - but it's fine:
foreach (glob(SERVER_PATH."/*/includes/*.php") as $inc) {
require($inc);
}
admiral [at] nuclearpixel [dot] com
23-Nov-2005 08:38
I've written a function that I've been using quite a lot over the past year or so. I've built whole websites and their file based CMSs based on this one function, mostly because (I think) databases are not as portable as groups of files and folders. In previous versions, I used opendir and readdir to get contents, but now I can do in one line what used to take several. How? Most of the work in the whole script is done by calling
glob("$dir/*")
Giving me an array containing the names of the items in the folder, minus the ones beginning with '.', as well as the ones I specify.
<?php
function alpharead3($dir){
if(!$dir){$dir = '.';}
foreach(glob("$dir/*") as $item){$sort[]= end(explode('/',$item));}
$killit = array('index.html', 'index.php', 'thumbs.db', 'styles.css');
$killcounter = 0;
foreach($sort as $sorteditem){
foreach($killit as $killcheck){
if(strtolower($sorteditem) == strtolower($killcheck))
{unset($sort[$killcounter]);}
}$killcounter++;}
if($sort){natsort($sort);}
foreach($sort as $item){$return[]= $item;}
if(!$return){return array();}
return $return;
}
$folder = 'images';
foreach(alpharead3($folder) as $item)
{
echo '<img src="'.$folder.'/'.$item.'"><br>'.$item."\n";
}
?>
Commens on this function are welcome!
27-Oct-2005 12:27
in the example below, i found i got an error if the directory was empty or the directory do not exists.
<?php
foreach (glob("*.txt") as $filename) {
echo "$filename size " . filesize($filename) . "\n";
}
?>
My solution has:
$arrayFiles=glob('c:\text\*.*');
if($arrayFiles){
foreach ($arrayFiles as $filename) {
echo "$filename size <br>";
}
}
else
echo"File not found."
Jacob Eisenberg
05-Oct-2005 10:55
Note that on Windows, glob distinguishes between uppercase and lowercase extensions, so if the directory contains a file "test.txt" and you glob for "*.TXT" then the file will not be found!
That bug only happens when you use patterns containing "*", like the example above. If you for example search for the full filename "test.TXT" then everything works correctly.
DMan
28-Aug-2005 12:59
Whilst on Windows, a path starting with a slash resolves OK for most file functions - but NOT glob.
If the server is LAUNCHED (or chdir()ed) to W:, then
file_exists("/temp/test.txt")
returns true for the file "W:/temp/test.txt".
But glob("/temp/*.txt") FAILS to find it!
A solution (if you want to avoid getting drive letters into your code) is to chdir() first, then just look for the file.
<?php
$glob="/temp/*.txt";
chdir(dirname($glob));
foreach (glob(basename($glob)) as $filename) {
$filepath = dirname($glob)."/".$filename; echo "$filepath size " . filesize($filepath) . "\n";
}
?>
Note also, glob() IS case sensitive although most other file funcs on Windows are not.
x_terminat_or_3 at yahoo dot country:fr
06-Jul-2005 03:36
This is a replacement for glob on servers that are running a php version < 4.3
It supports * and ? jokers, and stacking of parameters with ;
So you can do
<? $results=glob('/home/user/*.txt;*.doc') ?>
And it will return an array of matched files.
As is the behaviour of the built-in glob function, this one will also return boolean false if no matches are found, and will use the current working directory if none is specified.
<?php
if(!(function_exists('glob')))
{function glob($pattern)
{$path=$output=null;
if(PHP_OS=='WIN32')
$slash='\\';
else
$slash='/';
$lastpos=strrpos($pattern,$slash);
if(!($lastpos===false))
{$path=substr($pattern,0,-$lastpos-1); $pattern=substr($pattern,$lastpos);
}
else
{$path=getcwd();
}
$handle=@ opendir($path);
if($handle===false)
return false;
while($dir=readdir($handle))
{if(pattern_match($pattern,$dir))
$output[]=$dir;
}
closedir($handle);
if(is_array($output))
return $output;
return false;
}
function pattern_match($pattern,$string)
{$out=null;
$chunks=explode(';',$pattern);
foreach($chunks as $pattern)
{$escape=array('$','^','.','{','}',
'(',')','[',']','|');
while(strpos($pattern,'**')!==false)
$pattern=str_replace('**','*',$pattern);
foreach($escape as $probe)
$pattern=str_replace($probe,"\\$probe",$pattern);
$pattern=str_replace('?*','*',
str_replace('*?','*',
str_replace('*',".*",
str_replace('?','.{1,1}',$pattern))));
$out[]=$pattern;
}
if(count($out)==1)
return(eregi("^$out[0]$",$string));
else
foreach($out as $tester)
if(eregi("^$tester$",$string))
return true;
return false;
}
}
?>
This function is case insensitive, but if needed, you can do this to make it behave depending on os:
* replace eregi in the example with my_regexp
add this function
<?php
function my_regexp($pattern,$probe)
{$sensitive=(PHP_OS!='WIN32');
$sensitive=false;
return ($sensitive?
ereg($pattern,$probe):
eregi($pattern,$probe));
}
?>
mjs15451 at hotmail dot com
17-Jun-2005 03:03
In regards to the comments made by: NOSPAM sketch at infinite dot net dot au, he is wrong about Unix/Linux (I can't speak for Windows). I am running PHP 5.0.4 and I ran a bunch of different tests on relative and absolute paths using the glob function and they all work on Unix/Linux. I also tested glob on empty directories and patterns which don't match any files (even directories or files which don't exist) and it __always__ returns an empty array. I couldn't get the glob function to return false so it looks like it always returns an array.
Michael T. McGrew
16-May-2005 07:12
Take all file names in the directory and put them in a link.
<?php
foreach (glob("*.*") as $filename)
{
echo "<a href=\"".$filename."\">".$filename."</a><br/>";
}
?>
cgamedude at yahoo dot com
05-May-2005 03:38
Here is the *correct* way to do a reverse-alphabetical search:
<?
$Results = glob( 'blah.*' );
rsort( $Results );
?>
There now, wasn't that easy? :)
Deviant
04-Apr-2005 04:53
A slight edit on the globr() function stated by sthomas. This does exactly the same just works on windows systems for < PHP 4.3.3. :
<?php
function globr($sDir, $sPattern, $nFlags = NULL) {
$aFiles = glob("$sDir/$sPattern", $nFlags);
$files = getDir($sDir);
if (is_array($files)) {
foreach( $files as $file ) {
$aSubFiles = globr($file, $sPattern, $nFlags);
$aFiles = array_merge($aFiles,$aSubFiles);
}
}
return $aFiles;
}
function getDir($sDir) {
$i=0;
if(is_dir($sDir)) {
if($rContents = opendir($sDir)) {
while($sNode = readdir($rContents)) {
if(is_dir($sDir.'/'.$sNode )) {
if($sNode !="." && $sNode !="..") {
$aDirs[$i] = $sDir.'/'.$sNode ;
$i++;
}
}
}
}
}
return $aDirs;
}
?>
cjcommunications at gmail dot com
01-Apr-2005 05:02
Here is a way I used glob() to browse a directory, pull the file name out, resort according to the most recent date and format it using date(). I called the function inside a <select> and had it go directly to the PDF file:
function browsepdf(){
$pdffile=glob("printable/*.pdf");
rsort($pdffile);
foreach($pdffile as $filename){
$filename=ltrim($filename, "printable/");
$filename=rtrim($filename, ".pdf");
$file=$filename;
$datetime=strtotime($filename);
$newdate=strtotime("+3 days",$datetime);
$filenamedate=date("F d", $datetime);
$filenamedate.=" - ".date("F d, Y", $newdate);
echo "<option value='$file'>$filenamedate</option>";
}
}
fraggy(AT)chello.nl
23-Mar-2005 03:23
glob caused me some real pain in the buttom on windows, because of the DOS thing with paths (backslashes instead of slashes)...
This was my own fault because I "forgot" that the backslash, when used in strings, needs to be escaped, but well, it can cause a lot of confusion, even for people who are not exactly newbies anymore...
For some reason, I didn't have this problem with other file operations (chdir, opendir, etc...), which was the most confusing of all...
So, for people running scripts on Windows machines (Dos95, 98 or WinNT or DosXP), just remember this:
glob('c:\temp\*.*'); // works correctly, returns an array with files.
glob("c:\temp\*.*"); // does NOT work... the backslashes need to be escaped...
glob("c:\\temp\\*.*"); // that works again...
This is especially confusing when temporary writable directories are returned as an unescaped string.
$tempdir = getenv('TEMP');
// this returns "C:\DOCUME~1\user\LOCALS~1\Temp"
so in order to scan that directoy I need to do:
glob($tempdir . "\\*.*");
Or perhaps it's easier to replace all backslashes with slashes in order to avoid these kinds of confusions...
glob("c:/temp/*.*"); // works fine too...
I know I'm not contributing anything new here, but I just hope this post may avoid some unnecessary headaches...
NOSPAM sketch at infinite dot net dot au
14-Mar-2005 05:05
in the example below, i found i got an error if the directory was empty.
<?php
foreach (glob("*.txt") as $filename) {
echo "$filename size " . filesize($filename) . "\n";
}
?>
I think its because glob()'ing an empty directory returns false, and so calling foreach (false as $value) will obviously break.
to fix this, i did the following:
<?php
$files = glob("*.txt) or array(); // give it an empty array if the directory is empty or glob fails otherwise
echo "$filename size " . filesize($filename) . "n";
}
?>
Hope this helps someone
29-Jan-2005 02:09
Be aware...
On Windows you need to add "/" mark:
<?php
$files = glob("/dir/*.txt"); $files = glob("dir/*.txt"); ?>
On Unix you cant add the "/" mark:
<?php
$files = glob("dir/*.txt"); $files = glob("/dir/*.txt"); ?>
Hope this will save your time :)
23-Jan-2005 01:54
The example on this page will generate a warning if the glob function does not find any filenames that match the pattern.
The glob function result will only be an array if it finds some files and the foreach statement requires its argument to be an array.
By checking for the possibility that the result of the glob function may not be an array you can eliminate the warning.
Here's a better example:
<?php
$matches = glob("*.txt");
if ( is_array ( $matches ) ) {
foreach ( $matches as $filename) {
echo "$filename size " . filesize($filename) . "\n";
}
}
?>
Paul Gregg / Qube #efnet
30-Mar-2004 05:52
Just threw this together in response to a common question in irc:
Available at: http://www.pgregg.com/projects/
http://www.pgregg.com/projects/php/code/preg_find.phps
preg_find() - A function to search in a directory for files or directories matching a preg_ pattern. Tell it the pattern, the start directory and some optional flags and it will return an array of files and their associated stat() details. If you just want the filenames, just do an array_keys() on the result.
e.g. $files = preg_find("/\.php$/", '.', PREG_FIND_RECURSIVE);
will find all files ending in .php in the current directory and below.
Options are:
// PREG_FIND_RECURSIVE - go into subdirectorys looking for more files
// PREG_FIND_DIRMATCH - return directorys that match the pattern also
// PREG_FIND_FULLPATH - search for the pattern in the full path (dir+file)
// PREG_FIND_NEGATE - return files that don't match the pattern
// to use more than one simple seperate them with a | character
Hope you find it useful.
Paul.
Per Lundberg
25-Nov-2003 07:57
Be aware that on UNIX, * as the pattern will *not* match dot-files and dot-directories. Knowing this will save you some headache. :-) May He bless you.
MichaelSoft
06-Nov-2003 03:28
Note that, in some configurations, the search is case-sensitive! You'll need to have something like:
<?php
$images = glob("/path/to/images/{*.jpg,*.JPG}", GLOB_BRACE);
?>
Also on some servers, I have seen such scripts 'crash' with an CGI Error ("...not returning a complete set of HTTP headers...") when glob could not find any match!
ryan at wonko dot com
29-Oct-2003 11:03
Here's an example of how to use the GLOB_BRACE flag:
<?php
$images = glob("/path/to/images/{*.gif,*.jpg,*.png}", GLOB_BRACE);
?>
It's also worth noting that when using the GLOB_BRACE flag in any version of PHP prior to 4.3.4, PHP will crash if no matches are found.
sthomas at townnews dot com
11-Mar-2003 03:41
<?php
function globr($sDir, $sPattern, $nFlags = NULL)
{
$sDir = escapeshellcmd($sDir);
$aFiles = glob("$sDir/$sPattern", $nFlags);
foreach (glob("$sDir/*", GLOB_ONLYDIR) as $sSubDir)
{
$aSubFiles = rglob($sSubDir, $sPattern, $nFlags);
$aFiles = array_merge($aFiles, $aSubFiles);
}
return $aFiles;
}
?>
martin dot rode at zeroscale dot com
19-Feb-2003 11:37
If you don't have PHP >= 4.3 available and don't want to hassle with PHP (:-) do something like this on GNU/Linux:
<?php
foreach (explode("\n",`find -type d -maxdepth 1 ! -name ".*" -printf "%f\n" `) as $dirname) {
print $dirname;
}
?>
With the "find" you can "glob" whatever you like.
tmm at aon dot at
21-Dec-2002 04:50
I have written my own function for searching files, but it only supports ? and *
However it should be easily expandable.
<?php
function GetMatchingFiles($files, $search) {
if(strpos($search,".")) {
$baseexp=substr($search,0,strpos($search,"."));
$typeexp=substr($search,strpos($search,".")+1,strlen($search));
} else {
$baseexp=$search;
$typeexp="";
}
$baseexp=preg_quote($baseexp);
$typeexp=preg_quote($typeexp);
$baseexp=str_replace(array("\*","\?"), array(".*","."), $baseexp);
$typeexp=str_replace(array("\*","\?"), array(".*","."), $typeexp);
$i=0;
foreach($files as $file) {
$filename=basename($file);
if(strpos($filename,".")) {
$base=substr($filename,0,strpos($filename,"."));
$type=substr($filename,strpos($filename,".")+1,strlen($filename));
} else {
$base=$filename;
$type="";
}
if(preg_match("/^".$baseexp."$/i",$base) && preg_match("/^".$typeexp."$/i",$type)) {
$matches[$i]=$file;
$i++;
}
}
return $matches;
}
And if someone's searching for a function which gets all files from a directory including the subdirectories:
// Returns all Files contained in given dir, including subdirs
function GetContents($dir,$files=array()) {
if(!($res=opendir($dir))) exit("$dir doesn't exist!");
while(($file=readdir($res))==TRUE)
if($file!="." && $file!="..")
if(is_dir("$dir/$file")) $files=GetContents("$dir/$file",$files);
else array_push($files,"$dir/$file");
closedir($res);
return $files;
}
?>
leon at leonatkinson dot com
17-Oct-2002 06:03
Since this function is a wrapper for the OS function of the same name, you may find it helpful to look at the man page while the exact PHP implementation is sorted out.
You might have some luck passing in the literal values of the constants defined in /usr/include/glob.h. For example, GLOB_NOSORT is defined as (1 << 2), which is 4. In PHP, glob('*.php', 4) will returns an unsorted list for me in RH 7.x. YMMV.
opessin at ifrance dot com
07-Jul-2002 03:48
If this function is not available in your version of PHP, think looking at the 'Directory Functions' which can be used instead.
manual/en/ref.dir.php
| |