請注意,如果父目錄沒有為您設定 +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 陳述式,或變更工作目錄。
注意到這一點,因為我為這個問題坐了很久,
cheers, 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,並嘗試判斷您網路上另一台電腦上的檔案是否存在 - 例如: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);
}
}
}
}
}
?>
請注意,is_file() 對於大於你的整數儲存空間(大多數為 2^32)的檔案會失敗。
警告:is_file():bigfile 的 Stat 失敗 (errno=75 - 值對於定義的資料類型而言過大)
在 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 億位元組的數值都會得到負值。
這實際上是一個錯誤,但我不認為有簡單的變通方法。嘗試切換到 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 8月 13 18:39 /proc/kcore
OR FIND 未偵測到常規檔案。
root@boofh:/data# find /dev/ -type f
root@boofh:/data#
// php 版本
root@boofh:/data# php -v
PHP 5.4.4-14+deb7u3 (cli) (建置於:2013 年 7 月 17 日 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() 來區分目錄和檔案。
以下是一個不完整且不完善的臨時解決方法,之所以不完整是因為它永遠不會包含連結,而且我從未測試過在不允許讀取目錄時會發生什麼。
$items = scandir($dir);
foreach ($items as $item){
if ($item!='.' && $item!='..'){
$deep = @scandir($dir.'/'.$item);
echo ($deep ? '[DIR] ':'[FILE] '.$item.nl2br(PHP_EOL);
}
}