Generate/Download of CSV throws a Connection error PHP - php

So the process that I have goes like this. A user can pick a date range to view the data that he wants/needs. A Download is then available if he wants to download the file.
When doing a wide range the page throws off a connection error.
Firefox - The connection was reset
Chrome - No Data Received
The code that I use to generate the CSV is
<?php
$res = // the array generated by a mysql query
$text=strtotime("Now");
$filesave=fopen('Downloads/CallLogs'.$text.'.csv','w');
foreach ($res as $display)
{
fputcsv($filesave,$display);
}
//Force download the file. you can correct me if this is the improper way of doing it :)
header('Content-Type: application/download');
header('Content-Disposition: attachment; filename="CallLogs'.$text.'.csv"');
$fp = fopen("Downloads/CallLogs".$text.".csv", "r");
fpassthru($fp);
fclose($fp);
?>
Thanks in advance...

Related

File throws an error on download

I'm generating a csv file for download using the following code.
/**#var array $results contains the results of an SQL query**/
$tmpFile = tmpfile(); //Create a temp file to write the csv to
fputcsv($tmpFile, array_keys($results[0])); //Write the column headers
foreach ($results as $result) { //write each row to the file
fputcsv($tmpFile, $result);
}
rewind($tmpFile); //Rewind the stream
$csv = stream_get_contents($tmpFile); //Get the file as text
fclose($tmpFile); //Done with the temp file.
//Set the download headers
header('Content-Description: File Transfer');
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="testDownload.csv"');
//Output the content
echo $csv;
exit(0);
The download appears to start normally, but after a second I get a message in firefox, "[The file] could not be saved, because the source file could not be read." I've tested this with chrome/safari and have gotten similar results. I've also tested with some static content (not from the database) without success.
In the developer console, I can inspect the network request and see that it comes back with status 200 and if I inspect the response, I see the complete file. I can even copy/paste it into a text file and open it in excel.
Additionally, if I comment out the header() lines, the file contents display in the browser without issue.
The content is only ~2500 rows, no special characters.

How would I download blob files (.txt/pdf) from a MySQL database [duplicate]

This is one I just can't figure out: I have successfully built an upload feature on a web page to upload files to a MySQL Database. When I go on the server and open them via phpMyAdmin, they all look fine... txt, jpg, pdf, etc.
Yet, after putting together THIS thing (below) to download it, I get a strange problem: All of the text documents (and all other types of files, after I change the extension to 'txt') contain HTML code of the page itself, followed by the original content!
Also, different browsers display differently after the POST. When trying to download a txt file, IE will show the correct data in the ECHO on the page itself (no downloading) with an error message just before it:
Warning: Header may not contain more than a single header, new line detected. in C:\wamp\www\ace\dmain.php on line 82.
Line 82 is 'header("Content-length...'
Neither Firefox nor Chrome show anything. They just allow me to download it.
Here's the code:
<?php
if (isset($_POST['downloadid'])) {
$fileid = $_POST['downloadid'];
try {
$sql = "SELECT * FROM `datastore` WHERE `id` = '".$fileid."'";
$results = $pdo->query($sql);echo $sql;
while ($row = $results->fetch()) {
$filename = $row['filename'];
$mimetype = $row['mimetype'];
$filedata = $row['filedata'];
header("Content-length: strlen($filedata)");
header("Content-type: $mimetype");
header("Content-disposition: download; filename=$filename"); //disposition of download forces a download
echo $filedata;
// die();
} //of While
} //try
catch (PDOException $e) {
$error = '<br>Database ERROR fetching requested file.';
echo $error;
die();
} //catch
} //isset
?>
This:
header("Content-length: strlen($filedata)");
Is not going to produce what you expect. If you look at the headers in wireshark, or another method to view the request you will see that it does not contain an integer.
Use this instead:
header("Content-length: ".strlen($filedata));
After agonizing over fixing it in-place (that is, on the same page with the rest of the html and code), I decided to move it to a dedicated PHP page. After that, it worked fine.
Thanks for the comments!
here is good example and complete source

write ZIP with PHP from MSSQL IMAGE field retrieved as BINARY STREAM

I want to retrieve a ZIP file with PHP from a MSSQL database wich is stored in a IMAGE field.
In this part i make a connection using sqlsrv, send a query, and move to the first row and get the first field in BINARY encoding.
$conn = sqlsrv_connect($sql['s'],array('Database'=>$sql['db'],'UID'=>$sql['usr'],'PWD'=>$sql['pwd']));
$q = 'SELECT TOP 1 FileContent
FROM dbo.tblDocumentContent
WHERE FileContent IS NOT NULL
ORDER BY CreateDate DESC';
$res = sqlsrv_query($conn, $q);
sqlsrv_fetch($res);
$zip = sqlsrv_get_field($res,0,SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY));
At this point the zip is retrieved as a resource stream and here i get stuck.
When i set the headers and output the content, the browser downloads the zip.
header("Content-type: application/zip, application/octet-stream");
header("Content-Disposition: attachment; filename=test.zip;");
fpassthru($zip);
This works like a charm, the zip works perfect.
But what i want is to open the zip serverside without the user having to dowload it.
So when i just try to write the content to a file:
$file = fopen('test.zip', 'a');
fwrite($file, fpassthru($zip));
fclose($file);
It can't be opened. I figured that when the browser downloads the given content, it encodes it someway. Alltrough i can not figure out how to do that while writing it to a file.
If someone has any solutions to write the resource stream to a file on the server side in the proper way, that would be great.
This should solve the problem:
$file = fopen('test.zip', 'w');
while (!feof($img)) {
$chunk = fread($img, 1024);
fwrite($file, $chunk);
}
fclose($img);
fclose($file);

