Check if URL is an image? - php

This has been asked before, but most, if not all answers, were either solutions that didn't work in all situations or were unnecessary (like using getimagesize(), which downloads the entire image).
How would I check if a given URL leads to an image without having to hardcode image extensions (like .png', .jpg, etc.)?

You can read only file header by CURL and then detect if the header is image header or not.
curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $file_url);
curl_setopt($curl, CURLOPT_NOBODY, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$header = curl_exec($curl);
curl_close($curl);
if (strstr($header, 'image/png')) {
//file is image
}

Related

How to display remote image in php webpage

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://www.example.com/xxx.png');
curl_setopt($curl, CURLOPT_REFERER, 'http://www.example.com');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
header('Content-type:image/PNG');
echo $result;
curl_close($curl);
The function header() didn't work, it always dispalyed binary data.
Maybe because I used these codes in the middle of webpage what has existed.
The webpage outputed some texts before header(), so it didn't work.
I want to get image by url, and display image directly, no need save file to disc.
So how can I do ? Please help me !!!
—————————
I need set referer, so I used curl.
Use the image directly as follows:
<img src ='http://www.example.com/xxx.png'>

How to figure out type of the image before downloading it?

I know I can save an image using the following method:
$input = 'http://images.websnapr.com/?size=size&key=Y64Q44QLt12u&url=http://google.com';
$output = 'google.com.jpg'; // << How to save the image with proper extension?
file_put_contents($output, file_get_contents($input));
But what if I don't know the format of the downloaded image? What if it's "png"? How can I figure out the type of target image before saving it?
The best thing to do is just download it and rename the file later. That way, you only have to make one request.
Another thing you can do however is make an HTTP HEAD request. This gets all of the response headers, including the Content-Type header, so you can decide if you want that data or not before you download the file. However, not all servers support HEAD requests.
In any case, cURL is the easiest way to do this:
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, 'http://www.example.com/something');
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_HEADER, true);
$headers = curl_exec($ch);

How can I tell if a URL points to an image?

I have a php page with a text input where the user is supposed to paste a remote URL of an image, and I will have to store it in the server and display it to the user. Now the problem is, I don't trust a user will always provide a proper image url, and I don't want them to upload a pdf or other file, or a huge, few gb worth of file. Now I can check the extension, but that isn't very helpful, and I hear I can check the mime-type, but I don't know how I can open the file once and check all the validations like mime-type and file size in one go, and then copy the file over. Moreover, since the file will be pretty much served as it is(with a minor name change), I would like to know if it is possible to make sure that the file doesn't have any injected virus or problematic code.
Any suggestions appreciated.
You can use exif_imagetype() to see if its an image.
If you want to be 100% sure that its not malware or something weird. its a good idea to use the GD library and save it via the GD library. So there is no dangerous code inside.
Well there are really multiple things that can be done here. I would suggest using cURL as your mechanism for transferring the file (rather than file_get_contents() or similar). The reason for this is that you can first send a HEAD request against the resource to just get the header information before committing to actually download it. From the headers, you should be able to evaluate the file name, file size, mime-type information, etc. Note that NONE of this information should be trusted, but it at least gives you a sanity check before committing to the file download.
Once you have done the sanity check, you can download the file into a local snadbox directory. This should not be a web-accessible directory. You could use exif_imagetype() to determine if the file is indeed an image of the type you are interested in.
Assuming this all looks good, I would just do the last bit of cleanup-and renaming in GD library (perhaps use imagecreatefrom*() functions to make final image from the temp download file).
With Curl you have no problem with https, you may store a file and check it.
Here is the code to check content-type for image then file is checked with exif_imagetype() (enable php_mbstring and php_exif extentions).
$url = 'https://www.google.com/images/icons/ui/doodle_plus/doodle_plus_google_logo_on_grey.gif';
$userAgent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_exec( $ch ) ;
if(!curl_errno($ch))
{
$type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
if ( stripos($type, 'image') !== FALSE )
{
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch, CURLOPT_HEADER, false);
$filename = tempnam('/path/to/store/file/', 'prefix');
$fp=fopen($filename,'wb');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_exec($ch);
fclose($fp);
if ( exif_imagetype($filename) !== FALSE )
{
echo "100% IMAGE!";
// take it!
}
unlink($filename);
}
}
curl_close($ch);

Can I use a URL as the source for imagecreatefromjpeg() without enabling fopen wrappers?

I know it’s possible to use imagecreatefromjpeg(), imagecreatefrompng(), etc. with a URL as the ‘filename’ with fopen(), but I'm unable to enable the wrappers due to security issues. Is there a way to pass a URL to imagecreatefromX() without enabling them?
I’ve also tried using cURL, and that too is giving me problems:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://www.../image31.jpg"); //Actually complete URL to image
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
curl_close($ch);
$image = imagecreatefromstring($data);
var_dump($image);
imagepng($image);
imagedestroy($image);
You can download the file using cURL then pipe the result into imagecreatefromstring.
Example:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $imageurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // good edit, thanks!
curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); // also, this seems wise considering output is image.
$data = curl_exec($ch);
curl_close($ch);
$image = imagecreatefromstring($data);
You could even implement a cURL based stream wrapper for 'http' using stream_wrapper_register.
You could always download the image (e.g. with cURL) to a temporary file, and then load the image from that file.

How to know size of flv size from url?

If I know flv video,
for example:
www.domain.com/video.flv
I can't use "filesize" because it doesn't able to check size from external url, right?
So, how can I know his size?
You can use CURL to get the headers of a remote file, including the size of a file.
$url = 'http://www.domain.com/video.flv';
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$headers = curl_exec($ch);
$size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
curl_close($ch);
Setting CURLOPT_NOBODY to true, makes CURL not download the body of a requested URL.
You could use CURL to send a HTTP HEAD request to the URL you want to know the file size of. The server should send back a content-length header in its response, listing the filesize in octets (bytes).
The server isn't necessarially going to actually send the content-length header though. If it doesn't, then your only option is to actually download the file in full.
I can't use "filesize" because it doesn't able to check size from external url, right?
Yes it can do that, but it's a bit ridiculous to do so, because the url wrappers will first download the file and then check its size.
You could do a HEAD request, which will ask the server for the file size without requesting the file data.
Relevant snippet here:
http://snippets.dzone.com/posts/show/1207

Categories