Download doc file with php encoding error - php

I have a php code for downloading file based on file_id from URL. All works great, but i have problems with downloading files with extension .doc
Here is my code, what im doing wrong?
$file = mysql_fetch_array(mysql_query("SELECT * FROM ".sqlprefix."files WHERE id = '".$_GET['id']."'"));
$tmp = explode(".",$file['url']);
$tmp = $tmp[count($tmp)-1];
// $tmp = "doc";
switch ($tmp) {
case "pdf": $ctype="application/pdf"; break;
case "exe": $ctype="application/octet-stream"; break;
case "zip": $ctype="application/zip"; break;
case "docx": $ctype="application/vnd.openxmlformats-officedocument.wordprocessingml.document"; break;
case "doc": $ctype="application/msword"; break;
case "csv":
case "xls":
case "xlsx": $ctype="application/vnd.ms-excel"; break;
case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
case "gif": $ctype="image/gif"; break;
case "png": $ctype="image/png"; break;
case "jpeg":
case "jpg": $ctype="image/jpg"; break;
case "tif":
case "tiff": $ctype="image/tiff"; break;
case "psd": $ctype="image/psd"; break;
case "bmp": $ctype="image/bmp"; break;
case "ico": $ctype="image/vnd.microsoft.icon"; break;
default: $ctype="application/force-download";
}
$baseName = basename($file['url_del']);
$fileSize = filesize($file['url_del']);
$url = $file['url_del'];
// $ctype = "application/msword";
// $baseName = "File name with spaces and diacritic ěščěšč.doc"
// $fileSize = "214016"
// $url = "./files/File name with spaces and diacritic ěščěšč.doc";
header('Content-Description: File Transfer');
header('Content-Type: '.$ctype);
header('Content-Disposition: attachment; filename='.$baseName);
header('Expires: 0');
header('Pragma: public');
header('Content-Length: '.$fileSize);
readfile($url);
exit;
After downloading file in word i get this. I think, that problem must be in encoding...

Related

php readfile bad charset

I have a php code for downloading file based on file_id from URL. All works great, but I have problems with downloading files with extension .doc
Here is my code, what im doing wrong?
$file = mysql_fetch_array(mysql_query("SELECT * FROM ".sqlprefix."files WHERE id = '".$_GET['id']."'"));
$tmp = explode(".",$file['url']);
$tmp = $tmp[count($tmp)-1];
// $tmp = "doc";
switch ($tmp) {
case "pdf": $ctype="application/pdf"; break;
case "exe": $ctype="application/octet-stream"; break;
case "zip": $ctype="application/zip"; break;
case "docx": $ctype="application/vnd.openxmlformats-officedocument.wordprocessingml.document"; break;
case "doc": $ctype="application/msword"; break;
case "csv":
case "xls":
case "xlsx": $ctype="application/vnd.ms-excel"; break;
case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
case "gif": $ctype="image/gif"; break;
case "png": $ctype="image/png"; break;
case "jpeg":
case "jpg": $ctype="image/jpg"; break;
case "tif":
case "tiff": $ctype="image/tiff"; break;
case "psd": $ctype="image/psd"; break;
case "bmp": $ctype="image/bmp"; break;
case "ico": $ctype="image/vnd.microsoft.icon"; break;
default: $ctype="application/force-download";
}
$baseName = basename($file['url_del']);
$fileSize = filesize($file['url_del']);
$url = $file['url_del'];
// $ctype = "application/msword";
// $baseName = "File name with spaces and diacritic ěščěšč.doc"
// $fileSize = "214016"
// $url = "./files/File name with spaces and diacritic ěščěšč.doc";
header('Content-Description: File Transfer');
header('Content-Type: '.$ctype);
header('Content-Disposition: attachment; filename='.$baseName);
header('Expires: 0');
header('Pragma: public');
header('Content-Length: '.$fileSize);
readfile($url);
exit;
After downloading file in word I get this.
I think, that problem must be in encoding... enter image description here
It was terrible for me too.
I have found the slution here: PHP readfile() causing corrupt file downloads
Try to put this lines before readfile():
//clean all levels of output buffering
while (ob_get_level()) {
ob_end_clean();
}

Pass font file through PHP

