Filesystem 函数
在线手册:中文 英文
PHP手册

is_file

(PHP 4, PHP 5)

is_file判断给定文件名是否为一个正常的文件

说明

bool is_file ( string $filename )

如果文件存在且为正常的文件则返回 TRUE

Example #1 is_file() 例子

<?php
var_dump
(is_file('a_file.txt')) . "\n";
var_dump(is_file('/usr/bin/')) . "\n";
?>

以上例程会输出:

bool(true)
bool(false)

Note: 此函数的结果会被缓存。参见 clearstatcache() 以获得更多细节。

Tip

自 PHP 5.0.0 起, 此函数也用于某些 URL 包装器。请参见 Supported Protocols and Wrappers以获得支持 stat() 系列函数功能的包装器列表。

参见 is_dir()is_link()

参数

filename

Path to the file.

返回值

Returns TRUE if the filename exists and is a regular file, FALSE otherwise.

Note: 因为 PHP 的整数类型是有符号整型而且很多平台使用32位整型, 对2GB以上的文件,一些文件系统函数可能返回无法预期的结果 。

范例

Example #2 is_file() example

<?php
var_dump
(is_file('a_file.txt')) . "\n";
var_dump(is_file('/usr/bin/')) . "\n";
?>

以上例程会输出:

bool(true)
bool(false)

错误/异常

失败时抛出E_WARNING警告.

注释

Note: 此函数的结果会被缓存。参见 clearstatcache() 以获得更多细节。

Tip

自 PHP 5.0.0 起, 此函数也用于某些 URL 包装器。请参见 Supported Protocols and Wrappers以获得支持 stat() 系列函数功能的包装器列表。

参见


Filesystem 函数
在线手册:中文 英文
PHP手册
PHP手册 - N: 判断给定文件名是否为一个正常的文件

用户评论:

Anonymous (07-Feb-2012 03:44)

Note that is_file() returns false if the parent directory doesn't have +x set for you; this make sense, but other functions such as readdir() don't seem to have this limitation. The end result is that you can loop through a directory's files but is_file() will always fail.

alcala_ruben2 at hotmail dot com (19-Oct-2011 10:38)

This little script helps you get all php files (not hidden) inside certain folder including all subfolders

<?php
$allDirs
= array();
           
$dirLevel = 0;
           
$searchFactor = 0;
           
$searchPath = '';
           
$keepLooking = TRUE;
            while (
$keepLooking) {
                if(
$dirLevel == 0){
                   
$searchPath = '/path/to/parentFolder';
                   
$tmp = array();
                    foreach (
scandir($searchPath) as $filename) {
                       
$host = $searchPath.'/'.$filename;
                        if (
is_dir($host) && substr($filename,0,1)!='.'){
                           
$searchFactor++;
                           
array_push($tmp,$host);
                        }
                        elseif(
is_file($host)) {
                           
$forExt = explode('.',$host);
                            if(
$forExt[count($forExt)-1]=='php' && substr($filename,0,1)!='.')//if you want hidden files just take out the part "&& substr($filename,0,1)!='.'"
                               
echo $host;
                               
                        }
                    }
                    if(
$searchFactor>0){
                       
$dirLevel++;
                       
array_push($allDirs, $tmp);
                       
$searchFactor = 0;
                    }
                }   
                else{
                   
$tmp = array();
                    foreach (
$allDirs[$dirLevel-1] as $searchPath) {
                        foreach (
scandir($searchPath) as $filename) {
                           
$host = $searchPath.'/'.$filename;
                            if (
is_dir($host) && substr($filename,0,1)!='.'){
                               
$searchFactor++;
                               
array_push($tmp,$host);
                            }
                            elseif(
is_file($host)) {
                               
$forExt = explode('.',$host);
                                if(
$forExt[count($forExt)-1]=='php' && substr($filename,0,1)!='.')
                                    echo
$host;
                               
                            }
                        }
                    }
                    if(
$searchFactor>0){
                       
$dirLevel++;
                       
array_push($allDirs, $tmp);
                       
$searchFactor = 0;
                    }
                    else
                       
$keepLooking = FALSE;
                }
            }
?>

Anonymous (19-Jun-2011 07:47)

is_file doesn't recognize files whose filenames contain strange characters like czech ? or russian characters in general.

I've seen many scripts that take it for granted that a path is a directory when it fails is_file($path). When trying to determine whether a path links to a file or a dir, you should always use is_dir after getting false from is_file($path). For cases like described above, both will fail.

don dot duvall at deduvall dot com (11-Sep-2009 10:55)

I have noticed that using is_file on windows servers (mainly for development) to use a full path c:\ doesn't always work.

I have had to use
C:/foldertowww/site/file.ext

