Force downloading files with foreign characters - php

How can I force the download of files whose file name contains more characters than English, for example Swedish, Norwegian like ö ä å . It's working perfect if the file is without ö ä å but not if file name holds Swedish characters.
The following is the code that I use to open files.
$file_id = $_GET['f'];
$sql = " SELECT * ".
" FROM attachment ".
" WHERE attachment_id = ".$file_id." ".
$res = mysql_query($sql);
$row = mysql_fetch_array($res);
$filename = $row['filename'];
$USER_ID = $row['user_id'];
$DIRECTORY_ID = $row['directory_id'];
$target_path = "upload/".$USER_ID."/".$DIRECTORY_ID."/";
// And the function is :
function Download($path, $speed = null)
{
if (is_file($path) === true)
{
$file = #fopen($path, 'rb');
$speed = (isset($speed) === true) ? round($speed * 1024) : 524288;
if (is_resource($file) === true)
{
set_time_limit(0);
ignore_user_abort(false);
while (ob_get_level() > 0)
{
ob_end_clean();
}
header('Expires: 0');
header('Pragma: public');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . sprintf('%u', filesize($path)));
header('Content-Disposition: attachment; filename="' . basename($path) . '"');
header('Content-Transfer-Encoding: binary');
while (feof($file) !== true)
{
echo fread($file, $speed);
while (ob_get_level() > 0)
{
ob_end_flush();
}
flush();
sleep(1);
}
fclose($file);
}
exit();
}
return false;
}
Download($target_path.$filename);
I have used:
$filename = urlencode($filename);
$filename = htmlentities($filename, ENT_QUOTES, "UTF-8");
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
and
$path = iconv('UTF-8', 'ASCII//TRANSLIT', $path)
But nothing is working.
I want to thank you in advance and Any help you can give will be greatly appreciated.
Jonas.

use this:
<?php
header('Content-Type: text/html; charset=utf-8');
?>
and be sure that you save your PHP Source file as utf-8.

Related

PHP text file auto download giving error headers already sent

I am uploading text file and then converting it after conversion I am forcing it to auto download that converted text file, but it's not getting downloaded, giving error Warning: Cannot modify header information - headers already sent
Force download text file PHP code
if (file_exists($fileCreate)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($fileCreate));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($fileCreate));
ob_clean();
flush();
readfile($fileCreate);
exit;
}
}
Full PHP code
<?php
error_reporting(E_ALL & ~E_NOTICE);
if(!empty($_FILES['uploaded_file']))
{
$path = "upload/";
$path = $path . basename( $_FILES['uploaded_file']['name']);
if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $path)) {
echo "The file ". basename( $_FILES['uploaded_file']['name']).
" has been uploaded";
} else{
echo "There was an error uploading the file, please try again!";
}
$count = 0;
$fileCreate = 'order-'.date('m-d-Y').".txt";
$myfile = fopen("$fileCreate","w") or die("Unable to open file!");
fwrite($myfile, "1"."\n");
if($file = fopen("$path", "r")){
while(!feof($file)) {
$line = fgets($file);
$keywords = preg_split("/[\s,]+/", $line);
$x = $keywords[2];
$y = 5;
$y .= $x;
$y .= "001";
$date = $keywords[1];
$date1 = str_replace('"','',$date);
$newDate = date("Y/m/d", strtotime($date1));
$y .= str_replace("/", "", $newDate);
$y .= " ";
$fso = $keywords[3];
$fso = str_replace('"','',$fso);
$y .= $keywords[3];
if($fso != "FPO" || $fso != "APO"){
$y .= $keywords[4];
}
$y = str_replace('"','',$y);
$storeValue[$count]=$y;
fwrite($myfile, $y."\n");
$count++;
}
$str = strval($count);
$strlen = strlen($str);
if($strlen == 1){
$footer = 900000;
}
else if($strlen == 2){
$footer = 90000;
}
else if($strlen == 3){
$footer = 9000;
}
else if($strlen == 4){
$footer = 900;
}
else if($strlen == 5){
$footer = 90;
}
else{
$footer = 9;
}
$footer .= $count;
$footerDate = date("Y/m/d");
$footer .= str_replace("/", "", $footerDate);
fwrite($myfile, $footer."\n");
fclose($file);
}
if (file_exists($fileCreate)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($fileCreate));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($fileCreate));
ob_clean();
flush();
readfile($fileCreate);
exit;
}
}
?>
UPDATE: It's fixed by adding output_buffering = ON in php.ini file
Two things.
1) You need to start session immediately after the <?php
2) You session redirect does not work if something output before the session redirect (header location).
What you can do is,
You can use javascript for redirecting.
echo '<script>window.location.replace("http://stackoverflow.com");</script>';
Anyway if you are using sessions, start session on the top of page (session_start()).
<?php
session_start();
error_reporting(E_ALL & ~E_NOTICE);
if(!empty($_FILES['uploaded_file']))
Update
It's fixed by adding output_buffering = ON in php.ini file

