PHP: Creating a MYSQL query inside a function - php

I have a function which performs an SQL query, "queryValue" the actual query to perform is passed later.
Function queryCreate($queryValue){
//DB connection variables
$host = "";
$user = "";
$password = "";
$database = "";
//create the connection
$conn = new mysqli($host, $user, $password, $database);
if ($conn->connect_error) {
die('DB Connection error: (' . $conn->connect_error . ') ' . $conn->connection_errorno);
}
$query = mysqli_query($conn,$queryValue) or die(mysqli_error($conn));
if ($result = mysqli_fetch_array($query,MYSQLI_ASSOC)) {
fputcsv($fh, array_keys($result));
fputcsv($fh, $result);
while ($result = mysqli_fetch_array($query,MYSQLI_ASSOC)) {
fputcsv($fh, $result);
}
}
return $queryValue;
}
I'm then attempting to assign the query value in a separate if statement. Below:
if(isset($_POST["Submit"]) && ($_POST['Weight'] == 'Weight')) {
$fh = csvCreate("Output Weight Null ".date('m-d-Y-His').".csv");
$queryValue = queryCreate('SELECT * FROM `table` WHERE WEIGHT = 0 OR weight IS NULL');
}
The problem I have is that the query does not appear to be being passed to the function. Could anyone suggest where I have gone wrong here? Many thanks.
The csvCreate function is shown here:
function csvCreate($filename){
header("Cache=Control: must-revalidate, post-check=0, pre-check=0");
header('Content-Description: File Transfer');
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename={$filename}");
header("Expires: 0");
header("Pragma: public");
$fh = #fopen( 'php://output', 'w' );
return $fh;
}

The problem is with the parameters of fputcsv() calls within queryCreate() function.
The file handler ($fh variable) is declared outside of queryCreate() function using the csvCreate() function:
$fh = csvCreate("Output Weight Null ".date('m-d-Y-His').".csv");
However,$fh is not passed as a parameter to queryCreate(), nor is $fh declared as a global variable, yet $fh variable is used to reference the file in all fputcsv() calls:
fputcsv($fh, array_keys($result));
In this case, $fh within queryCreate() will not refer to $fh variable where queryCreate() is called, but it will create a local $fh variable (empty at that), therefore the fputcsv() call will fail. The csv file is created in csvCreate(), this is independent from putting the values within the file.
The best solution would be to either pass $fh as a parameter to queryCreate(), or call csvCreate() from queryCreate(). In the latter case, the name of the dataset should be passed as a parameter.
UPDATE
Let's see some code as well:
//declaration of queryCreate()
Function queryCreate($queryValue, $reportName){ //$reportName is the name of the report
...
//create the csv file, put some parameter checks here as well
$fh = csvCreate($reportName.date('m-d-Y-His').".csv");
//and some error handling here
...
//output the contents of the query to the csv file
if ($result = mysqli_fetch_array($query,MYSQLI_ASSOC)) {
fputcsv($fh, array_keys($result));
fputcsv($fh, $result);
while ($result = mysqli_fetch_array($query,MYSQLI_ASSOC)) {
fputcsv($fh, $result);
}
}
... //should include closing of the csv file
} //end queryCreate()
...
//call the queryCreate()
if(isset($_POST["Submit"]) && ($_POST['Weight'] == 'Weight')) {
$queryValue = queryCreate('SELECT * FROM `table` WHERE WEIGHT = 0 OR weight IS NULL','Output Weight Null ');
}

Related

Export data to CSV file with php and simple html dom

