111

I need to see if a specific image exists on my cdn.

I've tried the following and it doesn't work:

if (file_exists(http://www.example.com/images/$filename)) {
    echo "The file exists";
} else {
    echo "The file does not exist";
}

Even if the image exists or doesn't exist, it always says "The file exists". I'm not sure why its not working...

tshepang
  • 12,111
  • 21
  • 91
  • 136
PaperChase
  • 1,557
  • 4
  • 18
  • 23
  • Be carefult with this as you might find doing a `file_exists` to a remote location will be very slow. – crmpicco Feb 21 '14 at 09:54
  • @user9440008 Hi It is good to use PATH in the file_exist function instead of using URL. Can you please explain, how to access of path from CDN server instead of URL? – Syed Imran Ertaza Feb 13 '22 at 07:02

22 Answers22

142

You need the filename in quotation marks at least (as string):

if (file_exists('http://www.mydomain.com/images/'.$filename)) {
 … }

Also, make sure $filename is properly validated. And then, it will only work when allow_url_fopen is activated in your PHP config

knittl
  • 246,190
  • 53
  • 318
  • 364
  • 5
    I've been able to do it successfully using @GetImageSize. However, what will be less server intensive? – PaperChase Nov 03 '11 at 07:37
  • 10
    file_exists() needs to use a file path on the hard drive, not a URL This is not useful answer for me, should not be set as accepted. – Martin Jun 05 '16 at 18:10
  • From PHP: bool file_exists ( string $filename ) As of PHP 5.0.0, this function can also be used with some URL wrappers. Refer to Supported Protocols and Wrappers to determine which wrappers support stat() family of functionality. – Adrian P. Aug 10 '16 at 10:35
  • if $filename string is null then the file_exists will return true for the directory. Better to use is_file($filepath) – PodTech.io Nov 28 '17 at 23:14
  • 1
    As people said, it doesn't work on remote URL/paths. But it works in local paths (internal server path where files are located). Also, from other methods, remote takes as long as 14 seconds, and local, less than 1 second (for a certain example) – Rafa Aug 01 '18 at 10:52
126
if (file_exists('http://www.mydomain.com/images/'.$filename)) {}

This didn't work for me. The way I did it was using getimagesize.

$src = 'http://www.mydomain.com/images/'.$filename;

if (@getimagesize($src)) {

Note that the '@' will mean that if the image does not exist (in which case the function would usually throw an error: getimagesize(http://www.mydomain.com/images/filename.png) [function.getimagesize]: failed) it will return false.

JeffJenk
  • 2,575
  • 2
  • 21
  • 28
15

Try like this:

$file = '/path/to/foo.txt'; // 'images/'.$file (physical path)

if (file_exists($file)) {
    echo "The file $file exists";
} else {
    echo "The file $file does not exist";
}
Brandan
  • 14,735
  • 3
  • 56
  • 71
pinaldesai
  • 1,835
  • 2
  • 13
  • 22
14

Well, file_exists does not say if a file exists, it says if a path exists. ⚡⚡⚡⚡⚡⚡⚡

So, to check if it is a file then you should use is_file together with file_exists to know if there is really a file behind the path, otherwise file_exists will return true for any existing path.

Here is the function i use :

function fileExists($filePath)
{
      return is_file($filePath) && file_exists($filePath);
}
Rizerzero
  • 1,120
  • 12
  • 13
  • 2
    How could there be a path existing, but the file not existing, when the path contains the file name? – Andrew Mar 27 '15 at 18:08
  • 1
    i mean that it even works if the user gives a path and not a file , the function would return true even if it's not a file my friend . – Rizerzero Mar 27 '15 at 20:36
  • Interesting and potentially important differentiation to make. But if you check the docs, it looks like you only need to use is_file for this purpose, and not in conjunction with file_exists. – Andrew Mar 31 '15 at 17:07
  • ok let me sum this up to you , ( use :PaperChase ) wants to check if a file_exists , his issue is that even if he gives a path to the function he will get a true response , so to clearly check if a file exists then he would use My function , because the php function would return true even if a path is passed , so the function name is bad , it should be Path_exists() and My function Does really check if a file exists , because it would return false if a anything else than an existing file path is passed . i hope this is Clear now . – Rizerzero Apr 01 '15 at 13:44
  • Yes it would work fine, but according to http://php.net/manual/en/function.is-file.php is_file() already checks if the path/file exists before checking if it is a file, so you shouldn't need to. – Andrew Apr 01 '15 at 13:49
  • ok haystack needle / needle haystack , then we agree on how bad php is . And functions has meaningless names is_file should check if it's a file and file_exists should only return true for an existing file and they can add an path_exists ... – Rizerzero Apr 01 '15 at 17:59
  • After 4 years I am still concerned that Andrew's point didn't get accross. You don't need your own `fileExists()` function as it does *exactly* the same as `is_file()` in all the different scenarios. To put it differently `is_file()` already includes it's own version of `file_exists()`, so `fileExists()` actually checks for the file path twice. Granted the name of `file_exists()` function is somewhat misnamed. – s3c Dec 19 '19 at 08:26
  • @s3c Andrew is right " How could there be a path existing, but the file not existing, when the path contains the file name?" **My point is a file_exists function should not return true when a path is given ! that's all. if the function's name was path_exists then yes ! but a path is not a file for me and even if we could use is_file() the name is confusing and misleading .** – Rizerzero Dec 26 '19 at 10:04
  • Full path of the file includes it's filename.ext as well. So path can be a file. But it could be just a path to some directory. I agree it's possible that `file_exists( ... )` function may have been misnamed. Regardless you function is redundand. You might as well save the existing `is_file( ... )` under a different name and it would work the same as your function. Happy holidays everybody – s3c Dec 29 '19 at 09:37
9

Here is the simplest way to check if a file exist:

if(is_file($filename)){
    return true; //the file exist
}else{
    return false; //the file does not exist
}
John
  • 11,985
  • 3
  • 45
  • 60
jfindley
  • 682
  • 7
  • 6
8

If the file is on your local domain, you don't need to put the full URL. Only the path to the file. If the file is in a different directory, then you need to preface the path with "."

$file = './images/image.jpg';
if (file_exists($file)) {}

Often times the "." is left off which will cause the file to be shown as not existing, when it in fact does.

master_gracey
  • 344
  • 1
  • 8
  • 18
8

A thing you have to understand first: you have no files.
A file is a subject of a filesystem, but you are making your request using HTTP protocol which supports no files but URLs.

So, you have to request an unexisting file using your browser and see the response code. if it's not 404, you are unable to use any wrappers to see if a file exists and you have to request your cdn using some other protocol, FTP for example

Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
7
public static function is_file_url_exists($url) {
        if (@file_get_contents($url, 0, NULL, 0, 1)) {
            return 1;
        }

        return 0;           
    }
realmag777
  • 2,050
  • 1
  • 24
  • 22
4

There is a major difference between is_file and file_exists.

is_file returns true for (regular) files:

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

file_exists returns true for both files and directories:

Returns TRUE if the file or directory specified by filename exists; FALSE otherwise.


Note: Check also this stackoverflow question for more information on this topic.

Community
  • 1
  • 1
Wilt
  • 41,477
  • 12
  • 152
  • 203
2

You have to use absolute path to see if the file exists.

$abs_path = '/var/www/example.com/public_html/images/';
$file_url = 'http://www.example.com/images/' . $filename;

if (file_exists($abs_path . $filename)) {

    echo "The file exists. URL:" . $file_url;

} else {

    echo "The file does not exist";

}

If you are writing for CMS or PHP framework then as far as I know all of them have defined constant for document root path.

e.g WordPress uses ABSPATH which can be used globally for working with files on the server using your code as well as site url.

Wordpress example:

$image_path = ABSPATH . '/images/' . $filename;
$file_url = get_site_url() . '/images/' . $filename;

if (file_exists($image_path)) {

    echo "The file exists. URL:" . $file_url;

} else {

    echo "The file does not exist";

}

I'm going an extra mile here :). Because this code would no need much maintenance and pretty solid, I would write it with as shorthand if statement:

$image_path = ABSPATH . '/images/' . $filename;
$file_url = get_site_url() . '/images/' . $filename;

echo (file_exists($image_path))?'The file exists. URL:' . $file_url:'The file does not exist';

Shorthand IF statement explained:

$stringVariable = ($trueOrFalseComaprison > 0)?'String if true':'String if false';
Dmitriy Kravchuk
  • 476
  • 4
  • 16
2

you can use cURL. You can get cURL to only give you the headers, and not the body, which might make it faster. A bad domain could always take a while because you will be waiting for the request to time-out; you could probably change the timeout length using cURL.

Here is example:

function remoteFileExists($url) {
$curl = curl_init($url);

//don't fetch the actual page, you only want to check the connection is ok
curl_setopt($curl, CURLOPT_NOBODY, true);

//do request
$result = curl_exec($curl);

$ret = false;

//if request did not fail
if ($result !== false) {
    //if request was ok, check response code
    $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);  

    if ($statusCode == 200) {
        $ret = true;   
    }
}

curl_close($curl);

return $ret;
}
$exists = remoteFileExists('http://stackoverflow.com/favicon.ico');
if ($exists) {
echo 'file exists';
} else {
   echo 'file does not exist';   
}
manish1706
  • 1,571
  • 24
  • 22
1

try this :

if (file_exists(FCPATH . 'uploads/pages/' . $image)) {
    unlink(FCPATH . 'uploads/pages/' . $image);
}
Robert
  • 5,703
  • 2
  • 31
  • 32
Dev_meno
  • 124
  • 14
1

If you are using curl, you can try the following script:

function checkRemoteFile($url)
{
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL,$url);
 // don't download content
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if(curl_exec($ch)!==FALSE)
{
    return true;
}
else
{
    return false;
}

}

Reference URL: https://hungred.com/how-to/php-check-remote-email-url-image-link-exist/

Yogi Ghorecha
  • 1,584
  • 1
  • 19
  • 26
1

If path to your image is relative to the application root it is better to use something like this:

function imgExists($path) {
    $serverPath = $_SERVER['DOCUMENT_ROOT'] . $path;

    return is_file($serverPath)
        && file_exists($serverPath);
}

Usage example for this function:

$path = '/tmp/teacher_photos/1546595125-IMG_14112018_160116_0.png';

$exists = imgExists($path);

if ($exists) {
    var_dump('Image exists. Do something...');
}

I think it is good idea to create something like library to check image existence applicable for different situations. Above lots of great answers you can use to solve this task.

B. Bohdan
  • 480
  • 4
  • 12
1

Here is one function that I use to check any kind of URL. It will check response code is URL exists or not.

/*
 * Check is URL exists
 *
 * @param  $url           Some URL
 * @param  $strict        You can add it true to check only HTTP 200 Response code
 *                        or you can add some custom response code like 302, 304 etc.
 *
 * @return string or NULL
 */
function is_url_exists($url, $strict = false)
{
    if (is_int($strict) && $strict >= 100 && $strict < 600 || is_array($strict)) {
        if(is_array($strict)) {
            $response = $strict;
        } else {
            $response = [$strict];
        }
    } else if ($strict === true || $strict === 1) {
        $response = [200];
    } else {
        $response = [200,202,301,302,303];
    }
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,$url);
    curl_setopt($ch, CURLOPT_NOBODY, 1);
    curl_setopt($ch, CURLOPT_FAILONERROR, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $return = curl_exec($ch);
    if (!curl_errno($ch) && $return !== false) {
        return ( in_array(curl_getinfo($ch, CURLINFO_HTTP_CODE), $response) !== false );
    }
    return false;
}

This is exactly what you need.

Ivijan Stefan Stipić
  • 6,249
  • 6
  • 45
  • 78
1

You can use the file_get_contents function to access remote files. See http://php.net/manual/en/function.file-get-contents.php for details.

Kai
  • 9,038
  • 5
  • 28
  • 28
0

file_exists reads not only files, but also paths. so when $filename is empty, the command would run as if it's written like this:

file_exists("http://www.example.com/images/")

if the directory /images/ exists, the function will still return true.

I usually write it like this:

// !empty($filename) is to prevent an error when the variable is not defined
if (!empty($filename) && file_exists("http://www.example.com/images/$filename"))
{
    // do something
}
else
{
    // do other things
}
dapidmini
  • 1,490
  • 2
  • 23
  • 46
0

file_exists($filepath) will return a true result for a directory and full filepath, so is not always a solution when a filename is not passed.

is_file($filepath) will only return true for fully filepaths

PodTech.io
  • 4,874
  • 41
  • 24
0

you need server path with file_exists

for example

if (file_exists('/httpdocs/images/'.$filename)) {echo 'File exist'; }
Altravista
  • 357
  • 3
  • 12
0
if(@getimagesize($image_path)){
 ...}

Is working for me.

Safeer Ahmed
  • 587
  • 6
  • 14
0

Try it:

$imgFile = 'http://www.yourdomain.com/images/'.$fileName;
if (is_file($imgFile) && file_exists($imgFile)) {
    echo 'File exists';
} else {
    echo 'File not exist';
}

Another Way:

$imgFile = 'http://www.yourdomain.com/images/'.$fileName;
if (is_file($imgFile)) {.....
}
0

Read first 5 bytes form HTTP using fopen() and fread() then use this:

DEFINE("GIF_START","GIF");
DEFINE("PNG_START",pack("C",0x89)."PNG");
DEFINE("JPG_START",pack("CCCCCC",0xFF,0xD8,0xFF,0xE0,0x00,0x10)); 

to detect image.

Peter
  • 16,453
  • 8
  • 51
  • 77