Download Remote File - php

I have a function that will be passed in a link. The link is to a remote image. I thought I could just use the extension of the file in the URL to determine the type of image but some URLs won't have extensions in the URL. They probably just push headers to the browser and therefore I do not have an extension to parse from the URL.
How can I test if the URL has an extension and if not then read the headers to determine the file type?
Am I over complicating things here? Is there an easier way to do this? I am making use of Codeigniter maybe there is something already built in to do this?
All I really want to do is download an
image from a URL with the correct
extension.
This is what I have so far.
function get_image($image_link){
$remoteFile = $image_link;
$ext = ''; //some URLs might not have an extension
$file = fopen($remoteFile, "r");
if (!$file) {
return false;
}else{
$line = '';
while (!feof ($file)) {
$line .= fgets ($file, 4096);
}
$file_name = time().$ext;
file_put_contents($file_name, $line);
}
fclose($file);
}
Thanks all for any help

You never want to switch on the file extension. For example, not all ASCII text files will have ".txt", and then there's always the fun ".jpg" versus ".jpeg". Instead, switch on the Content-Type header that the web server responds with. (See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17).
Some web servers will also respect the Accept header (see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1). So, if you know you only want PNG image files, then send Accept: image/png. If the server respects it, then its response will be much smaller than sending the whole unwanted file over the network connection. However, because not all web servers do this well (if at all), make sure you still switch on the Content-Type response header. It's just a bandwidth saving thing.
You could also send Accept: image/* to get any type of image.
Cheers.

You should always use the Content-Type response header to determine the type of data received. From that you can set the correct extension. URLs do not have extensions, and you should not rely on anything after a period being such.

You won't be able to read headers using fsock/fread or even file_get_contents. That's all hidden away in the background and discarded when the retrieval finishes. You'll have to use the CURL functions and set up a proper HTTP GET session using that, from which you can retrieve full details of the transfer.

Related

Mask Image URL and make it look like its on your web server

How would i go about making a page called banner.php on my site and have that page look up a banner id in my db (already know how to look it up and fetch the url), but how would i go about making it seem like its the actual image destination if i wanted to use myurl.com/banner.php?bid=3 in a tag on someone else's website.
Regards,
Jarrod
Anyone who can help on how to do this its appreciated!
In your banner.php you have to actually load the image from its real server and output it again in your banner.php. Be sure to send the correct Content-Type header, so the browsers take your PHP-file as an image.
The quickest code for your banner.php I can imagine for a jpeg-image may look like this:
<?php
$imageContents = file_get_contents('http://example.com/real-banner.jpg');
header('Content-Type: image/jpeg');
echo $imageContents;
When a user then calls http://your-domain.com/banner.php it is shown as an image in the browser, not knowing where its original source was.
Hints:
Change the header Content-Type to image/png or image/gif depending on the image type.
If you are using file_get_contents(), be sure that your server support fopen wrappers, otherwise using URLs in file_get_contents() won't work. See the Notes-Section of file_get_contents()
Another method for getting content from another server would be the PHP curl library
Edit:
If you want to output the same header the original image has, you can iterate through the variable $http_response_header which gets autofilled with the headers after a file_get_contents call. Search for the Content-Type header and output it the same.
<?php
$imageContents = file_get_contents('http://example.com/real-banner.jpg');
// get the content type header out of the file_get_contents request
foreach ($http_response_header as $header) {
if (strtolower(substr($header, 0, 13)) == 'content-type:') {
$origContentTypeHeader = $header;
break;
}
}
header($origContentTypeHeader);
echo $imageContents;

How to get MIME-type of an image with file_get_contents in PHP

I need to get the MIME type of an image, but I only have the body of the image which I've got with file_get_contents. Is there a possibility to get the MIME type?
Yes, you can get it like this.
$file_info = new finfo(FILEINFO_MIME_TYPE);
$mime_type = $file_info->buffer(file_get_contents($image_url));
echo $mime_type;
If you download a file using HTTP, do not guess (aka autodetect) the MIME type. Even if you downloaded the file using file_get_contents, you can still access HTTP headers.
Use $http_response_header to retrieve headers of the last file_get_contents call (or any call with http[s]:// wrapper).
$contents = file_get_contents("https://www.example.com/image.jpg");
$headers = implode("\n", $http_response_header);
if (preg_match_all("/^content-type\s*:\s*(.*)$/mi", $headers, $matches)) {
$content_type = end($matches[1]);
echo "Content-Type is '$content_type'\n";
}
Resort to the autodetections only if the server fails to provide the Content-Type (or provides only a generic catch-all type, like application/octet-stream).
Be very careful what you do by checking only the Mime Type! If you really want to be sure that an image is actually an image, the safest way to do this is open it with an image manipulation library and write it with the library. This will both fail if the image is actually malicious code and guarantee that you are actually writing an image file to the disk. Just as an example for this, you can easily trick MIME into thinking that some malicious code is GIF.
To answer your questions more directly, use the FileInfo PECL module.

getting file information via url in php

like file upload there are
<?php
$_FILES['file']['tmp_name'];
$_FILES['file']['name'];
$_FILES['file']['size'];
$_FILES['file']['type'];
?>
now.
i have a file that is sitting on my other web server, and i want to get the name size and mime type of that file via url.. is this possible?..
i've alreay tried to use this code below. but it doesn't work
$url = "http://mydomain.com/myfile.rar";
filesize ( $url );
mime_content_type ( $url );
You can try native php function get_headers it's very fast way to read file data
You can't do it like this. The information you get when you use $_FILES is meta-information that is sent along with the file (and the size can even be calculated after the file is retrieved).
You cannot get this information like that, but you can download the actual file and inspect the header information to get that information. To do this, read about curl, which allows you to do HTTP requests to another server.
It might be possible to request just the headers, so you get the information without getting the file, which is obviously more efficient.
Another solution is to implement a file-info script on the other server that allows you to get the file info.
So you could request http://mydomain.com/fileinfo.php?file=myfile.rar. In fileinfo.php you can get all the file info of the given file and just echo it.

Server-side, get progress on sending file

Basically, what I want to do is to check how much of a file my webserver has sent to a client, when the client is downloading one. Is this even possible?
Does apache provide any module/extension that would help me accomplish my task?
I use a linux distro, apache2 and php5. Regards.
Browser provides this functionality if file has correct "Content-length" header set. Why do you want to implement this in your page?
Solved it.
I simply open the file with PHP that I want to send to the client.
$fh = fopen($filePath, 'r');
Then I calculate 60% of the filesize by writing
$fileSize = filesize($filePath);
$sizeFirst = floor(($fileSize / 100) * 60);
Now the $sizeFirst variable contains the length of the first 60% of the file, in a numeric value.
To calculate the rest 40% I use:
$sizeLast = $fileSize - $sizeFirst;
Now I can write out the first 60%, do my action, and then write outh the rest 40%.
$dataFirst = fread($fh, $sizeFirst);
echo($dataDirst);
// Do my action here.
$dataSecond = fread($fh, $sizeSecond);
echo($dataSecond);
exit();
I need to set the header(); before writing out this, the Content-length, Content-type and Content-Disposition must be set in order to send a valid header and filecontent to the client.
Hope it helps someone.

Best way to store an image from a url in php?

I would like to know the best way to save an image from a URL in php.
At the moment I am using
file_put_contents($pk, file_get_contents($PIC_URL));
which is not ideal. I am unable to use curl. Is there a method specifically for this?
Using file_get_contents is fine, unless the file is very large. In that case, you don't really need to be holding the entire thing in memory.
For a large retrieval, you could fopen the remote file, fread it, say, 32KB at a time, and fwrite it locally in a loop until all the file has been read.
For example:
$fout = fopen('/tmp/verylarge.jpeg', 'w');
$fin = fopen("http://www.example.com/verylarge.jpeg", "rb");
while (!feof($fin)) {
$buffer= fread($fin, 32*1024);
fwrite($fout,$buffer);
}
fclose($fin);
fclose($fout);
(Devoid of error checking for simplicity!)
Alternatively, you could forego using the url wrappers and use a class like PEAR's HTTP_Request, or roll your own HTTP client code using fsockopen etc. This would enable you to do efficient things like send If-Modified-Since headers if you are maintaining a cache of remote files.
I'd recommend using Paul Dixon's strategy, but replacing fopen with fsockopen(). The reason is that some server configurations disallow URL access for fopen() and file_get_contents(). The setting may be found in php.ini and is called allow_url_fopen.

Categories