Read the name or type of a remote file opened with "fopen"

Asked

Viewed 456 times

1

In my PHP script I have a line that reads a file with fopen, using the url "https://api.modarchive.org/downloads.php?moduleid=".$i ($i is an accountant of a loop) where I save the file in the variable $file, and I want to save it on my computer using file_put_contents(), only that for this, I need to set the path which I want to save, including the file extension.

The problem is that you can not know the file extension downloaded only by URL, so you can not use pathinfo(), nor explode, nor any kind of function that uses the file path as parameter, I can actually download the file, but setting a default extension, or not setting.

The problem is that the original files have extensions and types that vary.

The code that I try to run currently is this:

for($i = 1; $i < 5; $i ++){
    $file = fopen("https://api.modarchive.org/downloads.php?moduleid=".$i, 'r');
    file_put_contents("mods/mod".$i.".extensaodoarquivo", $file);
}

Is there any function that returns the file name or extension, perhaps passing as parameter the file itself, instead of a string representing his path, or some better solution?

1 answer

3


Simplest solution, the $http_response_header:

The variable $http_response_header is of great help in the URL of your question.

When you use fopen() in remote resources, it is automatically populated with the request header.

To see the format of the data, just this:

$file = fopen("https://api.modarchive.org/downloads.php?moduleid=".$i, 'r');
var_dump($http_response_header);

A line is of special interest to us:

Content-Disposition: attachment; filename=nomedoarquivo.it

As the name is already listed, just iterate the returned array, to locate the desired line, and extract the name:

$file = fopen("https://api.modarchive.org/downloads.php?moduleid=".$i, 'r');
$filename = '';
foreach( $http_response_header as $header ) {
    if( strtolower( substr( $header, 0, 20 ) ) === "content-disposition:" ) {
        $filename = substr( strstr( $header, '=' ), 1 );
    }
}

echo 'o nome original é: '.$filename

if the header desired exist, $filename will be populated with the original name.


Other possibilities:

A possible solution if we didn’t have the name in the headers would be the function

mime_content_type( $file )

She will return the mime-type file analysis based on file magic.mime.

The format of the return is this:

image/gif
image/png
application/x-7z-compressed
... etc ...

In the documentation itself has some example functions to make a array of extensions and types with ease.

Important: for better performance and bandwidth utilization, you can test the file after received and then rename it, avoiding two unnecessarily remote accesses.

Handbook:

http://php.net/manual/en/function.mime-content-type.php


Alternatively you can use functions fileinfo:

<?php
  $fi = new finfo( FILEINFO_MIME,'/usr/share/file/magic' );
  $mime_type = $fi->buffer( file_get_contents($file) );
?>

Handbook:

http://us3.php.net/manual/en/ref.fileinfo.php


Both functions are file-based mime.magic, which is commonly available on Linux servers, and also distributed with PHP if needed on other systems.

The mime.magic contains some position maps and strategic bytes, which serve to characterize the files by their actual content.

  • I don’t think I need it anymore, I found this function get_headers() that the position [7] gives me the name of the file and the extension,I can use this to get the file extension without problems

  • has better things: var_dump($http_response_header); that’s what I’m putting in the answer

  • The ideal is the response loop, because nothing guarantees that the order and quantity of the headers is the same in all calls. It worked pretty well the question code, test here: http://files.box.net.br/file.htm?i=7 (Change i to see the name change)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.