Resume Download Links in PHP

The following file (which I don't understand it at all) serves my requested file and makes it ready to be downloaded. But, the links that are created and served by this file miss really important items when downloading by IDM.
File size: (unknown), Time left (unknown) , Resume capability (unknown).
Very unprofessional and bad in all aspects. What should I do as a novice?
if (isset($status) && ($status == 'd')) { //if Every Thing Is Fine The Download Start
$filename = $url;
$extension = fileexten($filename);
$fakename = fakefilename($downcode);
$mime = contenttype($extension);
// set_time_limit(0);
if ($notadownload == FALSE) {
header('Pragma: public');
header('Expires: 0');
header("Content-Type:" . $mime);
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Disposition: attachment;filename=' . $fakename . '.' . $extension);
header("Content-Transfer-Encoding: binary");
ob_clean();
flush();
#readfile($filename);
} else {
$mime = getContentType($filename);
header("Content-Type:" . $mime);
if (strpos($mime, 'text') == FALSE) {
$extension = fileexten($filename);
header('Content-Disposition: inline;filename=' . $fakename . '.' . $extension);
}
echo #file_get_contents($filename);
}
}

Not able to download files with php in android browsers

When using computer files are downloaded normally.
Problem start on android browsers.
When we download a file from android default browser, the file is downloaded but it is of 0.00 bytes, so not technically present there(corrupt file).
When we download file from any third party application like or opera it gives error that "file could not be downloaded." not the header error. And files could be downloaded via UC Browser and Chrome and Firefox. But still gives the error in default browser.
Here is the code I am using:
<?php
require 'php/db.php';
if(isset($_POST['file_id'])&&!empty($_POST['file_id'])){
download_file($_POST['file_id']);
}
function download_file($id){
global $con;
$id = mysqli_real_escape_string($con,htmlentities($id));
$file="SELECT file_name,file_title,file_size,down FROM files WHERE file_id= $id";
$result = mysqli_query($con,$file);
$row = mysqli_fetch_assoc($result);
$name = $row['file_name'];
$title = $row['file_title'];
$size = $row['file_size'];
$ext = strtoupper(ext($name)); // Function defined bellow
$down = $row['down'];
$newname = $title.'.'.$ext;
$olddir = "files/".$name;
$down++;
if(is_file($olddir)) {
$update_down = "UPDATE files SET down = $down WHERE file_id = '$id'";
$update_down_result = mysqli_query($con,$update_down);
header('Pragma: public'); // required
header('Expires: 0'); // no cache
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Last-Modified: '.gmdate ('D, d M Y H:i:s', filemtime ($olddir)).' GMT');
header('Cache-Control: private',false);
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$newname.'"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.$size); // provide file size
header('Connection: close');
readfile($olddir);
exit();
}else header("Location: index.php?msg=Sorry!+File+could+not+be+downloaded");
}
function ext($name){
$rut = strrev($name);
$erut = explode('.', $rut);
return strrev($erut[0]);
}
We give file id to this function and it downloads the file on PC.
Can anyone tell me how to remove the error? So that users can download files from their android phones too.
Probably $size == 0;
$size = $row['file_size'];
...
$olddir = "files/".$name;
change to
$olddir = "files/".$name;
$size = filesize($olddir);
And change
else header("Location: index.php?msg=Sorry!+File+could+not+be+downloaded");
to
else header("Location: index.php?msg=Sorry!+File+could+not+be+found+on+server: " . $olddir);
I got the solution.
Mainly I changed two things:
Used GET method instead of Post Method.
Used Flush and ob_clean functions to clear the buffer.
New code for downfile.php is like this:
<?php
require '../php/db.php';
ob_start();
if(isset($_GET['file_id'])&&!empty($_GET['file_id'])){
download_file($_GET['file_id']);
}else die("There was an error in downloading file. Please try again later.");
function download_file($id){
global $con;
$id = mysqli_real_escape_string($con,htmlentities($id));
$file="SELECT file_name,file_title,file_size,down FROM files WHERE file_id= $id";
$result = mysqli_query($con,$file);
$row = mysqli_fetch_assoc($result);
$name = $row['file_name'];
$title = $row['file_title'];
$ext = ext($name);
$down = $row['down'];
$newname = $title.'.'.$ext;
$size = $row['file_size'];
$down++;
if(is_file($name)) {
$update_down = "UPDATE files SET down = $down WHERE file_id = '$id'";
$update_down_result = mysqli_query($con,$update_down);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$newname.'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: '.$size);
ob_clean();
flush();
readfile($name);
exit;
}else header("Location: index.php?msg=Sorry!+File+could+not+found!");
}
function ext($name){
$rut = strrev($name);
$erut = explode('.', $rut);
return strrev($erut[0]);
}
?>
Through this code I am able to download files in android browsers too.
Hope this may help. :)

save html output in txt file with php