I have a website that is set up like this:
client request --> gate.php --> requested file
Every request the client sends goes to gate.php were it is parsed. Gate.php then includes the requested file from a restricted directory so that the client cannot access any file but gate.php.
Gate file:
<?php
$_uri = strtok($_SERVER["REQUEST_URI"],'?');
$_root = "<root>";
// Index //
switch($_uri) {
case "/": $_uri = "<path>"; break;
case "/css": $_uri = "<path>"; break;
case "/js": $_uri = "<path>"; break;
case "/font": $_uri = "<path>".strtok($_GET["p"],".")."/".$_GET["p"]; break;
case "/ajax": $_uri = "<path>"; break;
case "/signin": $_uri = "<path>"; break;
case "/signup": $_uri = "<path>"; break;
default:
if(substr($_uri,0,8) == "/profile") { // profile
$_uri = "<path>";
$_page = substr($_uri,9);
} else {
header("HTTP/1.1 404");
require_once($_root."<path>");
die();
}
}
!isset($_page) and isset($_GET["p"]) ? $_page = $_GET["p"] : 0;
// Mime //
$_path = explode(".",$_uri);
switch($_path[1]) {
case "php": $_path[2] = "text/html"; break;
case "css": $_path[2] = "text/css"; break;
case "js": $_path[2] = "application/javascript"; break;
case "xml": $_path[2] = "application/xml"; break;
case "svg": $_path[2] = "application/xml+svg"; break;
case "jpg": $_path[2] = "image/jpeg"; break;
case "png": $_path[2] = "image/png"; break;
case "otf": $_path[2] = "x-font/otf"; break;
case "eot": $_path[2] = "x-font/eot"; break;
case "ttf": $_path[2] = "x-font/ttf"; break;
case "woff": $_path[2] = "x-font/woff"; break;
default:
header("HTTP/1.1 500");
require_once($_root."<path>");
die();
}
$_path[2] == "text/html" ? require_once($_root."<path>") : 0;
// File //
header("Content-Type: ".$_path[2]);
require_once($_root."/sys".$_uri);
?>
The problem is, when I pass a font file through the gate, the font file contains the text <? which PHP parses and returns an error.
Is there any way to escape the font file so that PHP does not parse it?
You can only require files that can be interpreted by PHP. If you want to serve other kinds of files through your script, you have to output them by reading them.
Something like:
$file = 'myfontfile.ttf';
if (file_exists($file)) {
header('Content-Type: application/octet-stream');
header('Content-Disposition: inline; filename="'.basename($file).'"');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}

How to show file size when force the browser to download in PHP

I'm downloading mp4,mp3 etc.. files from my server with php. But browsers are not showing the size of file.
I searched everywhere but i couldn't find any working answer. Hope you can help me. Thanks in advance.
Here is the code :
function force_download($file)
{
$ext = explode(".", $file);
switch($ext[sizeof($ext)-1])
{
case 'jar': $mime = "application/java-archive"; break;
case 'zip': $mime = "application/zip"; break;
case 'jpeg': $mime = "image/jpeg"; break;
case 'jpg': $mime = "image/jpg"; break;
case 'jad': $mime = "text/vnd.sun.j2me.app-descriptor"; break;
case "gif": $mime = "image/gif"; break;
case "png": $mime = "image/png"; break;
case "pdf": $mime = "application/pdf"; break;
case "txt": $mime = "text/plain"; break;
case "doc": $mime = "application/msword"; break;
case "ppt": $mime = "application/vnd.ms-powerpoint"; break;
case "wbmp": $mime = "image/vnd.wap.wbmp"; break;
case "wmlc": $mime = "application/vnd.wap.wmlc"; break;
case "mp4s": $mime = "application/mp4"; break;
case "ogg": $mime = "application/ogg"; break;
case "pls": $mime = "application/pls+xml"; break;
case "asf": $mime = "application/vnd.ms-asf"; break;
case "swf": $mime = "application/x-shockwave-flash"; break;
case "mp4": $mime = "video/mp4"; break;
case "m4a": $mime = "audio/mp4"; break;
case "m4p": $mime = "audio/mp4"; break;
case "mp4a": $mime = "audio/mp4"; break;
case "mp3": $mime = "audio/mpeg"; break;
case "m3a": $mime = "audio/mpeg"; break;
case "m2a": $mime = "audio/mpeg"; break;
case "mp2a": $mime = "audio/mpeg"; break;
case "mp2": $mime = "audio/mpeg"; break;
case "mpga": $mime = "audio/mpeg"; break;
case "wav": $mime = "audio/wav"; break;
case "m3u": $mime = "audio/x-mpegurl"; break;
case "bmp": $mime = "image/bmp"; break;
case "ico": $mime = "image/x-icon"; break;
case "3gp": $mime = "video/3gpp"; break;
case "3g2": $mime = "video/3gpp2"; break;
case "mp4v": $mime = "video/mp4"; break;
case "mpg4": $mime = "video/mp4"; break;
case "m2v": $mime = "video/mpeg"; break;
case "m1v": $mime = "video/mpeg"; break;
case "mpe": $mime = "video/mpeg"; break;
case "mpeg": $mime = "video/mpeg"; break;
case "mpg": $mime = "video/mpeg"; break;
case "mov": $mime = "video/quicktime"; break;
case "qt": $mime = "video/quicktime"; break;
case "avi": $mime = "video/x-msvideo"; break;
case "midi": $mime = "audio/midi"; break;
case "mid": $mime = "audio/mid"; break;
case "amr": $mime = "audio/amr"; break;
default: $mime = "application/force-download";
}
header('Content-Description: File Transfer');
header('Content-Type: '.$mime);
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);
}
if (isset($_POST['downl'])){
$file = "http://localhost/project1/downloads/gmf.mp4";
force_download($file);
}
<form method="POST" action=''>
<?php echo'<input type="submit" name="downl" value="Download Baby" >' ; ?>
</form>
If i try to show file size with echo filesize($file) it gives this error :
Warning: filesize(): stat failed for http://localhost/project1/downloads...
Since php 5.0.0 the file command supports http wrappers but the http wrapper does not support stat commands like size. So you cannot get the file size in your case with size.

