PHPのお勉強!

PHP TOP

file_exists

(PHP 4, PHP 5, PHP 7, PHP 8)

file_existsファイルまたはディレクトリが存在するかどうか調べる

説明

file_exists(string $filename): bool

ファイルあるいはディレクトリが存在するかどうかを調べます。

パラメータ

filename

ファイルあるいはディレクトリへのパス。

Windows 上でネットワーク共有上のファイルを調べるには、 //computername/share/filename または \\computername\share\filename のように指定してください。

戻り値

filename で指定したファイルまたはディレクトリが存在すれば true を返し、そうでなければ false を返します。

注意:

この関数は、シンボリックリンクの指す先のファイルが存在しない場合は false を返します。

注意:

チェックは、実効ユーザーではなく実ユーザーの UID/GID で行います。

注意: PHP の数値型は符号付整数であり、 多くのプラットフォームでは 32 ビットの整数を取るため、 ファイルシステム関数の中には 2GB より大きなファイルについては期待とは違う値を返すものがあります。

エラー / 例外

失敗したときは E_WARNING が発生します。

例1 あるファイルが存在するかどうか調べる

<?php
$filename
= '/path/to/foo.txt';

if (
file_exists($filename)) {
echo
"$filename が存在します";
} else {
echo
"$filename は存在しません";
}
?>

注意

注意: この関数の結果は キャッシュされます。詳細は、clearstatcache() を参照してください。

ヒント

PHP 5.0.0 以降、この関数は、 何らかの URL ラッパーと組合せて使用することができます。 どのラッパーが stat() ファミリーをサポートしているかを調べるには サポートするプロトコル/ラッパー を参照してください。

参考

  • is_readable() - ファイルが存在し、読み込み可能であるかどうかを知る
  • is_writable() - ファイルが書き込み可能かどうかを調べる
  • is_file() - 通常ファイルかどうかを調べる
  • file() - ファイル全体を読み込んで配列に格納する
  • SplFileInfo

add a note

User Contributed Notes 30 notes

up
76
maurice at idify dot nl
17 years ago
Note: The results of this function are cached. See clearstatcache() for more details.

That's a pretty big note. Don't forget this one, since it can make your file_exists() behave unexpectedly - probably at production time ;)
up
13
ziptwipi at goioia dot com
8 years ago
Note that realpath() will return false if the file doesn't exist. So if you're going to absolutize the path and resolve symlinks anyway, you can just check the return value from realpath() instead of calling file_exists() first
up
23
welkom at remconijhuis dot nl
10 years ago
I needed to measure performance for a project, so I did a simple test with one million file_exists() and is_file() checks. In one scenario, only seven of the files existed. In the second, all files existed. is_file() needed 3.0 for scenario one and 3.3 seconds for scenario two. file_exists() needed 2.8 and 2.9 seconds, respectively. The absolute numbers are off course system-dependant, but it clearly indicates that file_exists() is faster.
up
25
vernon at kesnerdesigns dot net
17 years ago
In response to seejohnrun's version to check if a URL exists. Even if the file doesn't exist you're still going to get 404 headers. You can still use get_headers if you don't have the option of using CURL..

$file = 'http://www.domain.com/somefile.jpg';
$file_headers = @get_headers($file);
if($file_headers[0] == 'HTTP/1.1 404 Not Found') {
$exists = false;
}
else {
$exists = true;
}
up
9
jag
5 years ago
file_exists() does NOT search the php include_path for your file, so don't use it before trying to include or require.

use

@$result = include $filename;

Yes, include does return false when the file can't be found, but it does also generate a warning. That's why you need the @. Don't try to get around the warning issue by using file_exists(). That will leave you scratching your head until you figure out or stumble across the fact that file_exists() DOESN'T SEARCH THE PHP INCLUDE_PATH.
up
10
Anonymous
18 years ago
I wrote this little handy function to check if an image exists in a directory, and if so, return a filename which doesnt exists e.g. if you try 'flower.jpg' and it exists, then it tries 'flower[1].jpg' and if that one exists it tries 'flower[2].jpg' and so on. It works fine at my place. Ofcourse you can use it also for other filetypes than images.