How to export grabbed data to .csv file? I'm using php simple html dom to parse data. Here is the code:
foreach ($linkoviStranica as $stranica)
{
$podaciStranice = "http://someurl/$stranica";
$data = file_get_html($podaciStranice);
$name = $data->find('div[class="price-card-name-header-name"]');
$onlinePrice = $data->find('div[class="price-box online"]');
$diffPrice = $data->find('div[class="price-box paper"]');
echo "<strong>".$name[0]->innertext."<strong>"."<br>";
if (!empty($onlinePrice[0]->innertext))
{
echo $onlinePrice[0]->innertext."<br>";
}
if (!empty($diffPrice[0]->innertext))
{
echo $diffPrice[0]->innertext."<br>";
echo "---------------------"."<br>";
}
}
I want to export, $name, $onlinePrice, $diffPrice to csv file with header in the following format:
name onlinePrice diffPrice
example 10 44
xxxx 412 461
zzzzz 1414 41
Could you please help me? Thanks!
Something like this:
// Define a array to hold all the data
$data = [];
// OR use this line if you want the headers with names on the first line of the file
// $data = [['name', 'onlinePrice', 'diffPrice']];
// Loop the raw data
foreach ($linkoviStranica as $stranica) {
$podaciStranice = "http://someurl/$stranica";
$data = file_get_html($podaciStranice);
$name = $data->find('div[class="price-card-name-header-name"]');
$onlinePrice = $data->find('div[class="price-box online"]');
$diffPrice = $data->find('div[class="price-box paper"]');
// Add current row to out array
$data[] = [
$name[0]->innertext,
$onlinePrice[0]->innertext,
$diffPrice[0]->innertext
];
}
// Open a new file. Replace the file name with the name you'd like
$fp = fopen('file.csv', 'w');
// Loop each row in the data array
foreach ($data as $fields) {
// This method converts a row to a CSV line (http://php.net/manual/en/function.fputcsv.php)
fputcsv($fp, $fields);
}
// Close the file handler
fclose($fp);
$header ="SNo , Order Date , Order Number , Compaign , Amount , Order Status , Used Date , Cancel Reason , Order Commision , Payment Date , Payment Status \n";
$header1 =$header ;
$result='';
foreach ($data as $fields) {
$result= 'echo your data with coma seprated '."\n";
}
$all=$header.$result;
$name="report.csv";
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=".$name);
header("Pragma: no-cache");
header("Expires: 0");
print "$header1 $result";

fputcsv Creates the file but downloads it empty