Trying to download Blob via PHP / MySQL

This is one I just can't figure out: I have successfully built an upload feature on a web page to upload files to a MySQL Database. When I go on the server and open them via phpMyAdmin, they all look fine... txt, jpg, pdf, etc.
Yet, after putting together THIS thing (below) to download it, I get a strange problem: All of the text documents (and all other types of files, after I change the extension to 'txt') contain HTML code of the page itself, followed by the original content!
Also, different browsers display differently after the POST. When trying to download a txt file, IE will show the correct data in the ECHO on the page itself (no downloading) with an error message just before it:
Warning: Header may not contain more than a single header, new line detected. in C:\wamp\www\ace\dmain.php on line 82.
Line 82 is 'header("Content-length...'
Neither Firefox nor Chrome show anything. They just allow me to download it.
Here's the code:
<?php
if (isset($_POST['downloadid'])) {
$fileid = $_POST['downloadid'];
try {
$sql = "SELECT * FROM `datastore` WHERE `id` = '".$fileid."'";
$results = $pdo->query($sql);echo $sql;
while ($row = $results->fetch()) {
$filename = $row['filename'];
$mimetype = $row['mimetype'];
$filedata = $row['filedata'];
header("Content-length: strlen($filedata)");
header("Content-type: $mimetype");
header("Content-disposition: download; filename=$filename"); //disposition of download forces a download
echo $filedata;
// die();
} //of While
} //try
catch (PDOException $e) {
$error = '<br>Database ERROR fetching requested file.';
echo $error;
die();
} //catch
} //isset
?>
This:
header("Content-length: strlen($filedata)");
Is not going to produce what you expect. If you look at the headers in wireshark, or another method to view the request you will see that it does not contain an integer.
Use this instead:
header("Content-length: ".strlen($filedata));
After agonizing over fixing it in-place (that is, on the same page with the rest of the html and code), I decided to move it to a dedicated PHP page. After that, it worked fine.
Thanks for the comments!
here is good example and complete source

Export mySQL to excel or csv

I'm no php expert (a mere beginner) but need some help!
After hours searching Google and trying out about 100 different scripts, I finally found one that does what I need - almost.
Basically, my site has a button marked 'Export to Excel'. Visitor to site clicks button and a download begins containing all data from a specified table.
I found this on here - PHP code to convert a MySQL query to CSV
which does exactly what I want except the user sees the following error when trying to open the file:
Error - 'The file you are trying to open, 'export.xls', is in a different format than specified by the file extension. Verify that the file is not corrupted and is from a trusted source before opening the file. Wo you want to open the file now?'
User clicks 'Yes' and file opens with all data! Brilliant! Except users will not open the file with this error.
I would be very grateful if someone knows a way to fix this.
Many thanks
TT
Or, you could just change the script in the above solution to return a file with the .csv extension. .csv files are associated with Excel, so they should open directly.
Ok, this results from a feature specified by Excel 2007 called Extension Hardening. You can turn it off, but that can only be done client-side. If you click "OK" or "Yes" the file should open anyway. Check this blog post for more info.
EDIT: What this means is that Excel is finding that the file is of a different type (say HTML or CSV) that what is specified by the file extension. Therefore Excel wants to warn you that this file is not what it says it is. Unless you are going to create native Excel files on the server then prompt the user to download them, there is no getting around this error except for each user to turn off Extension Hardening on their own computer.
if you make the first letters “ID” of a text file Excel incorrectly
assumes you are trying to open an SYLK file.
Meaning if the first row & column value is "ID", Excel will throw this warning. Just change it from "ID" to anything else.
Credit: http://alunr.com/excel-csv-import-returns-an-sylk-file-format-error/
Dim objXL As Excel.Application
Dim objWkb As Excel.Workbook
Set objXL = New Excel.Application
'turn off excel warnings
objXL.DisplayAlerts = False
'Open the Workbook
Set objWkb = objXL.Workbooks.Open(fpath)
functions sendFile($filename,$content_type="application/ms-excel") {
header('Content-type: '.$content_type);
header('Content-disposition: Attachment; filename=' . $filename);
readfile($filename);
}
I had the same problem so I looked at the following link: PHP code to convert a MySQL query to CSV
I modified one of the answers to get the headers to work.
include('DBFILE.PHP');
$select="SELECT * FROM SOMETable";
$result = mysqli_query($conn, $select);
if (!$result) die('Couldn\'t fetch records');
$num_fields = mysql_num_fields($result);
//This is what I changed...
$headers ="";
while ($property = mysqli_fetch_field($result)) {
$headers.= $property->name.",";
}
$headers.="\n";
//////
$fp = fopen('php://output', 'w');
if ($fp && $result) {
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="export.csv"');
header('Pragma: no-cache');
header('Expires: 0');
fputcsv($fp, $headers);
while ($row = $result->fetch_array(MYSQLI_NUM)) {
fputcsv($fp, array_values($row));
}
die;
}
I Tested this and it works like a charm, you just need to add your db connection or include the db.php file that you have.
you can change the name of the file if you edit the following line
header('Content-Disposition: attachment; filename="export.csv"');
Change export to what ever name you like.

Categories