How to get entire column from database to file? - php

I'm trying to develop a short code that allows me to get the entire data from on column from a table to a .txt file.
$query = $connection->prepare("SELECT * FROM newsletter WHERE status = :status");
$query->execute(array(":status" => "1"));
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$file = $_SERVER['DOCUMENT_ROOT']."/assets/files/".$date=date("d-m-Y")."-newsletter.txt";
$openf = fopen($file, "w");
$current = file_get_contents($file);
$current .= "".$row["email"].",";
file_put_contents($file, $current);
fwrite($openf, $current);
fclose($openf);
}
header('Content-Description: File Transfer');
header('Content-Disposition: attachment; filename='.basename($file));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
header("Content-Type: text/plain");
readfile($file);
this is what i have so far, but the main problem is that it only prints 1 line to the .txt file, whether it should print at least 2.
Anyone can help me solve this? I've tried different methods and none worked so far.

create the file before loop and save after loop
$query = $connection->prepare("SELECT * FROM newsletter WHERE status = :status");
$query->execute(array(":status" => "1"));
//create file
$file = $_SERVER['DOCUMENT_ROOT']."/assets/files/".$date=date("d-m-Y")."-newsletter.txt";
$openf = fopen($file, "w");
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$current = file_get_contents($file);
$current .= "".$row["email"].",";
file_put_contents($file, $current);
}
//save and close
fwrite($openf, $current);
fclose($openf);
...

Related

How to set text output alignment in MySQL Data export?

This is the SQL query
$query = "SELECT col1,col2,col3,col4,col5,col6,col7,col8 FROM table;
if (!$result = mysqli_query($con, $query))
{
exit(mysqli_error($con));
}
This is the part that outputs the text file
$filename = "output.txt";
$file = fopen($filename, "w");
foreach ($result as $rows)
{
fwrite($file, implode("\t",$rows).PHP_EOL);
}
header('Content-Description: File Transfer');
header('Content-type: text/tab-separated-values');
header('Content-Disposition: attachment; filename="'.basename($filename).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filename));
readfile($filename);
exit;
This is the current output:
This is the output that I need:
As commented out by #Slava Rozhnev and best way is to use csv like this:
<?php
$query = "SELECT col1,col2,col3,col4,col5,col6,col7,col8 FROM table";
$result = mysqli_query($con, $query);
$fp = fopen('file.csv', 'w');
while( $row = mysqli_fetch_array($result, MYSQLI_ASSOC) ) {
fputcsv($fp, $row);
}
fclose($fp);

Download multiple .txt files into .zip file with PHP

Now in system it is possible to download .txt file generated from MySQL table row. I am trying to make it possible to download all .txt files in one zip file. Actually, I stuck on the point where I am not sure if my approach is possible.
if (isset($_POST["ExportAll"])) {
$query = $con->query("SELECT id, filename FROM thistable");
$MultiArray = Array();
while($result = $query->fetch_assoc()){
$rowArray = Array();
$rowArray[] = $result['id'];
$rowArray[] = $result['filename'];
$MultiArray[] = $rowArray;
}
foreach ($MultiArray as $arg) {
$query = "SELECT * FROM thistable WHERE id LIKE '" . $arg[0] . "';";
$result = mysqli_query($con, $query);
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $arg[1] );
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
$output = fopen("php://output", "w");
while ($row = mysqli_fetch_assoc($result)) {
foreach(array_slice($row,2) as $line) {
echo ("$line \r\n");
}
}
fclose($output);
}
}
It is possible to put all $output values into some kind of $zipArray = Array() and then download it with header("Content-type: application/zip");
?
Yes you can download multiple text files as single zip file using php ZipArchive class. This is sample only you can try with your own scenario.
$zipname = 'sample.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
$files_array = ["sample1", "sample2"]; // List of file names
foreach ($files_array as $file) {
$row = ["Line 1", "Line 2", "Line 3", "Line 5"]; // Assuming as your table row
$filename = $file.".txt";
$lines_to_add = "";
foreach(array_slice($row, 2) as $line) {
$lines_to_add .= $line."\r\n";
}
$zip->addFromString($filename, $lines_to_add); // Adding lines to file
}
$zip->close();
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
unlink($zipname); // Remove zip file if you don't want be in server

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. :)

Create downloadable CSV from web search using PHP and mySQL

