请注意,如果父目录没有为您设置 +x,则 is_file() 将返回 false;这是有意义的,但其他函数(如 readdir())似乎没有此限制。最终结果是您可以循环遍历目录中的文件,但 is_file() 将始终失败。
(PHP 4, PHP 5, PHP 7, PHP 8)
is_file — 判断文件名是否为普通文件
filename
文件路径。
如果文件名存在且是普通文件,则返回 true
,否则返回 false
。
注意: 由于 PHP 的整数类型是有符号的,并且许多平台使用 32 位整数,因此对于大于 2GB 的文件,某些文件系统函数可能会返回意外的结果。
失败时,会发出 E_WARNING
。
示例 #1 is_file() 示例
<?php
var_dump(is_file('a_file.txt')) . "\n";
var_dump(is_file('/usr/bin/')) . "\n";
?>
以上示例将输出
bool(true) bool(false)
注意: 此函数的结果会被缓存。有关更多详细信息,请参见 clearstatcache()。
请注意,如果父目录没有为您设置 +x,则 is_file() 将返回 false;这是有意义的,但其他函数(如 readdir())似乎没有此限制。最终结果是您可以循环遍历目录中的文件,但 is_file() 将始终失败。
### 符号链接将被解析 ###
如果将符号链接(unix 符号链接)作为参数传递,is_file 将解析符号链接,并提供有关引用文件的的信息。例如
touch file
ln -s file link
echo '<? if (is_file("link")) echo "y\n"; ?>' | php -q
将打印“y”。
is_dir 也解析符号链接。
我倾向于使用大量的 include,我发现 is_file 基于执行的脚本,而不是运行的脚本。
如果您请求 /foo.php,而 foo.php 如下所示
<?php
include('foobar/bar.php');
?>
而 bar.php 如下所示
<?php
echo (is_file('foo/bar.txt'));
?>
那么 PHP(在 win32 上,php 5.x)将查找 /foo/bar.txt,而不是 /foobar/foo/bar.txt。
您必须为此重写 is_file 语句,或更改工作目录。
因为我花了一些时间才解决这个问题,所以在这里说明一下,
干杯,Toxik。
关于 rehfeld dot us 的注释
根据我的经验,查找文件扩展名的最佳(也是最简单)的方法是
<?php
// 当您确定它实际上具有扩展名时使用。
$extension = end(explode(".", $file_name));
?>
或者
<?php
// 此方法还将检查它是否实际上具有扩展名
$parts = explode(".", $file_name);
if (is_array($parts) && count($parts) > 1)
$extension = end($parts);
?>
如果您在 win32 机器上作为服务运行 apache,并且尝试确定网络中另一台 PC 上的文件是否存在 - 例如:is_file('//servername/share/dir1/dir2/file.txt') - 当您以 LocalSystem 身份运行服务时,您可能会返回 false。为避免这种情况,您必须以“已注册”域用户身份启动 Apache 服务。
is_file 无法识别文件名包含特殊字符的文件,例如捷克语的 ů 或俄语字符。
我见过许多脚本认为路径是目录,当 is_file($path) 失败时。当尝试确定路径是链接到文件还是目录时,您应该始终在从 is_file($path) 获取 false 后使用 is_dir。对于上面描述的情况,两者都会失败。
有时此函数不起作用是因为权限问题,
您可以使用此函数检查路径是否在最后有点,将返回 true。
public function isFile($file) {
$f = pathinfo($file, PATHINFO_EXTENSION);
return (strlen($f) > 0) ? true : false;
}
isfile('http://www.ip4t.net/image.jpg');
您应该将 '' 之间的字符串替换为您要检查的文件路径
我花了一天左右的时间才弄清楚 is_file() 实际上是在寻找字符串形式的有效 $ 现有路径/文件。它没有对给定的参数执行类似模式的测试。它正在测试给定的参数是否指向特定的现有“name.ext”或其他(非目录)文件类型对象。
这是一个针对文件大小限制的解决方法。使用 bash 文件测试运算符,因此它可以更改为测试目录等。(有关可能的测试运算符,请参见 http://tldp.org/LDP/abs/html/fto.html)
<?php
function is_file_lfs($path){
exec('[ -f "'.$path.'" ]', $tmp, $ret);
return $ret == 0;
}
?>
这可能是新手常犯的错误,请注意路径是相对于文件系统和脚本位置的。这意味着MS IIS虚拟目录无法通过相对路径访问 - 请使用绝对路径。
这让我很困惑,因为虚拟目录至少在IIS上是可以通过URL访问的。
此函数删除定义文件夹中的所有内容。
适用于PHP 4和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);
}
}
}
}
}
?>
小心,如果文件大于整数存储空间(对于大多数系统来说是2^32),`is_file()` 会失败。
警告:is_file(): Stat failed for bigfile (errno=75 - Value too large for defined data type)
在win32下的PHP 4.1.0中,如果文件不存在,这似乎会打印警告消息(使用error_reporting = E_ALL & ~E_NOTICE)。
我注意到在Windows服务器(主要用于开发)上使用`is_file`并使用完整路径c:\并不总是有效。
我不得不使用
C:/foldertowww/site/file.ext
所以我执行了一个`str_replace('\\', '/', $path)`
有时我用\代替/也能工作。(这是在XP上使用apache2)
但可以肯定的是,你不能混合使用分隔符。
还要注意,如果设置了`open_basedir`配置,并且文件(或目录)不在配置的位置之一,则`is_file()`(以及`is_dir()`)将返回false。
基本上,正如其他说明所述,如果您没有权限访问文件或目录,这些函数将返回false,但这也是人们可能忽略的另一个用例。
一种无需在硬编码完整路径和使用相对路径之间进行选择的方法是通过以下代码:
<?php
// 在引导文件中
define('DIR_ROOT', dirname(__FILE__));
// 在其他文件中,用常量作为路径前缀
require(DIR_ROOT . '/relative/to/bootstrap.php');
?>
或者,如果您必须使用相对路径
<?php
require(dirname(__FILE__) . '/relative/to/this_file.php');
?>
这样,所有路径都将是绝对路径,但您可以将应用程序移动到文件系统的任何位置。
顺便说一句,每次连续调用`dirname`都会向上移动一层目录树。
<?php
echo __FILE__;
// /www/site.com/public/index.php
echo dirname(__FILE__);
// /www/site.com/public
echo dirname(dirname(__FILE__));
// /www/site.com
?>
在32位环境中,包括`is_file()`、`stat()`、`filesize()`在内的这些函数将无法工作,因为PHP的默认整数是有符号的。因此,任何超过约21亿字节的文件,您实际上都会得到一个负值。
这实际上是一个bug,但我认为没有简单的解决方法。尝试切换到64位。
我做了很多文件解析工作,发现以下技术非常有用
while (false !== ($document = readdir($my_dir)))
{
$ext=explode('.',$document);
if($document != '.' && $document != '..' && $ext[1])
{
'对文件执行某些操作...'
}
}
它解决了在处理网页时,下载的html文件被读取为目录的问题。它还允许您通过添加确定文件类型的能力来扩展上述方法的用途,例如:
if($document != '.' && $document != '..' && $ext[1]=='htm')
或者
if($document != '.' && $document != '..' && $ext[1]=='doc')
关于rlh at d8acom dot com 的方法,
这是不正确的。嗯,它有效,但是您不能保证使用该方法获得文件扩展名。
例如:filename.inc.php
您的方法会告诉您扩展名为“inc”,但实际上是“php”。
这是一个有效的方法。
<?php
$dh = opendir($dir);
while (false !== ($document = readdir($dh))) {
$pos = strrpos($document, '.');
if (false !== $pos && strlen($document) > $pos + 1) {
$ext = substr($document, $pos + 1);
}
}
?>
我明白了,`is_file`在`/dev`(Linux)中的特定文件上不能正常工作。
看
root@boofh:/data# php -r "var_dump(is_file('/dev/core'));"
bool(true)
root@boofh:/data# php -r "var_dump(is_file('/proc/kcore'));"
bool(true)
root@boofh:/data# ls -alh /proc/kcore
-r-------- 1 root root 128T Aug 13 18:39 /proc/kcore
或者`FIND`检测不到常规文件。
root@boofh:/data# find /dev/ -type f
root@boofh:/data#
// php版本
root@boofh:/data# php -v
PHP 5.4.4-14+deb7u3 (cli) (built: Jul 17 2013 14:54:08)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
今天我遇到了评论中已经描述的行为,即`is_file()`或`is_dir()`无法区分目录和文件。
下面是一个不完善的hack,因为它从未包含链接,而且我从未测试过当不允许读取目录时会发生什么。
$items = scandir($dir);
foreach ($items as $item){
if ($item!='.' && $item!='..'){
$deep = @scandir($dir.'/'.$item);
echo ($deep ? '[DIR] ':'[FILE] '.$item.nl2br(PHP_EOL);
}
}