I have this piece of PHP code that's intended to retrieve data from a mySQL database, and export it to a CSV file that has to be automatically downloaded after it was created.
$connection = mysqli_connect($host, $username, $password, $dbname) or die("Connection Error " . mysqli_error($connection));
// fetch mysql table rows
$sql = "select * from users";
$result = mysqli_query($connection, $sql) or die("Selection Error " . mysqli_error($connection));
$fp = fopen('users.csv', 'w');
while($row = mysqli_fetch_assoc($result)) {
fputcsv($fp, $row);
}
fclose($fp);
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="users.csv"');
mysqli_close($connection);
The problem here is that it:
Retrieves the data.
Retrieves the CSV file on the server in the same directory of the export.php file with the data on it.
Downloads the file with the same name BUT it's EMPTY
Thanks.
You're writing it to a file called users.csv, but the file you are forcing the user to download is the output of the page.
As long as your query is correct, once the PHP script has run, there should be a file called users.csv in the same directory as the PHP file that contains the correct data.
You need to output the data to the browser for it to be attributed to the file you're downloading.
Try this:
//Connect to database
$connection = mysqli_connect($host, $username, $password, $dbname) or die("Connection Error " . mysqli_error($connection));
//Fetch mysql table rows
$sql = "select * from users";
$result = mysqli_query($connection, $sql) or die("Selection Error " . mysqli_error($connection));
//Close connection
mysqli_close($connection);
//Set $output
$output = "";
//Set header values
$headers = array("Header 1", "Header 2", "Header 3");
//Insert header values to $output
foreach($headers as $h){
$output .= fieldCheck($h) . ",";
}
$output = rtrim($output, ","). "\n";
//Iterate through results
while($row = mysqli_fetch_assoc($result)) {
foreach($row as $cell){
//Comma-separate each value
$output .= fieldCheck($cell).",";
}
//Remove last comma of each line and add newline
$output = rtrim($output, ",") . "\n";
}
//Set headers
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="users.csv"');
//Output
echo $output;
exit;
//Function in case of comma in field
function fieldCheck($string){
if(strpos($string, ",") !== false){
$string = '"'.$string.'"';
}
return $string;
}
I have seen this question come up quite a few times and here the user is sending the data to "users.csv" as shown below:
$fp = fopen('users.csv', 'w');
The issue is that unless the file "users.csv" is already created there is nothing to write the data to, so the CSV is blank. The "fopen" does not create the file it only opens an existing file and the "w" directive then instructs "fputcsv" to put it into the file "users.csv" which may not exist and if the file does exist it writes over the existing file.
Here is an explainer PHP script that will send the output (CSV) to a filename of your choice for downloading:
//Connect to database
$connection = mysqli_connect($host, $username, $password, $dbname) or die("Connection Error " . mysqli_error($connection));
//Get the data
//The order and number of elements must match the header below or the data
//will appear in the wrong columns.
$sql = "SELECT FirstName,LastName,Address,City,State,Zip FROM users";
$result = mysqli_query($connection, $sql) or die("Selection Error " . mysqli_error($connection));
//Close connection
mysqli_close($connection);
//Name of the file you want the user to download can be any name but
//use the .CSV file extension so it will be recognized
//as a CSV when downloaded.
$NameOfCSVFileToDownload = "MyCSVFile.csv";
//set headers tells the page what to do
header("Content-Type: application/csv; charset=utf-8");
header("Content-Disposition: attachment;filename=\"$NameOfCSVFileToDownload\"");
//Where to send the data -
//there are several option but sending it to output will insert
//the data into "$NameOfCSVFileToDownload" when complete, your output.
//Output is a way to access I/O streams
$output = fopen("php://output", 'w');
//Add the header or 1st row for your data
//-notice we are sending it to "$output" you can add any names you want
//for this header row but make sure that the number of columns in the header
//matches the number of columns you are retrieving from the database or they
//will not line up when you open up the CSV and things will look scrambled.
fputcsv($output, array('FirstName','LastName','Address','City','State','Zip'));
//Loop through the data and insert the data into "$output"
while($rows = $result->fetch_assoc()){
fputcsv($output, $rows);
}
//Close the "$output" file to complete the write.
fclose($output);
That's all, call the page and it will prompt to open or download the CSV that contains data. If it is still blank make sure your SQL statement is actually pulling data.
You can also review the PHP manual on streams to better understand.
PHP Manual
Combining a few ideas mentioned in the comments:
Output directly to stdout (rather than a users.csv file). This prevents concurrent processes from clashing with the same output file. No need to buffer temporary results in a variable, either.
Use fputcsv()'s 3rd argument to specify ';' as the field separator. No need to rewrite special code for that.
Use array_map() and a custom filter to add quotes around all the fields.
// Helper function to surround a string with double quotes
function pad_with_quotes($s) {
return '"' . $s . '"';
}
// Helper function to output a row to $fp:
function output_row($fp, $row) {
// Separate fields with ';':
fputcsv($fp, array_map('pad_with_quotes', $row), ';');
}
// Send HTTP headers
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="users.csv"');
// Open a pointer to stdout:
$fp = fopen('php://output', 'w'); // TO DO: check for fopen() failure
// Output headers (padded with quotes):
output_row($fp, ['foo', 'bar']); // TO DO: change headers
// DB connection/query goes here; omitted for brevity
// Loop through DB results:
while($row = mysqli_fetch_assoc($result)) {
// Output a row of results:
output_row($fp, row);
}

Export database to CSV with columns PHP