I am trying to create a CSV file that can be downloaded by the user and not have the data permanently saved on the server.
I am using mySQL and PHP for this page. I get the data in the right format to show up ("echo") on the webpage but not able to get the file to generate/download...maybe I am missing something or looking in the wrong place but any help would be great!
I have been trying several script both my own and others I have found but the one I currently have is below:
$file = 'export';
$colresult = mysql_query("SHOW COLUMNS FROM ".$tbl_name."");
if (mysql_num_rows($colresult) > 0) {
while ($row = mysql_fetch_assoc($colresult)){
$csv_output .= $row['Field'].", "; $i++; } } $csv_output .= "\n";
$csvresult = mysql_query($sql);
while ($rowr = mysql_fetch_row($csvresult)) {
for ($j=0;$j<$i;$j++) { $csv_output .= $rowr[$j].", ";
}
$csv_output .= "\n"; }
$filename = $file."_".date("Y-m-d_H-i",time()).".csv";
header("Content-type: application/csv");
header("Content-disposition: attachment;filename=".$filename.".csv");
readfile("../documents/csv/".$filename.".csv");
$fp = fopen($filename, 'w');
foreach($csvret as $csvret){
fputcsv($fp, $csvret);
}
print $csv_output;
print $filename;
Thanks!
You'll need to pass some headers to force the web browser to recognize the file as "downloadable":
<?php
header('Content-Description: File Transfer');
header("Content-Type: application/csv");
header('Content-Disposition: attachment; filename="'.basename($filename).'"');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($filename));
readfile($filename);
exit;
Simply add that code in place of:
print $csv_output;
print $filename;

Combining 2 CSV files

I'm trying to combine two CSV files in PHP. I'm looking for perfect method. Here's my code so far:
$one = fopen('data5.csv', 'r');
$two = fopen('userdata.csv', 'r');
$final = fopen('final_data.csv', 'a');
$temp1 = fread($one, filesize("data5.csv"));
$temp2 = fread($two, filesize("userdata.csv"));
fwrite($final, $temp1);
fwrite($final, $temp2);
I will give you a solution to use if you have big CVSs and you don't want to use much of your machine's RAM (imagine each CSV is 1GB, for example).
<?php
function joinFiles(array $files, $result) {
if(!is_array($files)) {
throw new Exception('`$files` must be an array');
}
$wH = fopen($result, "w+");
foreach($files as $file) {
$fh = fopen($file, "r");
while(!feof($fh)) {
fwrite($wH, fgets($fh));
}
fclose($fh);
unset($fh);
fwrite($wH, "\n"); //usually last line doesn't have a newline
}
fclose($wH);
unset($wH);
}
Usage:
<?php
joinFiles(array('join1.csv', 'join2.csv'), 'join3.csv');
Fun fact:
I just used this to concat 2 CSV files of ~500,000 lines each. It took around 5seconds and used 512kb of memory.
Logic:
Open each file, read one line and then write it to the output file. Yes, it may be slower writing each line rather than writing a whole buffer, but this allows the usage of heavy files while being gentle on the memory of the machine.
At any point, you are safe because the script only reads on line at a time and then writes it.
Enjoy!
How about...
file_put_contents('final_data.csv',
file_get_contents('data5.csv') .
file_get_contents('userdata.csv')
);
Note that this loads the entire files into PHP memory though. So, if they are big, you may get memory_limit issues.
If you want to just concatenate the two files you can do this easily with executing a shell script assuming you are on unix like os:
exec("cat data5.csv > final_data.csv && cat userdata.csv >> final_data.csv");
ob_start();
$dir1 = "csv/2014-01/";
$dir = $_REQUEST['folder_name'];
$totalfiles = count(glob($dir."/*",GLOB_BRACE));
echo "Total files in folder = ".$totalfiles;
if ($opend = opendir($dir)){
$i =0; $final_array_export= array();
$fil_csv =end(explode('/',$dir));
$file_name = 'download/'.$fil_csv.'.csv';
$file_cre = fopen($file_name,"w");
$headers = array("header1","header2");
fputcsv($file_cre,$headers);
while (($file = readdir($opend)) !== false){
$filename = $dir.'/'.$file;
$files = fopen($filename,"r");
if($files){
$fullarray = fgetcsv($files);
$head=array();
if(count($fullarray) >0){
foreach($fullarray as $headers){
$head[] = $headers;
}
}
while($data = fgetcsv($files,0,",")){
if(count($data) >0 && count($head) >0){
$array_combine = array_combine($head,$data);
}
fputcsv($file_cre,$array_combine);
}
}
}
fclose($file_cre);
header("Content-Type: application/force-download");
header("Content-type: application/csv");
header('Content-Description: File Download');
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: ' . filesize($file_name));
ob_clean();
flush();
readfile($file_name);
}

Categories