©
Dokumen ini menggunakan Manual laman web PHP Cina Lepaskan
(PHP 4 >= 4.3.0, PHP 5, PHP 7)
glob — 寻找与模式匹配的文件路径
$pattern
[, int $flags
= 0
] ) glob() 函数依照 libc glob() 函数使用的规则寻找所有与
pattern
匹配的文件路径,类似于一般 shells
所用的规则一样。不进行缩写扩展或参数替代。
pattern
The pattern. No tilde expansion or parameter substitution is done.
flags
有效标记有:
GLOB_MARK
- 在每个返回的项目中加一个斜线
GLOB_NOSORT
- 按照文件在目录中出现的原始顺序返回(不排序)
GLOB_NOCHECK
- 如果没有文件匹配则返回用于搜索的模式
GLOB_NOESCAPE
- 反斜线不转义元字符
GLOB_BRACE
- 扩充 {a,b,c} 来匹配 'a','b' 或 'c'
GLOB_ONLYDIR
- 仅返回与模式匹配的目录项
GLOB_ERR
- 停止并读取错误信息(比如说不可读的目录),默认的情况下忽略所有错误
返回一个包含有匹配文件/目录的数组。如果出错返回 FALSE
。
Note:
On some systems it is impossible to distinguish between empty match and an error.
版本 | 说明 |
---|---|
5.1.0 | GLOB_ERR was added
|
4.3.3 | GLOB_ONLYDIR
在 Windows 或者其它不使用 GNU C 库的系统上开始可用。
|
Example #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
Note: 此函数不能作用于远程文件,被检查的文件必须是可通过服务器的文件系统访问的。
Note: 此函数在一些系统上还不能工作(例如一些旧的 Sun OS)。
Note:
GLOB_BRACE
在一些非 GNU 系统上无效,比如 Solaris。
[#1] sharshun dot aliaksandr at gmail dot com [2015-11-04 02:26:11]
<?php
function glob_recursive($pattern, $flags = 0){
// forked from https://github.com/rodurma/PHP-Functions/
// blob/master/glob_recursive.php
$files = glob($pattern, $flags);
foreach (glob(dirname($pattern).'**");
$arr=array_unique(array_merge($a, $ar));
foreach ($arr as $v) {
if (is_dir($v)) {
$arra[0][]=$v.'/';
} else {
$arra[1][]=$v;
}
}
sort($arra);
return $arra;
}
$a=dirInfoReGet('c:/test_directory/');
print_r($a);
?>
http://i.stack.imgur.com/H7UF3.jpg
Best regards.
[#2] Anxiety35 at gmail dot com [2014-12-01 21:20:19]
After fiddling with GLOB_BRACE a bunch, I have found the most items that can be included in the braces is about 10 before glob no longer returns any matches.
I have a scenario where there can be a thousand or more files to check for where I can't pattern match and need to check specific names. I was hoping to batch them in large groups to see if it would help performance. However, if I include more than 10 in a GLOB_BRACE the function will return FALSE.
[#3] rene dot rathmann at gmx dot de [2014-01-02 11:05:04]
You can do a recursive file search with yield.
<?php
function findAllDirs($start) {
$dirStack=[$start];
while($dir=array_shift($dirStack)) {
$ar=glob($dir.'
function array_prepend($array, $string, $deep=false) {
if(empty($array)||empty($string)) return $array;
foreach($array as $key => $element)
if(is_array($element))
if($deep)
$array[$key] = array_prepend($element,$string,$deep);
else
trigger_error('array_prepend: array element',E_USER_WARNING);
else
$array[$key] = $string.$element;
return $array;
}
?>
[#18] ottodenn at gmail dot com [2010-02-01 02:18:58]
just a quick one:
get all dirs, without files:
<?php
$dirs = array_filter(glob($path.'*'), 'is_dir');
?>
[#19] dragos dot rusu at ymail dot com [2009-11-11 00:52:58]
Glob function doesn't return the hidden files (including ".*" files). PHP5 RecursiveIterator can be used for iterating through directories recursively.
[#20] wang yun [2009-09-22 06:00:51]
A function to quickly remove a directory (works in seconds for a hundred thousand files)
<?php
function rmrf($dir) {
foreach (glob($dir) as $file) {
if (is_dir($file)) {
rmrf("$file*dirincludes
function alpharead3($dir){
if(!$dir){$dir = '.';}
foreach(glob("$dir
function globr($sDir, $sPattern, $nFlags = NULL)
{
$sDir = escapeshellcmd($sDir);
// Get the list of all matching files currently in the
// directory.
$aFiles = glob("$sDir/$sPattern", $nFlags);
// Then get a list of all directories in this directory, and
// run ourselves on the resulting array. This is the
// recursion step, which will not execute if there are no
// directories.
foreach (glob("$sDir
$file = new FileHandler($_FILES['excel_file']);
$inputFileName = $file->uploadFile()->fileNameSanitized(); // File to read
...
}
catch(Exception $e)
{
die('Error cargando archivo "'.($file->fileNameOriginal()).'": '.$e->getMessage());
}
}
?>
[#3] uramihsayibok, gmail, com [2007-08-12 21:18:12]
It isn't mentioned anywhere that I've seen, but $filename *is* case-sensitive on Windows.
It means that while C:\Windows\TEMP\php123.tmp may have been uploaded, C:\Windows\Temp\php123.tmp was not.
I found this out because I was using realpath() on the filename which 'fixed' the case (my Temp folder is in titlecase, not uppercase - thank you Vista).
Anyways, the problem was that PHP used %TEMP% to determine the destination for the uploaded file, and %TEMP% used the all-capitals version of the path. Changing it to use titlecase instead + restarting Apache fixed the problem.
[#4] YLearn [2005-10-10 10:42:34]
Just looked at what I posted again and found several mistakes of the major and minor sort. That's what I get for posting before I finish my coffee. This should work better (i.e. should work in the first place):
<?php
default: //a default error, just in case! :)
echo "There was a problem with your upload.";
$err_msg = "Unrecognized file POST error: ".$HTTP_POST_FILES['userfile']['error'];
if (!(strpos($err_msg, "\n") === false)) {
$err_lines = explode("\n", $err_msg);
foreach ($err_lines as $msg) {
error_log($msg, 0);
}
} else {
error_log($err_msg, 0);
}
break;
?>
[#5] YLearn [2005-10-10 09:41:15]
Regarding topcat's suggested change, I am split on doing that. I don't like showing users errors that may give them more information than they should have (or show that I haven't provided for that particular error). But I want to know when there are errors that fall to the default case so I can fix my code. What I will typically do is write them to the error log something like this modification to metaltoad's post (takes into account the possibility of multi-line errors which error_log doesn't handle well):
<?php
default: //a default error, just in case! :)
echo "There was a problem with your upload.";
$err_msg = "Unrecognized file POST error: ".$HTTP_POST_FILES['userfile']['error'];
if ((strpos($err_msg, "\n") === 0) {
$err_lines = explode("\n", $err_msg);
foreach ($err_lines as $msg) {
error_log($msg, 0);
}
} else {
error_log($err_msg, 0)
}
break;
?>
[#6] juk [2005-09-18 15:26:51]
If your $_FILES and $_POST are empty, this can be due to
- the limit set by post_max_size in php.ini
- the limit set by upload_max_filesize in php.ini
Unfortunately the first limit is not reported back as an error code in $_FILES['error'].
[#7] topcat [2005-07-14 04:56:37]
Just a little tip to info at metaltoad's comment:
It's good practice to print error code when it can't be recognized:
default: //print the error code
echo "Unrecognized error code: ".$HTTP_POST_FILES['userfile']['error'];
break;
[#8] [2005-04-23 12:29:03]
make use u got the enctype="multipart/form-data" in ur form tag otrherwise nothing works... took me two hours to find that out.......
[#9] beer UNDRSCR nomaed AT hotmail DOT com [2005-04-15 04:21:19]
Regarding the comment of info at metaltoad dot net
@ 19-Feb-2003 04:03
<?php
// ... yada yada yada...
preg_match("/.exe$|.com$|.bat$|.zip$|.doc$|.txt$/i", $HTTP_POST_FILES['userfile']['name']))
// ... yada yada yada...
?>
This will not work. It will, but not correctly.
You shuld escape the . (dot) for the preg function,
and escape the $ (dollar) sign for PHP, or use
single-quoted string...
The syntax should be (much shorter and neater):
<?php
// ... yada yada yada...
preg_match('/\\.(exe|com|bat|zip|doc|txt)$/i', $_FILES['userfile']['name']))
// ... yada yada yada...
?>
[#10] lots2learn at gmail dot com [2005-02-06 21:13:02]
if files are not getting uploaded and $_FILE array is empty ..and your code looks fine..then check php.ini file..the file_uploads option should be turned 'On' to allow file uploads. Turn it on and restart apache to have effect .
[#11] info at metaltoad dot net [2003-02-19 13:03:29]
As of PHP 4.2.0, rather than automatically assuming a failed file uploaded is a file attack, you can use the error code associated with the file upload to check and see why the upload failed. This error code is stored in the userfile array (ex: $HTTP_POST_FILES['userfile']['error']).
Here's an example of a switch:
if (is_uploaded_file($userfile)) {
//include code to copy tmp file to final location here...
}else{
switch($HTTP_POST_FILES['userfile']['error']){
case 0: //no error; possible file attack!
echo "There was a problem with your upload.";
break;
case 1: //uploaded file exceeds the upload_max_filesize directive in php.ini
echo "The file you are trying to upload is too big.";
break;
case 2: //uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the html form
echo "The file you are trying to upload is too big.";
break;
case 3: //uploaded file was only partially uploaded
echo "The file you are trying upload was only partially uploaded.";
break;
case 4: //no file was uploaded
echo "You must select an image for upload.";
break;
default: //a default error, just in case! :)
echo "There was a problem with your upload.";
break;
}
Additionally, by testing the 'name' element of the file upload array, you can filter out unwanted file types (.exe, .zip, .bat, etc). Here's an example of a filter that can be added before testing to see if the file was uploaded:
//rejects all .exe, .com, .bat, .zip, .doc and .txt files
if(preg_match("/.exe$|.com$|.bat$|.zip$|.doc$|.txt$/i", $HTTP_POST_FILES['userfile']['name'])){
exit("You cannot upload this type of file.");
}
//if file is not rejected by the filter, continue normally
if (is_uploaded_file($userfile)) {
[#12] itadmin at itmusicweb dot co dot uk [2002-11-28 06:11:09]
The example brought out does not work as supposed to:
function is_uploaded_file($filename) {
if (!$tmp_file = get_cfg_var('upload_tmp_dir')) {
$tmp_file = dirname(tempnam('', ''));
}
$tmp_file .= '/' . basename($filename);
return (ereg_replace('/+', '/', $tmp_file) == $filename);
}
It works only with files under ....4 or 5 kb, other files automatically get the size of 0 bytes. So something must be wrong here. Built-in is_uploaded_file() works good.
[#13] troels at NO dot SPAM dot webcode dot dk [2002-10-14 12:44:59]
to get the example to work on windows, youll have to add a line, that replaces backslashes with slashes. eg.: $filename = str_replace ("\\", "/", $filename);
also, as someone mentioned, globalizing $HTTP_POST_FILES is a good idea ...
<pre>
function is_uploaded_file($filename)
{
global $HTTP_POST_FILES;
if (!$tmp_file = get_cfg_var("upload_tmp_dir")) {
$tmp_file = dirname(tempnam("", ""));
}
$tmp_file .= "/" . basename($filename);
// fix for win platform
$filename = str_replace ("\\", "/", $filename);
return (ereg_replace("/+", "/", $tmp_file) == $filename);
}
</pre>