Here my php script to export database info to CSV file.
I dont arrive to put any structure to correctly tidy my infos in my CSV file.
For example, put all names in a name column, all emails in an email column... etc
include_once('conf.php');
include_once('BDD.php');
header('charset=UTF-8');
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");
$bdd = new BDD($conf['bddhost'], $conf['bddport'], $conf['bddname'], $conf['bdduser'], $conf['bddpass']);
$sql = "SELECT * FROM user";
$qry = $bdd->prepare($sql);
// Execute the statement
$qry->execute();
$data = fopen('/tmp/db_user_export_".time().".csv', 'w');
while ($row = $qry->fetch(PDO::FETCH_ASSOC))
{
// Export every row to a file
fputcsv($data, $row);
echo ''.$row['prenom'].' '
.$row['nom'].' '
.$row['email'].' '
.$row['cp'].' '
.$row['information'].'
';
}
fclose($data);
You don't want to use echo as you are creating the file with fputcsv
while ($row = $qry->fetch(PDO::FETCH_ASSOC))
{
// Export every row to a file
fputcsv($data, $row);
}
// reset the file pointer to the beginning of the file
rewind($data);
// dump the csv file and stop the script
fpassthru($data);
exit;
Syntax errors:
$data = fopen('/tmp/db_user_export_".time().".csv', 'w');
^-- ^-- ^-- ^---
You're mixing string quoting styles, so your filename is literally going to contain the characters ", ., t, etc... in it.
Try
$data = fopen('/tmp/db_user_export_' .time() .'.csv', 'w');
^----------^---
instead. Note the change from " -> '.
Since your result is an array, this may help you out:
Convert php array to csv string
if(!function_exists('str_putcsv'))
{
function str_putcsv($input, $delimiter = ',', $enclosure = '"')
{
// Open a memory "file" for read/write...
$fp = fopen('php://temp', 'r+');
// ... write the $input array to the "file" using fputcsv()...
fputcsv($fp, $input, $delimiter, $enclosure);
// ... rewind the "file" so we can read what we just wrote...
rewind($fp);
// ... read the entire line into a variable...
$data = fread($fp, 1048576);
// ... close the "file"...
fclose($fp);
// ... and return the $data to the caller, with the trailing newline from fgets() removed.
return rtrim($data, "\n");
}
}
$csvString = '';
foreach ($list as $fields) {
$csvString .= str_putcsv($fp, $fields);
}
More about this on GitHub, a function created by #johanmeiring.

PHP not creating downloadable CSV file

