简体   繁体   中英

How to set the filename of a file generated in PHP

A newb question – I need to set the filename of a file generated in PHP (tcpdf to be specific) to the variable $number. At the moment I have written it to put the same filename each time.

  1. How do I set the downloaded file name to be the variables set in generatereport.php?

  2. How do I pass the variables from reports.php to report.php?

I have two files:

generatereport.php which creates the report

reports.php which gets requests from the webpage and serves the file generated for download

Here is my code:

In generatereport.php this is what generates the file using tcpdf

$string = $pdf->Output(’Site '.$number.' '.$date.'.pdf', 'S');
return $string;

In report.php:

   function downloadFile($data,$name) {
        header("Cache-Control: public");
        header("Content-Description: File Transfer");
        header("Content-Disposition: attachment; filename=$name");
        header("Content-Type: mime/type");
        header("Content-Transfer-Encoding: binary");
        // UPDATE: Add the below line to show file size during download.
        header('Content-Length: ' . strlen($data));
        echo $data;
    }    


    if (isset($_GET['reportType'])) {
        switch ($_GET['reportType']) {
            case 'report3':
                downloadFile(reports::report3($_GET['id']),"report.pdf");
                break;
 case 'report1':
                downloadFile(reports::xlsReport1($_GET['id']),"report1.xlsx");
                break;
        }
    }

Thank you!

You could try something like this...

Change generatereport.php to return an array with two elements, the first one being the file name and the second one being the data:

$filename = 'Site '.$number.' '.$date.'.pdf';
$string = $pdf->Output($filename, 'S');
return array($string, $filename);

Then modify the second chunk of code in report.php to handle the new return type:

if (isset($_GET['reportType'])) {
    switch ($_GET['reportType']) {
        case 'report3':
            list($data, $filename) = reports::report3($_GET['id']); 
            downloadFile($data, $filename);
            break;
        case 'report1':
            list($data, $filename) = reports::xlsReport1($_GET['id']);
            downloadFile($data, $filename);
            break;
    }
}

This assumes that you change the XLS generation function to return an array containing the data and file name as well.

I'm not 100% clear on your code structure, but the essential element that solves your problem is the idea of returning an array instead of a string from the report generation functions, where one element of the array contains the data and the other element contains the filename.

Having dealt with this kind of problem a million times, may I also suggest two other areas that may need some improvement.

The first one is file paths. Unless every single file of your application is in the same folder, including temporary files (which would be a really bad idea), you are going to want to pass back a file name that includes some path information (eg. 'temp/reportfiles/report3.pdf'). However, when you are setting the name in the output header, you will only want the file name part, eg. report3.pdf. So you might want to change that one line of code in the downloadFile() method as follows:

   header("Content-Disposition: attachment; filename=" . basename($name));

Finally, when you set the MIME type, you need to set it to an actual type. There are many ways to figure out the MIME type, but I tend to use the following helper function:

function getMimeType( $filename )
{
    switch( pathinfo( $filename, PATHINFO_EXTENSION ))
    {
        case 'csv':
            return 'text/csv';

        case 'pptx':
            return 'application/vnd.openxmlformats-officedocument.presentationml.presentation';

        case 'pdf':
            return 'application/pdf';

        case 'xls':
            return 'application/vnd.ms-excel';

        case 'png':
        case 'jpg':
        case 'jpeg':
        case 'gif':
            return 'application/image';

        case 'zip':
            return 'application/zip';

        default:
            return 'application/octet-stream';
    }
}

You would need to change the following line in downloadFile() to use this function:

    header("Content-Type: " . getMimeType($name));

I hope that all helps. Good luck with your coding!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM