Retrieving a file outside root, avoid cutting off filename which contain spaces - php

I have uploaded files to a folder outside my webroot folder and use some php code to retrieve the file after being authenticated by database. My code below seems to work, i.e. retrieves the file, the only issue I have is, the pdfs uploaded contain filenames with spaces and the code below seems to only retrieve the first word before the space.
The example filenames are
My Trip To London.pdf
Wildlife Photography Part 1.pdf
Apart from going through the database and phuycical files and substituting each file to contain an underscore instead of a space, is there a way I can alter the code below so it retrieves the whole filename?
I thought I could substitute the filename with with %20 if it detected a space but that doesn't work.
/* Done some processing above to retrieve the $filename for the pdf */
$file = 'h:'.$filename;
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;

the pdfs uploaded contain filenames with spaces and the code below seems to only retrieve the first word before the space.
Quote the name:
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
or in clearer form:
header(sprintf('Content-Disposition: attachment; filename="%s"', basename($file)));

Related

How force download an .xlsx file in PHP without having it corrupted?

None of the already existing questions have helped me.
I'm trying to force download an excel file with the file type .xlsx. It works perfectly fine in a download code like this:
echo "<a href='" . $dateiname . "'>Datei herunterladen</a>";
But whenever I try to make a forced download, it doesn't work. I've tried various headers from various questions on stackoverflow, the last two being
header('Content-type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $dateiname . '"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Pragma: no-cache');
header('Content-Length: ' . filesize($dateiname));
$objWriter->save('php://output');
and
header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
header("Content-Transfer-Encoding: binary ");
header('Content-Disposition: attachment; filename='.basename($dateiname));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($dateiname));
$objWriter->save('php://output');
I tried both in the same file as where I create the file, but also in a separate file, but either way I always get the error:
Excel cannot open the file (filename) because the file format or file extension is not valid. Verify that the file has not been corruted and that the file extension matches the format of the file.
The file itself on my server seems perfectly fine.
I've found how I used PHPExcel to force downloading an xlsfile.
header("Content-Disposition: attachment; filename={$fileName}.{$fileFormat}");
header("Content-Type: application/vnd.ms-excel;");
header("Cache-Control: max-age=0");
$objWriter->save('php://output');
Hope it helps.

How do I force download of a file through Flysystem?

I may be missing something exceptionally obvious here, but I'm using yii2-flysystem along with Dropbox to read and write files.
I can upload and write them to Dropbox with no problem but then, when reading like this:
$file = Yii::$app->dropboxFs->read($fn);
..all that gives me is a string (/tmp/phpQkg8mJ).
How do I actually force the download of the file that I'm reading? I'm not sure what that temporary file location actually relates to.
Try function readfile().
According to example, your code should be looks something like this:
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}

Why data is changed after uploading xml file PHP

i have the code to upload xml file using dom.
if (!$dom->load($folderName . "/" . $fvalue)) {
echo "<br>".$fvalue." file is corrupt or Tags are not closed properly ";
}
it uploads the file BUT after uploading, there are 3 whitespaces in the start of the file before any xml Tag. Problem is we download uploaded file and upload again. but with whitespaces in the start of the file, dom dont allow to upload the file as it is corrupted.(i check the validation of xml using xmlvalidation.com) which returns error because there are spaces at the start. if i remove space manually than no error.
How i can upload the file without adding spaces at the start ?
I checked to remove spaces from file etc. but i dont want to do that. i want to upload the file without changing.
problem was with downloading the file. after download there was some spaces in the start of the file. code was
header("Content-type: application/force-download; charset=utf-8");
header("Content-type: application/force-download");
header("Content-disposition: attachment;filename=" . $downFileName);
readfile($filename);
i changed to this and it's working fine now.
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($downFileName));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($filename));
ob_clean();
flush();
readfile($filename);

getting a file from outside the document root. PHP

I am currently storing docx files and pdf files in a user upload folder outside the doc root. I intend for these files to be downloaded via a db link to the heavily scrambled file name.
Previously I have only obtained data from files outside the root with PHP - is it possible to retrieve whole files from this area and if so how does one go about it.
<?php
$file_id = $_GET['id'];
$local_path = get_real_filelocation_from_id($file_id);
readfile($local_path);
The code for get_real_filelocation_from_id() is left as an exercise for the OP.
<?php
$get_file=$_GET['file_name'];
$file = '/path/to/uploads/'.$get_file;
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
?>
After many hours of searching I found this that seems to work. Unfortunately, although the symbolic link root seemed to be a good path to follow I am unsure of how to actually implement it - firebug goes into quirks mode when I try even the most basic script.

PHP - What are the correct headers for downloading file?

I have a piece of code that allow users download file from server (document such as docs,docx,pdf etc).
Users can download files but it has some errors like the files were broken. For example, a MS Word file after download need to recovery to read content.
I wonder that if there is any mistake in this code (or problem when uploading?).
$size_of_file = filesize($download_path);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $file_name);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . $size_of_file);
//read file from physical path
readfile($download_path);
Did you try like this ?
<?php
header("Content-type: application/vnd.ms-word");
header("Content-Disposition: attachment; Filename=SaveAsWordDoc.doc");
?>
I found the root of the problem, I hav some extra spaces after php close tag. Thank you guys.

Categories