I am trying to pull out data from my database using php and exporting it into a downloadable CSV file that can be opened with excel. I am able to do this when i use mysql however, many have advised to not include mysql syntax in my code as its being deprecated and instead i should use mysqli. I have changed my code but now my code is not working. Does anyone know why that is?
mysql version (working version)`
mysql_connect('localhost', 'xxxxx', 'xxxxx') or die('connect');
mysql_select_db('db') or die('select');
$result = mysql_query('SELECT * bodyshops_master_network') or die('query');
if(mysql_num_rows($result) == 0)
{
die('no data');
}
$fh = tmpfile() or die('tmpfile');
$cols = array_keys(mysql_fetch_assoc($result));
fputcsv($fh, $cols);
mysql_data_seek($result, 0); // set result row pointer back to first row
while($row = mysql_fetch_assoc($result))
{
fputcsv($fh, $row);
}
rewind($fh);
$text = fread($fh, 999999);
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="download.csv"');
header('Content-Length: ' . strlen($text));
echo $text;
exit;
mysqli version (not working):
$mysqli = new mysqli("localhost", "xxxxx", "xxxxx", "db");
if (mysqli_connect_errno())
{
printf("Connect failed: ", mysqli_connect_error());
exit();
} else
{
$result = "SELECT * FROM bodyshops_master_network";
if(mysqli_num_rows($result) == 0)
{
die('no data');
}
$fh = tmpfile() or die('tmpfile');
$cols = array_keys($result->fetch_assoc());
fputcsv($fh, $cols);
$result->data_seek(0); // set result row pointer back to first row
while($row = $result->fetch_assoc())
{
fputcsv($fh, $row);
}
rewind($fh);
$text = fread($fh, 999999);
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="download.csv"');
header('Content-Length: ' . strlen($text));
echo $text;
exit;
Check phpinfo to see that mysqli extension is enabled.
Remove/comment the header calls so that you receive the output as plain HTML so that you notice if any message shows up (due to die or coding error) or if you actually get the data.
Also note that you loose the date of the first record you retrieve because you call:
$cols = array_keys(mysql_fetch_assoc($result));
respectively
$cols = array_keys($result->fetch_assoc());
What is not working?
Are you getting any errors?
Is the file empty, is there any file downloading?
Maybe errors aren't enabled, try this:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
?>
I'm new on StackOverflow, I think this would help. (I speak spanish, I hope you to understand my english :D )
I've been looking for a simply way to use mysqli and download a csv file that could be read by excel without UTF-8 problems (using ñ,á,ü...). I didn't found it, so I created one by myself (learning from Google and StackOverflow answers), after some hours I got something that works finally.
This is a Class that connects with the database and the functions will do whatever you want using mysqli and PHP. In this case, calling this class (require or include), just use the "downloadCsv()" function.
As an example, this would be the "class.php" file:
<?php
class DB{
private $con;
//this constructor connects with the database
public function __construct(){
$this->con = new mysqli("Your_Host","Your_User","Your_Pass","Your_DatabaseName");
if($this->con->connect_errno > 0){
die('There was a problem [' . $con->connect_error . ']');
}
}
//create the function that will download a csv file from a mysqli query
public function downloadCsv(){
$count = 0;
$header = "";
$data = "";
//query
$result = $this->con->query("SELECT * FROM Your_TableName");
//count fields
$count = $result->field_count;
//columns names
$names = $result->fetch_fields();
//put column names into header
foreach($names as $value) {
$header .= $value->name.";";
}
}
//put rows from your query
while($row = $result->fetch_row()) {
$line = '';
foreach($row as $value) {
if(!isset($value) || $value == "") {
$value = ";"; //in this case, ";" separates columns
} else {
$value = str_replace('"', '""', $value);
$value = '"' . $value . '"' . ";"; //if you change the separator before, change this ";" too
}
$line .= $value;
} //end foreach
$data .= trim($line)."\n";
} //end while
//avoiding problems with data that includes "\r"
$data = str_replace("\r", "", $data);
//if empty query
if ($data == "") {
$data = "\nno matching records found\n";
}
$count = $result->field_count;
//Download csv file
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=FILENAME.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo $header."\n".$data."\n";
}
?>
After creating the "class.php" file, in this example, use that function on "download.php" file:
<?php
//call the "class.php" file
require_once 'class.php';
//instantiate DB class
$export = new DB();
//call function
$export->downloadCsv();
?>
After download, open the file with MS Excel.
I hope this help you, I think I wrote it well, I didn't feel comfortable with the text and code field.

send an email exported cvs file php mysql

I am trying to send email exported csv file. However, when i click the link, have a pop-up to download a CVS with the record from MySQL. how can i send an email this csv file to spesific email adress ? thanks a lot for help and ideas.
best regards.
Here is my code
header("Content-type: application/x-msdownload");
header("Content-Disposition: attachment; filename=log.csv");
header("Pragma: no-cache");
header("Expires: 0");
$resultstr = array();
foreach ($selectionlist as $result)
$resultstr[] = $result;
$ww=implode(",",$resultstr);
function escape_csv_value($value) {
$value = str_replace('"', '""', $value); // First off escape all " and make them ""
if(preg_match('/,/', $value) or preg_match("/\n/", $value) or preg_match('/"/', $value)) { // Check if I have any commas or new lines
return '"'.$value.'"'; // If I have new lines or commas escape them
} else {
return $value; // If no new lines or commas just return the value
}
}
$sql = mysql_query("SELECT * FROM article
WHERE idArticle in ($ww) ORDER BY idArticle DESC"); // Start our query of the database
$numberFields = mysql_num_fields($sql) or die('MySql Error' . mysql_error());; // Find out how many fields we are fetching
if($numberFields) { // Check if we need to output anything
for($i=0; $i<$numberFields; $i++) {
$keys[] = mysql_field_name($sql, $i); // Create array of the names for the loop of data below
$col_head[] = escape_csv_value(mysql_field_name($sql, $i)); // Create and escape the headers for each column, this is the field name in the database
}
$col_headers = join(',', $col_head)."\n"; // Make our first row in the CSV
$data = '';
while($info = mysql_fetch_object($sql)) {
foreach($keys as $fieldName) { // Loop through the array of headers as we fetch the data
$row[] = escape_csv_value($info->$fieldName);
} // End loop
$data .= join(',', $row)."\n"; // Create a new row of data and append it to the last row
$row = ''; // Clear the contents of the $row variable to start a new row
}
// Start our output of the CSV
/*header("Content-type: application/x-msdownload");
header("Content-Disposition: attachment; filename=log.csv");
header("Pragma: no-cache");
header("Expires: 0");*/
echo $col_headers.$data;
} else {
// Nothing needed to be output. Put an error message here or something.
echo 'No data available for this CSV.';
}
OK. First you have to Save the CSV file. If you set headers as you mentioned the file will be automatically downloaded. Please read this article on this.
http://us2.php.net/manual/en/function.fputcsv.php
Once you create your CSV file you can email it using PHP mail function. If you need some library just check this out. It's easy to implement.
http://www.redvodkajelly.com/code/php-email-class/

Categories