so I preform an str_replace('\\', '/', $path)
Sometimes I have had the \ instead of / work. (this is using apache2 on XP)

but for sure you cannot have mixed separators.

ca dot redwood at gmail dot com (23-Apr-2009 08:24)

this is a simple way to find specific files instead of using is_file().
this example is made for mac standards, but easily changed for pc.

<?php
function isfile($file){
    return
preg_match('/^[^.^:^?^\-][^:^?]*\.(?i)' . getexts() . '$/',$file);
   
//first character cannot be . : ? - subsequent characters can't be a : ?
    //then a . character and must end with one of your extentions
    //getexts() can be replaced with your extentions pattern
}

function
getexts(){
   
//list acceptable file extensions here
   
return '(app|avi|doc|docx|exe|ico|mid|midi|mov|mp3|
                 mpg|mpeg|pdf|psd|qt|ra|ram|rm|rtf|txt|wav|word|xls)'
;
}

echo
isfile('/Users/YourUserName/Sites/index.html');
?>

Kevin Gregull (13-Nov-2008 04:14)

This Function deletes everything in a defined Folder:
Works with PHP 4 and 5.

<?php
 
function deletefolder($path)
  {
    if (
$handle=opendir($path))
    {
      while (
false!==($file=readdir($handle)))
      {
        if (
$file<>"." AND $file<>"..")
        {
          if (
is_file($path.'/'.$file))
          {
            @
unlink($path.'/'.$file);
          }
          if (
is_dir($path.'/'.$file))
          {
           
deletefolder($path.'/'.$file);
            @
rmdir($path.'/'.$file);
          }
        }
      }
    }
  }
?>

rigrace at swbell dot net (10-Oct-2008 05:48)

It took me a day or so to figure out that is_file() actually looks for a valid $ existing path/file in string form. It is not performing a pattern-like test on the parameter given. Its testing to see if the given parameter leads to a specific  existing 'name.ext' or other (non-directory) file type object.

sy well-known-sign damla.net (24-Mar-2008 12:23)

In 32 bit environments, these functions including is_file(), stat() filesize() will not work due to PHPs default integer being signed. So anything above ~2.1 billion bytes you actually get a negative value.

This is actually a bug but I dont think there is an easy workaround. Try to switch to 64 bit.

gizmo at gizmo dot sk (22-Feb-2008 09:50)

here is a workaround for the file size limit. uses bash file testing operator, so it may be changed to test directories etc.  (see http://tldp.org/LDP/abs/html/fto.html for possible test operators)

<?php
function is_file_lfs($path){
   
exec('[ -f "'.$path.'" ]', $tmp, $ret);
    return
$ret == 0;
}
?>

Guilherme guilherme at gmail dot com (17-Jul-2007 02:36)

If you are trying to get the extension of the file. I have the following piece of code for you:

<?php
$extension
= substr($file_name, strrpos($file_name, "."));

// That code must get the correctly extension in any cases.
?>

cristian dot ban at neobytesolutions com (27-Jun-2007 09:46)

regarding note from rehfeld dot us :

In my experience the best( and easiest ) way to find the extension of a file is :

<?php

// use this when you are sure it actually has an extension.
$extension = end(explode(".", $file_name));

?>

or

<?php

// this one will also check if it actually has an extension
$parts = explode(".", $file_name);
if (
is_array($parts) && count($parts) > 1)
   
$extension = end($parts);

?>

riki1512 / a_t / gmx / d_ot / de (07-Feb-2007 11:22)

Be careful with big files. I get a

Warning: is_file(): Stat failed for all.rar (errno=75 - Value too large for defined data type) in /.../test.php on line 3

and FALSE as result for a file of 3,5 GB.

tatarynowicz at gmail dot com (18-Oct-2006 03:35)

An easy way not to have to choose between hard-coding full paths and using relative paths is either via this line:

<?php
// in the bootstrap file
define('DIR_ROOT', dirname(__FILE__));
// in other files, prefix paths with the constant
require(DIR_ROOT . '/relative/to/bootstrap.php');
?>

or if you have to use a relative path:

<?php
require(dirname(__FILE__) . '/relative/to/this_file.php');
?>

This way all your paths will be absolute, yet you can move the application anywhere in the filesystem.

BTW, each successive call to dirname takes you one step up in the directory tree.

<?php
echo __FILE__;
// /www/site.com/public/index.php
echo dirname(__FILE__);
// /www/site.com/public
echo dirname(dirname(__FILE__));
// /www/site.com
?>

SimonCharest at gmail dot com (08-Aug-2006 06:39)

In rlh's example, "$ext=explode('.',$document);" is only good if you consider that the filename only possesses a single dot (".") and that it is right before the extension. You should get the last dot's position with the strRPos() function instead.

Another note : some files might not even have an extension (i.e.: mostly under Linux/Unix).

Emin Sadykhov (azdg_nospam at azdg dot com) (12-Dec-2005 01:57)

File operations such as is_file (also is_dir, opendir, readdir) work slower with Absolute paths - processing time is increase in 2-3 times.

Current rule is actual only for PHP5 (tested on 5.0.4, 5.1.1, Windows and Linux, 1st and 2nd Apache)

Try to use relative paths in these operators.

Example tested on my machine:
<?php
# note: in the both conditions file really exists!

# WIN XP, PHP4
# processing time: ~ 0.0003 sec.
if(is_file("images/10.jpg")) echo 'file exists';

# processing time: ~ 0.0002 sec. !!!
if(is_file("C:/server/htdocs/mysite/images/10.jpg")) echo 'file exists';

# WIN XP, PHP5
# processing time: ~ 0.0004 sec.
if(is_file("images/10.jpg")) echo 'file exists';

# processing time: ~ 0.0010 sec.
if(is_file("C:/server/htdocs/mysite/images/10.jpg")) echo 'file exists';
?>

Jonathan Shaltz (14-Oct-2005 06:23)

Maybe this is a newbie mistake, but note that paths are relative to the filesystem and the location of the script.  This means that MS IIS virtual directories are not available by relative path - use an absolute.
This threw me because virtual directories ARE available for URLs, at least on IIS.

bill fumerola (31-Aug-2005 02:45)

be careful, is_file() fails on files larger than your integer storage (2^32 for most).

Warning: is_file(): Stat failed for bigfile (errno=75 - Value too large for defined data type)

punknroll at gmx dot at (11-Aug-2005 04:11)

is_file returns false if you don't have the permissions for the file or the directory (eg.: you are web34 and the directory belongs to root)!

(08-Mar-2005 05:02)

### Symbolic links are resolved ###

If you pass a symlink (unix symbolic link) as parameter, is_file will resolve the symlink and will give information about the refered file. For example:

  touch file
  ln -s file link
  echo '<? if (is_file("link")) echo "y\n"; ?>' | php -q

will print "y".

is_dir resolves symlinks too.

ludvig dot ericson at gmail dot com (25-Oct-2004 07:06)

I tend to use alot of includes, and I found that the is_file is based on the script executed, not ran.
if you request /foo.php and foo.php looks like this:
<?php
include('foobar/bar.php');
?>
and bar.php looks like this:
<?php
echo (is_file('foo/bar.txt'));
?>

Then PHP (on win32, php 5.x) would look for /foo/bar.txt and not /foobar/foo/bar.txt.
you would have to rewrite the is_file statement for that, or change working directory.
Noting this since I sat with the problem for some time,

cheers, Toxik.

rehfeld.us (03-Sep-2004 11:04)

regarding rlh at d8acom dot com method,

It is incorrect. Well, it works but you are not guaranteed the file extension using that method.

for example :   filename.inc.php

your method will tell you the ext is "inc", but it is in fact "php"

heres a way that will work properly.

<?php

$dh
= opendir($dir);

while (
false !== ($document = readdir($dh))) {
   
$pos = strrpos($document, '.');
    if (
false !== $pos && strlen($document) > $pos + 1) {
       
$ext = substr($document, $pos + 1);
    }
}

?>

rlh at d8acom dot com (12-Feb-2003 01:17)

I do a lot of file parsing and have found the following technique extremely useful:

while (false !== ($document = readdir($my_dir)))
{
    $ext=explode('.',$document);
    if($document != '.' && $document != '..' && $ext[1])
    {
                       'Do something to file...'
              }
}

It gets around the fact that, when working on website pages, the html files are read as directories when downloaded. It also allows you to extend the usefulness of the above method by adding the ability to determine file types e.g.

if($document != '.' && $document != '..' && $ext[1]=='htm')
or
if($document != '.' && $document != '..' && $ext[1]=='doc')

andreas dot stagl at fits dot at (27-Mar-2002 07:34)

if you're running apache as a service on a win32 machine, an you try to determinate if a file on an other pc in your network exists - ex.: is_file('//servername/share/dir1/dir2/file.txt') - you may return false when you're running the service as LocalSystem. To avoid this, you have to start the Apache-Service as a 'registered' domain user.

quietust at ircN dot org (14-Dec-2001 04:20)

In PHP 4.1.0 under win32, this seems to print out a warning message if the file does not exist (using error_reporting = E_ALL & ~E_NOTICE).

amraam at ao dot net (12-Mar-2000 02:56)

It seems that is_file doesn't return true for a file that is 0 bytes.  Perhaps it is something with the file system.  I am using IIS 3.0 on an NT4 box.  I worked around it using !is_dir($filename) but that seems a clunky way to do it.