<?php
function imageExists($image,$dir) {

$i=1; $probeer=$image;

while(
file_exists($dir.$probeer)) {
$punt=strrpos($image,".");
if(
substr($image,($punt-3),1)!==("[") && substr($image,($punt-1),1)!==("]")) {
$probeer=substr($image,0,$punt)."[".$i."]".
substr($image,($punt),strlen($image)-$punt);
} else {
$probeer=substr($image,0,($punt-3))."[".$i."]".
substr($image,($punt),strlen($image)-$punt);
}
$i++;
}
return
$probeer;
}
?>
up
9
vcoletti at tiscali dot it
7 years ago
With PHP 7.0 on Ubuntu 17.04 and with the option allow_url_fopen=On, file_exists() returns always false when trying to check a remote file via HTTP.

So
$url="http://www.somewhere.org/index.htm";
if (file_exists($url)) echo "Wow!\n";
else echo "missing\n";

returns always "missing", even for an existing URL.

I found that in the same situation the file() function can read the remote file, so I changed my routine in

$url="http://www.somewhere.org/index.htm";
if (false!==file($url)) echo "Wow!\n";
else echo "missing\n";

This is clearly a bit slower, especially if the remote file is big, but it solves this little problem.
up
9
bvazquez at siscomx dot com
17 years ago
If you are trying to access a Windows Network Share you have to configure your WebServer with enough permissions for example:

$file = fopen("\\siscomx17\c\websapp.log",'r');

You will get an error telling you that the pathname doesnt exist this will be because Apache or IIS run as LocalSystem so you will have to enter to Services and configure Apache on "Open a session as" Create a new user that has enough permissions and also be sure that target share has the proper permissions.

Hope this save some hours of research to anyone.
up
3
varrg
5 years ago
file_exists() is vulnerable to race conditions and clearstatcache() is not adequate to avoid it.

The following function is a good solution:

<?php
function file_exists_safe($file) {
if (!
$fd = fopen($file, 'xb')) {
return
true; // the file already exists
}
fclose($fd); // the file is now created, we don't need the file handler
return false;
}
?>

The function will create a file if non-existent, following calls will fail because the file exists (in effect being a lock).

IMPORTANT: The file will remain on the disk if it was successfully created and you must clean up after you, f.ex. remove it or overwrite it. This step is purposely omitted from the function as to let scripts do calculations all the while being sure the file won't be "seized" by another process.

NOTE: This method fails if the above function is not used for checking in all other scripts/processes as it doesn't actually lock the file.
FIX: You could flock() the file to prevent that (although all other scripts similarly must check it with flock() then, see https://www.php.net/manual/en/function.flock.php). Be sure to unlock and fclose() the file AFTER you're done with it, and not within the above function:

<?php
function create_and_lock($file) {
if (!
$fd = fopen($file, 'xb')) {
return
false;
}
if (!
flock($fd, LOCK_EX|LOCK_NB)) { // may fail for other reasons, LOCK_NB will prevent blocking
fclose($fd);
unlink($file); // clean up
return false;
}
return
$fd;
}

if (
$lock = create_and_lock("foo.txt")) {
// do stuff
flock($fd, LOCK_UN); // unlock
fclose($fd); // close
}
?>

SEE ALSO: https://linux.die.net/man/2/open about O_CREAT|O_EXCL (which is used with the 'x' modifier for fopen()) and problems with NFS
up
4
Avee
16 years ago
I made a bit of code that sees whether a file served via RTSP is there or not:

<?php
function rtsp_exists($url) {

$server = parse_url($url, PHP_URL_HOST);
$port = "554";
$hdrs = "DESCRIBE " .$url ." RTSP/1.0"."\r\n\r\n";

//Open connection (15s timeout)
$sh = fsockopen($server, $port, $err, $err_otp, 15);
//Check connections
if(!$sh) return false;
//Send headers
fputs($sh,$hdrs);
//Receive data (1KB)
$rtds = fgets($sh, 1024);
//Close socket
fclose($sh);

return
strpos($rtds, "200 OK") > 0;
}
?>
up
6
ktcb123 at hotmail dot com
17 years ago
For some reason, none of the url_exists() functions posted here worked for me, so here is my own tweaked version of it.

<?php
function url_exists($url){
$url = str_replace("http://", "", $url);
if (
strstr($url, "/")) {
$url = explode("/", $url, 2);
$url[1] = "/".$url[1];
} else {
$url = array($url, "/");
}

$fh = fsockopen($url[0], 80);
if (
$fh) {
fputs($fh,"GET ".$url[1]." HTTP/1.1\nHost:".$url[0]."\n\n");
if (
fread($fh, 22) == "HTTP/1.1 404 Not Found") { return FALSE; }
else { return
TRUE; }

} else { return
FALSE;}
}
?>
up
5
Fabrizio (staff at bibivu dot com)
19 years ago
here a function to check if a certain URL exist:
<?php
function url_exists($url) {
$a_url = parse_url($url);
if (!isset(
$a_url['port'])) $a_url['port'] = 80;
$errno = 0;
$errstr = '';
$timeout = 30;
if(isset(
$a_url['host']) && $a_url['host']!=gethostbyname($a_url['host'])){
$fid = fsockopen($a_url['host'], $a_url['port'], $errno, $errstr, $timeout);
if (!
$fid) return false;
$page = isset($a_url['path']) ?$a_url['path']:'';
$page .= isset($a_url['query'])?'?'.$a_url['query']:'';
fputs($fid, 'HEAD '.$page.' HTTP/1.0'."\r\n".'Host: '.$a_url['host']."\r\n\r\n");
$head = fread($fid, 4096);
fclose($fid);
return
preg_match('#^HTTP/.*\s+[200|302]+\s#i', $head);
} else {
return
false;
}
}
?>

in my CMS, I am using it with those lines:
<?php
if(!isset($this->f_exist[$image]['exist']))
if(
strtolower(substr($fimage,0,4)) == 'http' || strtolower(substr($fimage,0,4)) == 'www.'){
if(
strtolower(substr($image,0,4)) == 'www.'){
$fimage = 'http://'.$fimage;
$image = 'http://'.$image;
}
$this->f_exist[$image]['exist'] = $this->url_exists($fimage); //for now
} else {
$this->f_exist[$image]['exist'] = ($fimage!='' && file_exists($fimage) && is_file($fimage) && is_readable($fimage) && filesize($fimage)>0);
}
}
?>
up
5
ferodano at gmail dot com
15 years ago
You could use document root to be on the safer side because the function does not take relative paths:

