I have to export all my products from database into a csv file when executing the following script but i can't manage to put together the function that returns all my products from database into an array or iterator. My php code is put below. What am i doing wrong? Thank you.
<?php
require_once("config/db-connect.php");
function toate_produsele_active() {
$array_produse = mysqli_query($mysqli, "SELECT product_id, product_name, category_url, product_short_desc, product_price, product_photo FROM mb95_products");
while ($row = mysqli_fetch_assoc($array_produse)) {
print_r($row);
}
}
$f = fopen('php://output', 'wb');
if($f) {
foreach(toate_produsele_active() as $produs) {
$coloane = array(
$produs['product_id'],
$produs['product_name'],
$produs['category_url'],
$produs['product_short_desc'],
$produs['product_price'],
implode('[,]', str_replace('[,]', '[%2C]', $produs['product_photo'])),
);
fputcsv($f, $coloane, ';', '"');
}
fclose($f);
}
?>
My final desired result should look something like this:
1;Titlu produs1;categorie;Descriere produs1;RON;60;5;product_photo.jpg
let's say that toate_produsele_active() it's working as expected. I have created three functions, so the code can be reused and i have added the comments in the code:
<?php
// Create the header for the csv file (ID, Titlu, Descriere, Pret)
function getHeader()
{
$csv = '';
$headerData = array();
$header = 'ID, Titlu, Descriere, Pret';
$columns = explode(',', $header);
foreach ($columns as $column) {
$headerData[] = $column;
}
// the titles are separated by the semicolon
$csv .= implode(';', $headerData) . "\n";
return $csv;
}
// add the products data into an array and then fill the csv file
// with rows. Separated by semicolon
function iterateItems($csv)
{
$data = [];
foreach (toate_produsele_active() as $produs) {
$data[] = $produs['product_id'];
$data[] = $produs['product_name'];
$data[] = $produs['category_url'];
$data[] = $produs['product_short_desc'];
$csv .= implode(';', $data) . "\n";
}
return $csv;
}
function exportAll()
{
// name and location of the file
$csvFile = 'products.csv';
// create the header: ID, Titlu, Descriere, Pret
$csvHeader = getHeader();
// add the header and then the product data into the csv file
$csv = iterateItems($csvHeader);
// save he file (location, file)
file_put_contents($csvFile, $csv);
}
// call the function
exportAll();
Related
I'm looking to read a CSV export file with PHP. I have access to the File Path Variable called $file_path.
How would I sort the CSV export file by a specific column and then sort it again by a second column? and then save the CSV file to the same file name and file path.
UPDATE:
I got it to read the CSV, then sort it and also save it to the CSV. However, it's also sorting the headers. I am trying to use array_shift and array_unshift but when I use array_shift with a multi-layer array, I am getting an error. (unshift works fine though).
function wp_all_export_after_export($export_id, $exportObj)
{
// Check whether "Secure Mode" is enabled in All Export -> Settings
$is_secure_export = PMXE_Plugin::getInstance()->getOption('secure');
if (!$is_secure_export) {
$filepath = get_attached_file($exportObj->attch_id);
} else {
$filepath = wp_all_export_get_absolute_path($exportObj->options['filepath']);
}
$handle = fopen($filepath, 'r') or die('cannot read file');
$binNumber = array();
$category = array();
$rows = array();
$header = array();
//build array of binNumbers, Categories, and array of rows
while (false != ( $row = fgetcsv($handle, 0, ',') )) {
$binNumber[] = $row[3];
$category[] = $row[1];
$rows[] = $row;
}
fclose($handle);
$header = $rows[0];
array_shift($rows);
//sort array of rows by BinNumber & then Category using our arrays
array_multisort($binNumber,SORT_ASC, $category, SORT_ASC, $rows);
array_unshift($rows,$header);
$file = fopen($filepath,"w");
foreach ($rows as $line) {
fputcsv($file, $line);
}
fclose($file);
}
add_action('pmxe_after_export', 'wp_all_export_after_export', 10, 2);
I would like to get a CSV export working where the user picks some optional fields to export with the required fields. I'm having trouble just adding the list of fields to export into this csv export method.
The list of fields i want to be part of the export ends up in the $fields array, but I'm not sure how to integrate that into the export loop for each row.
// database conection stuff and $_POST data validation/sanitation above here, not relevant. From a CSV export form.
$exportToCSVQuery = " SELECT $allRequestedFields' FROM my_table ";
// if the (run query) is valid then...
if ($exportToCSVResult = mysqli_query($mysqli, $exportToCSVQuery)) {
// count number of rows in result.
$exportToCSVResultNumRows = mysqli_num_rows($exportToCSVResult);
// if there is at least one result.
if ($exportToCSVResultNumRows > 0 ) {
if ($safeDelimiter == 'Comma') {
$delimiter = ",";
}
elseif ($safeDelimiter == 'Semi-colon') {
$delimiter = ";";
}
else{
$delimiter = ",";
}
//create a file pointer
$f = fopen('php://memory', 'w');
//set column headers
$fields = array('ID', 'Name', 'em', 'type', 'reason', 'result', 'status', 'notes', 'datetime', 'requestedby', 'requestedbycitrixid', 'week', 'period', 'year', 'historylog');
// put required and optional fields together from the form.
$fields = $fields+$safeFieldsArray;
fputcsv($f, $fields, $delimiter);
//create $linedata information, formatted in a php assoc row format.
//flip the $fields array so the values become the keys, needed for the next step.
$fieldsFlipped = array_flip($fields);
//output each row of the data, format line as csv and write to file pointer
while($exporttocsvrow = $exporttocsvresult->fetch_assoc()){
$fieldsarrayforlinedata = array_intersect_key($exporttocsvrow,$fieldsFlipped);
// flip array
$flippedfieldsarrayforlinedata = array_flip($fieldsarrayforlinedata);
fputcsv($f, $flippedfieldsarrayforlinedata, $delimiter);
}
//move back to beginning of file
fseek($f, 0);
//set headers to download file rather than displayed
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $safeFilename . '";');
//output all remaining data on a file pointer
fpassthru($f);
}
else {
Echo 'No Data to Export';
}
}
else {
$exportToCSVResultErr = "Error: " .mysqli_error($mysqli) ;
trigger_error("Query Error: ".$exportToCSVQuery." Error:" $exportToCSVResultErr, E_USER_WARNING);
}
Edit: I tried adding something based on Pradeep’s answer below to the loop like so:
while($exporttocsvrow = $exporttocsvresult->fetch_assoc()){
$fieldsarrayforlinedata = array_intersect_key($exportToCSVRow,$fieldsFlipped);
unset($valuesArray);
$valuesArray = array();
foreach ($fieldsFlipped as $key){
foreach ($exportToCSVRow[$key] as $values) {
$valuesArray[] = $values;
}
}
fputcsv($f, $valuesArray, $delimiter);
}
But this just results in the CSV with headings and blank data. I guess I'm probably adding that loop incorrectly.
I hope this will help to get the desired output.
$row=array('fieldA'=>array('data1','data2','data2','data3'),'fieldB'=>array('data1','data2','data3'),'fieldC'=>array('data1','data2','data3'));
$key=array('fieldA','fieldB');
foreach($key as $key){
foreach($row[$key] as $values){
echo $values;
}
}
I am working on Export to CSV in PHP. I have code that works fine it gives me output in ExcelSheet as I want.
Code snippet:
public function generate_csv() {
$data_rows = array();
$table = 'ProductDetails';
$data_rows = array();
global $wpdb, $bp;
$data= $wpdb->get_results("SELECT * FROM " . $table . "");
$fh = #fopen( 'php://output', 'w' );
foreach ($data as $u ) {
$row = array();
$row[0] = $u->productCode;
$row[1] = $u->productTitle;
$row[2] = $u->productDescription;
$row[3] = $u->specification;
$row[4] = $u->whereToBuy;
$data_rows[] = $row;
}
header("Pragma: public");
... Some more header ...
header("Content-Transfer-Encoding: binary");
fputcsv( $fh, $header_row );
foreach ( $data_rows as $data_row ) {
fputcsv( $fh, $data_row );
}
fclose( $fh );
die();
}
As you can see in code I am hard coding all column names and creating array. The problem is if phpMyAdmin add/remove column in database then to get perfect ExcelSheet necessary changes need to make in this code also. Can any one please help me to make this code dynamic.? Like what should be instead of $row[0], $row[1], $row[2].... ??
Thank You
More global approach is to use double foreaches
$data_rows=array();
foreach ($data as $u ) {
$row = array();
foreach ($u as $field)
{
$row[] = $field; // collect dynamic row fields
}
$data_rows[] = $row; // each row will have own array of fields
}
/// EDITED
public function generate_csv($table) // better to have table name here
{
$data_rows = array();
$data_rows = array();
global $wpdb, $bp;
$sql = "SELECT * FROM " . $table . "";
$data= $wpdb->get_results($sql);
$fh = #fopen( 'php://output', 'w' );
//following the example from: https://stackoverflow.com/a/31068464/1171074
$header_data=array();
foreach ( $wpdb->get_col( "DESC " . $table, 0 ) as $column_name ) {
$header_data[] = $column_name;
}
array_push($data_rows,$header_data); // first array will be columns names
foreach ($data as $u ) {
$row = array();
foreach ($u as $field)
{
$row[] = $field; // collect dynamic row fields
}
$data_rows[] = $row; // each row will have own array of fields
}
............ // rest of the code
}
You can use the virtual INFORMATION_SCHEMA.COLUMNS table to get the column names, like so:
"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = {$table}"
This should get you pretty close, if not all the way there. It will query the table, build a headers row for the csv, then it will assemble each data row. You shouldn't need to know the row name, if you iterate the response row as value..
I apologize up front if it's a little buggy, since I don't have a PHP box handy where I'm at to verify the precise syntax.
public function generate_csv() {
global $wpdb;
global $bp;
$headers = array();
$data_rows = array();
$table = 'ProductDetails';
$data_rows = array();
$header_row;
# determine table field names
$table_sql = sprintf("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '%s'",$table);
# this will run the query and stuff field names into
$resp = $wpdb->get_results($table_sql);
foreach($resp as $row){
array_push($headers,$row[0]);
}
# get the records from the datbase
$data= $wpdb->get_results(sprintf("SELECT * FROM %s",$table));
# open output handle
$fh = #fopen( 'php://output', 'w' );
foreach ($data as $record ) {
$row = array();
foreach($record as $value){
array_push($row,$value);
}
array_push($data_rows,$row);
}
header("Pragma: public");
... Some more header ...
header("Content-Transfer-Encoding: binary");
fputcsv( $fh, $headers );
foreach ( $data_rows as $data_row ) {
fputcsv( $fh, $data_row );
}
fclose( $fh );
return;
}
I have an file text with several informations, i want read the file
and cut the data inside:
My file looks like this :
firstname;lastname;computer;ip
firstname;lastname;computer;ip
firstname;lastname;computer;ip
I want load that file in my mysql base each time a line is added.
I start with this script but i do not understand why the first names are not added in my database
Here my script :
<?php
$data = fopen("./session_name", "r");
$i = 0;
while ($line = fgets($data))
{
$i++;
$line = explode(';', $line);
$two = explode(';', $line[0]);
foreach($two as $t)
{
$insert = "INSERT INTO `session_test`(`prenom`, `nom`, `computer`, `adress_ip`) VALUES ('" . trim($t) . "',"","","")";
mysql_query($insert_data);
}
}
?>
<?php
$data = fopen("./session_name", "r");
$query = "INSERT INTO `session_test`(`prenom`, `nom`, `computer`, `adress_ip`) VALUES ";
while ($line = fgets($data)) {
$exploded = explode(';', $line);
$values[] = vsprintf("('%s','%s','%s','%s')",array_map('trim',$exploded));
}
$query .= implode(',',$values);
// mysqli or PDO code to query;
Having checked a variety of questions but not being able to find quite what I need, I am at a bit of a loss.
I am trying to chose the columns from MySQL I want exported to CSV by parsing the column names and adding the valid column names to a $colnames array, then adding those values as headers to the CSV and then only displaying the relevant data from the database through a while loop.
I have looked at the following in particular having been guided there from other questions: How to get all the key in multi-dimensional array in php
Here is the code:
function query_to_csv($query, $filename, $attachment = false, $headers = true, $specs_off = false) {
if($attachment) {
// send response headers to the browser
header( 'Content-Type: text/csv; charset=UTF-8' );
header( 'Content-Disposition: attachment;filename='.$filename);
$fp = fopen('php://output', 'w');
} else {
$fp = fopen($filename, 'w');
}
$result = mysql_query($query) or die( mysql_error() );
if($headers) {
// output header row (if at least one row exists)
$row = mysql_fetch_assoc($result);
if($row) {
// PRODUCTS TABLE SPECIFIC - get rid of specs_ and free_ columns so have nicer data set for user
if($specs_off) {
$columnames = array_keys($row);
$colnames = array();
//$colnames = array_keys($row);
foreach($columnames as $key => $value) {
if((substr_count($value, "spec_") < 1) && (substr_count($value, "free_") < 1)) {
array_push($colnames, $value);
}
}
}
else {
$colnames = array_keys($row);
}
// add in additional columns if exporting client data
if($table == 'clients') {array_push($colnames, "products", "last_order_date");}
//write the colnames to the csv file
fputcsv($fp, $colnames);
// reset pointer back to beginning
mysql_data_seek($result, 0);
}
} // done with the headers etc, now lets get on with the data
// clear out and create the $row_data array
$row_data = array();
// run through the row array adding values to row_data as we go
while($row = mysql_fetch_assoc($result)) {
// create the array_keys_multi from https://stackoverflow.com/questions/11234852/how-to-get-all-the-key-in-multi-dimensional-array-in-php/11234924#11234924
function array_keys_multi(array $array) {
$keys = array();
foreach ($array as $key => $value) {
$keys[] = $key;
if (is_array($array[$key])) {
$keys = array_merge($keys, array_keys_multi($array[$key]));
}
}
return $keys;
}
// run the function on the $row array
array_keys_multi($row);
// now use the $keys array
foreach($keys as $key => $value) {
// check if the value is in the colnames array and if so push the data on to the $row_data array ready for export to CSV
if(in_array($value, $colnames)) {
array_push($row_data, $row[$value]);
}
}
// now we are ready to write the CSV
fputcsv($fp, $row_data);
}
fclose($fp);
exit;
} // end of query_to_csv
// Write the sql statement
$sql = "SELECT * FROM ".$table." ";
if(isset($where_1_col)) { $sql .= " WHERE `".$where_1_col."` = '".$where_1_val."'"; }
if(isset($where_2_col)) { $sql .= " AND `".$where_2_col."` = '".$where_2_val."'"; }
if(isset($where_3_col)) { $sql .= " AND `".$where_3_col."` = '".$where_3_val."'"; }
if(isset($where_4_col)) { $sql .= " AND `".$where_4_col."` = '".$where_4_val."'"; }
if(isset($order_by_col)) { $sql .= " ORDER BY `".$order_by_col."` ". strtoupper($order_by_dir) ." "; }
// output as an attachment
query_to_csv($sql, $table."_export.csv", true, true, true);
All I am getting is a huge export of the chosen column names repeated as many times as there are values from the initial query. I don't know how to get the values in.
Any suggestions on where I am going wrong or how I can undertake this more neatly are welcomed.
It seems that you just append the new row data to $row_data but never clear that array.
array_push($row_data, $row[$value]);
What I did to fix it:
Move
// clear out and create the $row_data array
$row_data = array();
into the while loop.
Change
// clear out and create the $row_data array
$row_data = array();
while($row = mysql_fetch_assoc($result)) {
...
}
To
while($row = mysql_fetch_assoc($result)) {
// clear out and create the $row_data array
$row_data = array();
...
}
Note:
You are using $table everywhere but never define it. Like here if($table == 'clients')
If it is a global var you need to add global $table or a parameter to your function, too.
Edit:
As mentioned in my comment on your question you could just use array_keys() to get the keys.
php.net/manual/de/function.array-keys.php
And then change
array_keys_multi($row);
to
$keys = array_keys($row);
After that you can remove array_keys_multi()
Further you could move that part in front of your while-loop because you only need to calculate the column names you need once and not in every iteration.