사이트 내 전체검색
PHP
URL 이미지 존재 여부 확인 방법 / Check whether image exists on remote URL
로빈
https://cmd.kr/php/953 URL이 복사되었습니다.

본문

Use PHP To Check Whether Remote URL, Email Or Image Link Exist
In PHP, we have a built-in function file_exist that can help us to verify whether a particular file exist in our directory. However, do you ever have the need to check whether a particular URL, email or image link exist? We can use regular express to validate that the syntax of an email is correct but won't it be nice to reduce the amount of spam mail received? How about those images you have on your site? Won't you want to check whether there is a broken image or url link? Well, i have! Its always good to be informed in advance than meeting dissatisfy visitors. Anyway, in this article you will get to find and learn some of the more efficient and quicker ways to verify whether a particular link exist to use on your web application.

Check Remote Image Link Exist

There are many ways to check whether a particular image link exist after the introduce of PHP 5, GetImageSize. GetImageSize allows us to take in a remote link to retrieve the size of the image. Hence, we can do a simple check such as the one shown below,


 
1
2
3
4
5
6
$external_link = 'http://www.example.com/example.jpg';
if (@GetImageSize($external_link)) {
echo  "image exists ";
} else {
echo  "image does not exist ";
}
The above work well for any server that had GD installed. But there are more problem than just the one mention. This method is actually inefficient as it will download the entire image into your server before checking it. Thus, making the process very long. There might also be security risk as mention on Secure File Upload Check List that many image format allow comment to be embedded within the image and these comment might just be some PHP code that hacker has written. In short, this method download file from remote server to your server and take the risk of hacker using it to run malicious code after it has been downloaded on your server. BOMB! So if you are using the above method i advice you to change it and if you insist to use this, you can provide more validation checking for it. Just drop it.

So how do we check Image link in a more secure and quick environment? If you are using curl, you can try the following script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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;
    }
}
Like i said, this will depend on curl. However, it is secure and quick! How about the rest of us? Lucky, PHP also provides another method called file_get_contents. file_get_contents returns the file in a string, starting at the specified offset up to maxlen bytes. On failure, file_get_contents() will return FALSE. With these in mind we can create a function to check that the file downloaded is valid by taking only 1 bytes of information from the file. Hence, whatever evil things exist on the file will only be able to run 1 byte and furthermore the function returns a string where code cannot be run. Thus, this will gives us a simple solution such as the one below,

1
2
3
4
5
6
function url_exists($url) {
if(@file_get_contents($url,0,NULL,0,1))
{return 1;}
else
{ return 0;}
}
The above one is more secure than the initial one that we have and it has no dependency. The speed for this method is also faster than the initial one. But is there a faster one than the curl version?

Check For Remote URL Link

There are many ways to check whether a remote url link exist. However, checking Remote URL required the page to return certain header code to indicate that the page is successfully loaded (200). Hence, you might not want to use the method for checking image link for url link. Furthermore, For different cases you might be interested with different solution. Assuming you are just checking whether an existing domain exist, you can use the following code

1
2
3
4
5
6
function url_exists($url){
    if(strstr($url,  "http:// ")) $url = str_replace( "http:// ",  " ", $url);
    $fp = @fsockopen($url, 80);
    if($fp === false) return false;
    return true;
}
which is written by adam at darkhousemedia dot com. The above method definitely run faster than fopen but for https and domain names but for path url such as 'http://example.com?p=231', the above won't work although the speed is definitely one of the fastest.

Nonetheless, there are still better alternative than the one presented. We can just tried to check the header with the following code:

1
2
3
4
5
6
7
function url_exists($url){
    if ((strpos($url,  "http ")) === false) $url =  "http:// " . $url;
    if (is_array(@get_headers($url)))
          return true;
    else
          return false;
}
The above work perfectly without the need to worry about complex code. However, the above method only work for HTTP and PHP 5 and above, other lower version of PHP will not. Therefore, we will need some modification on the above method to cater for lower PHP version.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
function is_valid_url($url)
{
    $url = @parse_url($url);
    if (!$url)
    {
        return false;
    }
    $url = array_map('trim', $url);
    $url['port'] = (!isset($url['port'])) ? 80 : (int)$url['port'];
    $path = (isset($url['path'])) ? $url['path'] : '';
    if ($path == '')
    {
        $path = '/';
    }
    $path .= (isset($url['query'])) ?  "?$url[query] " : '';
    if (isset($url['host']) AND $url['host'] != gethostbyname($url['host']))
    {
        if (PHP_VERSION  >= 5)
        {
            $headers = get_headers( "$url[scheme]://$url[host]:$url[port]$path ");
        }
        else
        {
            $fp = fsockopen($url['host'], $url['port'], $errno, $errstr, 30);
            if (!$fp)
            {
                return false;
            }
            fputs($fp,  "HEAD $path HTTP/1.1\r\nHost: $url[host]\r\n\r\n ");
            $headers = fread($fp, 4096);
            fclose($fp);
        }
        $headers = (is_array($headers)) ? implode( "\n ", $headers) : $headers;
        return (bool)preg_match('#^HTTP/.*\s+[(200|301|302)]+\s#i', $headers);
    }
    return false;
}
The code here is the more detail version of the previous one which is created by SecondV on forums Dot digitalpoint Dot com. The above code cater for lower PHP version while still using the same approach of getting the return header value. Furthermore, it also validate the URL by using the parse_url method. f_open can also be used to check remote URL link.

1
2
3
4
5
6
7
function image_exist($url) {
    if (@fclose(@fopen( $url,  "r "))) {
    // true;
    } else {
    // false;
    }
}
However, this method required allow_url_fopen to be enabled on your php.ini file or else it will fail. Furthermore, i will not prefer this method over the previous one as it seems more sense that the page return success due to header code to indicate a success.

댓글목록

등록된 댓글이 없습니다.

PHP
871 (1/18P)

Search

Copyright © Cmd 명령어 3.137.180.32