<?php
if( file_exists( $_SERVER{'DOCUMENT_ROOT'} . "/my_images/abc.jpg")) {
...
}
?>

Do not forget to put the slash '/', e.g. my doc root in Ubuntu is /var/www without the slash.
up
7
stuart
16 years ago
When using file_exists, seems you cannot do:

<?php
foreach ($possibles as $poss)
{
if (
file_exists(SITE_RANGE_IMAGE_PATH .$this->range_id .'/ '.$poss .'.jpg') )
{
// exists
}
else
{
// not found
}
}
?>

so you must do:

<?php
foreach ($possibles as $poss)
{
$img = SITE_RANGE_IMAGE_PATH .$this->range_id .'/ '.$poss .'.jpg'
if ( file_exists($img) )
{
// exists
}
else
{
// not found
}
}
?>

Then things will work fine.

This is at least the case on this Windows system running php 5.2.5 and apache 2.2.3

Not sure if it is down to the concatenation or the fact theres a constant in there, i'm about to run away and test just that...
up
4
andrewNOSPAMPLEASE at abcd dot NOSPAMERSca
19 years ago
file_exists will have trouble finding your file if the file permissions are not read enabled for 'other' when not owned by your php user. I thought I was having trouble with a directory name having a space in it (/users/andrew/Pictures/iPhoto Library/AlbumData.xml) but the reality was that there weren't read permissions on Pictures, iPhoto Library or AlbumData.xml. Once I fixed that, file_exists worked.
up
4
pgl at yoyo dot org
15 years ago
Note that this will return false for streams, eg, php://stdin.
up
6
spark at limao dot com dot br
13 years ago
this code here is in case you want to check if a file exists in another server:

<?php
function fileExists($path){
return (@
fopen($path,"r")==true);
}
?>

unfortunately the file_exists can't reach remote servers, so I used the fopen function.
up
3
jaz-t at hotmail dot com
16 years ago
Note on openspecies entry (excellent btw, thanks!).

If your server cannot resolve its own DNS, use the following:
$f = preg_replace('/www\.yourserver\.(net|com)/', getenv('SERVER_ADDR'), $f);

Just before the $h = @get_headers($f); line.

Replace the extensions (net|com|...) in the regexp expression as appropriate.

EXAMPLE:
File you are checking for: http://www.youserver.net/myfile.gif
Server IP: 10.0.0.125

The preg_replace will effectively 'resolve' the address for you by assigning $f as follows:
http://10.0.0.125/myfile.gif
up