need to generate a txt file with the following output html code
<?php
function video() {
$video = 'BYN-DEM7Mzw';
echo '<script type="text/javascript">
function youtubeFeedCallback( data ){
document.writeln( data.entry[ "media$group" ][ "media$description" ].$t.replace( /\n/g, "<br/>" ) + "<br/>" ); }
</script>
<script type="text/javascript" src="http://gdata.youtube.com/feeds/api/videos/'.$video.'?v=2&alt=json-in-script&callback=youtubeFeedCallback"></script>';
}
ob_start();
video();
$output = ob_get_clean();
$desc = $output;
$video = 'BYN-DEM7Mzw';
$arq = $video.".txt";
$f = fopen($arq, "w+");
fclose;
$f = fopen($arq, "a+");
$content = "";
if(filesize($arq) > 0)
$content = fread($f, filesize($arq));
fwrite($f, $desc);
fclose($f);
?>
the problem that the file is saving up my script and not the output html
I think you should be using the right headers and the correct mime in it.
For example
header('Content-Description: File Transfer');
header('Content-type: text/plain');
header('Content-Disposition: attachment; filename='.$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));
if ($file != '')
{
echo file_get_contents($file);
}

Form downloads same ZIP over and over

Thanks to the users community on this forum, I wrote a very simple web form that allows my user to view text files from within their Internet browser.
I have now two functions whereby the text files returned by the search are compressed into a ZIP. Here's my code
function getFilesFromSite() {
$result = null;
$ZIPresult = null;
if (empty($_POST['DBSite'])) { return null; }
$mydir = MYDIR;
$dir = opendir($mydir);
$DBSite = $_POST['DBSite'];
$getfilename = mysql_query("select filename from search_table where site='" . $DBSite . "'") or die(mysql_error());
while ($row = mysql_fetch_array($getfilename)) {
$filename = $row['filename'];
$result .= '<tr><td>' . $filename . '</td></tr>';
$ZIPresult .= basename($mydir) . '/' . $filename.' ';
}
if ($result) {
$result = "<table><tbody><tr><td>Search Results.</td></tr> $result</table>";
shell_exec("/bin/rm -f SearchResult.zip;/usr/bin/zip -9 SearchResult.zip ". $ZIPresult ." > /dev/null ");
//header for forced download
header("Pragma: public");
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
$fileName = 'SearchResult.zip';
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Transfer-Encoding: binary");
header('Content-type: application/zip');
header("Content-length: " . filesize($fileName));
header('Content-Disposition: attachment; filename="' . $fileName . '"');
ob_start(); // Starts output buffering.
readfile($fileName); // "Outputs" the file.
$content = ob_get_flush(); // Grabs the output and assigns it to a variable.
print base64_encode($content);
}
function getFilesFromError() {
//Just a copy paste from above with different input parameter...
}
The problem is that the ZIP file with the contents from whatever search was done first gets downloaded over and over again. For instance, the results from getFilesFromSite() will always get downloaded even though I did a search with getFilesFromError() afterwards.
I suspect my headers are incorrectly set but I am not sure where.
PS: The new ZipArchive() library/class is not available on our production environment so I chose to use the Unix utility ZIP instead.
Using Base64 was actually not working for reasons well stated here. Instead, I turned zlib compression off and reverted back to using binary as output format. Finally, I set Content-Type to application/octet-stream in my header. Everything is working fine now ; here's my code:
function getFiles() {
ini_set('zlib.output_compression', 'Off');
$result = null;
$ZIPresult = null;
$cleanup = null;
$output = null;
$fileName = null;
//remove old zip if any
$cleanup = shell_exec("/bin/rm -f SearchResult.zip");
error_log("SHELL OUTPUT=>" . $cleanup, 0);
//test
if (empty($_POST['DBRIDs'])) { return null; }
$mydir = MYDIR; // set from the CONSTANT
$dir = opendir($mydir);
$DBRIDs = $_POST['DBRIDs'];
$getfilename = mysql_query("select /*! SQL_CACHE */ filename from automation where rid in (" . $DBRIDs . ")") or die(mysql_error());
while ($row = mysql_fetch_array($getfilename)) {
$filename = $row['filename'];
$result .= '<tr><td>' . $filename . '</td></tr>';
$ZIPresult .= basename($mydir) . '/' . $filename.' ';
}
if ($result) {
$result = "<table><tbody><tr><td>Search Results.</td></tr> $result</table>";
$output = shell_exec("/usr/bin/zip SearchResult.zip ". $ZIPresult ." ");
error_log("SHELL OUTPUT=>" . $output, 0);
$fileName = 'SearchResult.zip';
error_log("ZIP FILENAME=>" . $fileName, 0);
if (file_exists($fileName)) {
//header for forced download
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($fileName));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($fileName));
ob_clean();
flush();
readfile($fileName);
exit;
}
}
return $result;
}
Thanks to all for taking the time!!

Categories