Not able store docx,pdf,csv files in GridFs

I'm have using Php, MongoDb and GridFs to store and retrieve files. It works fine for images, but I want to store files with docx, pdf, csv and etc. extensions. Here is my code:
$ext = $this->getFileExt($_FILES["news_attachment"]["name"]);
switch ($ext) {
case 'pdf':
$mimeType = 'application/pdf';
break;
case 'doc':
$mimeType = 'application/msword';
break;
case 'docx':
$mimeType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
break;
case 'xls':
$mimeType = 'application/vnd.ms-excel';
break;
case 'xlsx':
$mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
break;
case 'ppt':
$mimeType = 'application/x-mspowerpoint';
break;
case 'pptx':
$mimeType = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
break;
case 'csv':
$mimeType = 'text/csv';
break;
case 'txt':
$mimeType = 'text/plain';
break;
default:
$mimeType='application/pdf';
}
$gridFs = $this->getGridFs();
$fileData = array(
"filename" => microtime(true) . "." . $ext,
"contentType" => $mimeType);
$_id = $gridFs->storeUpload("news_attachment", $fileData);
But I get the same error message Message: error setting up file: . I've checked the file size is 78kb, $fileData is ok also. So, my question is - What else can caused this error?
Would you not be supplying the same argument when trying to upload:
$gridFs->storeUpload($_FILES["news_attachment"]["name"],
or possibly
$gridFs->storeUpload($_FILES["news_attachment"]["tmp_name"],
I just need to add check for error if(!empty($_FILES["news_attachment"]) && $_FILES["news_attachment"]["error"] == 0){ save file}

Force download prompt php broken file

I have now the current code :
if($_POST['mode']=="save") {
$path = $_POST['path'];
$file = end(explode('/', $path));
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header("Content-Disposition: attachment; filename=$file");
readfile($file);
}
What i do is, get the path where the file is saved, explode it to only the file name and try to save that file. I do get the save as prompt, but when i save it and try to open the file i get the error message that the file/image is broken.
The files are not saved in the homedirectory but in a subdirectory called uploads.
Someone know what im doing wrong?
Thanks in advance.
Sinan
I normally use something like this:
$siteEmail = 'me#myemail.com';
$companyName = 'My Company';
# Path from server root
$fileDirectory = '/home/uploads/'; // include trailing slash
// get the file reference
$passedFile = $_POST['path'];
$filename = #urldecode($passedFile); // useful if your file is sent by $_GET
if((!isset($passedFile))||(#$passedFile=='')) {
echo "<html><title>".$companyName." - Download File</title><body>ERROR: Please pass a valid filename.<br /><br />Please go back and try again. If you continue to see this message please contact ".$siteEmail."</body></html>";exit();
}
// required for IE, otherwise Content-disposition is ignored
if(ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
$file_extension = strtolower(substr(strrchr($filename,"."),1));
if( $filename == "" ) {
echo "<html><title>".$companyName." - Download File</title><body>ERROR: download file NOT SPECIFIED.<br /><br />Please go back and try again. If you continue to see this message please contact ".$siteEmail."</body></html>";
exit;
} elseif ( ! file_exists( $fileDirectory . $filename ) ) {
echo "<html><title>".$companyName." - Download File</title><body>ERROR: File not found.<br /><br />Please go back and try again. If you continue to see this message please contact ".$siteEmail."
<p>path: ".$fileDirectory.$filename."</p>
<p>DOCUMENT_ROOT: ".$_SERVER['DOCUMENT_ROOT']."</p>
</body></html>";
exit;
};
switch( $file_extension ) {
case "pdf": $ctype="application/pdf"; break;
case "exe": $ctype="application/octet-stream"; break;
case "zip": $ctype="application/zip"; break;
case "doc": $ctype="application/msword"; break;
case "xls": $ctype="application/vnd.ms-excel"; break;
case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
case "rtf": $ctype="application/rtf"; break;
case "gif": $ctype="image/gif"; break;
case "png": $ctype="image/png"; break;
case "wav": $ctype="audio/wav"; break;
case "mp3": $ctype="audio/mpeg3"; break;
case "wmv": $ctype="video/x-ms-wmv"; break;
case "avi": $ctype="video/avi"; break;
case "asf": $ctype="video/x-ms-asf"; break;
case "mpg": $ctype="video/mpeg"; break;
case "mpeg": $ctype="video/mpeg"; break;
case "jpeg":
case "jpg": $ctype="image/jpg"; break;
default: $ctype="application/force-download";
}
// Everything went fine - you could log the download in the databse here if required?
// OUTPUT THE FILE
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // cache stop
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // cache stop
header("Cache-Control: must-revalidate"); // cache stop
header("Content-Type: $ctype"); // output filetype
header("Content-Disposition: attachment; filename=\"".basename($filename)."\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($fileDirectory.$filename));
readfile($fileDirectory.$filename);
exit();

Categories