Edit on my original post. I found the answer!!!! with help:)
I now have this working by using the below code with thanks for the advice on this in the comments:
<?php
$f = fopen('incident_csv\test.csv', 'w');
$query = "
select column1, column2, column3
from table
where columns = values
";
$var1 = mysql_query($query, $database connection variable);
/* From Monkey Zeus */
$csv_lines = array();
// Loop your records from the DB
while ($row = mysql_fetch_assoc($var1)){
$columns = array();
// Loop each column for the row
foreach($row as $k=>$v){
// Surround column item in double-quotes and escape double-quotes with double-double-quotes
$columns[] = '"'.str_replace('"', '""', $v).'"';
}
// Join on a comma
$csv_lines[] = implode(',', $columns);
}
// Create full CSV file by joining on a newline
$csv_file_string = implode("\n", $csv_lines);
/* From Monkey Zeus */
fwrite($f, $csv_file_string);
?>
You can do this:
$csv_lines = array();
// Loop your records from the DB
while ($row = mysql_fetch_assoc($var1)){
$columns = array();
// Loop each column for the row
foreach($row as $k=>$v){
// Surround column item in double-quotes and escape double-quotes with double-double-quotes
$columns[] = '"'.str_replace('"', '""', $v).'"';
}
// Join on a comma
$csv_lines[] = implode(',', $columns);
// Write to the file right away. You are using PHP4 so I imagine system memory is not plentiful
// If you use this then there is no need for the "$csv_lines[] =" from above
// nor the $csv_file_string after the while loop
// fwrite($f, implode(',', $columns)."\n");
}
// fclose($f); // If you choose to write to the file during the while loop then close the file handle when you are finished
// Create full CSV file by joining on a newline
$csv_file_string = implode("\n", $csv_lines);
You can simply wite an arrayToCsv function:
function arrayToCsv($array) {
$string = array();
foreach ($array as $field) {
$string[] = implode(';', $field);
}
return implode("\n", $string);
}
$a = array(
array('First Field of First Line', 'Second Field of First Line'),
array('First Field of Second Line', 'Second Field of Second Line')
);
fwrite($f, arrayToCsv($a));
But, remember to have your $f setted from $f = fopen('file location', 'w');
Hope I was helpful.
Related
I have a csv import export function where the database table has a category and a sub category column within the data structure.
The Database Fields are: 'SKU*', 'Name', 'Origin', 'Stock', 'Category', 'SubCategory', 'RRP', 'Price Enq', 'Description', 'Dimensions', 'SEO Meta Description', 'SEO Page Title', 'Priority'
I need to implode the values of each of these with a separator of >
so it would be Category>SubCategory in one column for both the heading line and the line values of each row.
now i know on an import from a csv i can run an explode to split the 2 columns out from the csv:
$temp = explode(">", strtoupper($data["productCategory"]));
$data["productCategory"] = trim($temp["0"]);
$data["productSubCategory"] = trim($temp["1"]);
but i cannot for the life of me work out how to take the 2 columns from the database and implode them correctly
id assumed that this would work:
// Merge productCategory and productSubCategory
$temp = implode(strtoupper($data["productCategory"])).">". implode(strtoupper($data["productSubCategory"]));
$data["productCategory"] = $temp;
but I cant work out how to incorporate that correctly into the export code im working with:
$field = "";
$values = array();
// Generate the Heading Row & SQL Select Keys
if (isset($layout) === true) {
foreach ($layout as $data => $ar) {
if ($ar['csv'] === true || $ar['csv'] == "Y") {
// Build SQL Select Query
if (strlen($field) > 0) {
$field .= ', ';
}
$field .= "`".$data."`";
// Add Heading to Array
array_push($values, $ar['heading']);
}
}
// Add Heading to Array
array_push($values, "Delete");
}
// Open New CSV File
$fp = fopen('product_data.csv', 'w');
// Insert Heading Row
fputcsv($fp, $values);
$sql = "SELECT ".$field." FROM 'Product' ORDER BY `productSKU` ";
$result = sql_exec($sql);
while ($line = $result->fetch_assoc()) {
// Reset values array for each line
$values = array();
// Go through data and generate array for fputcsv()
foreach ($line as $key => $data) {
// Decode HTML Entities in the Data (so people know what they're looking at)
$data = html_entity_decode($data, ENT_QUOTES | ENT_HTML401, "UTF-8");
// Add Data to array for fputcsv
array_push($values, $data);
}
// Add line to the CSV
fputcsv($fp, $values);
}
fclose($fp);
can anyone please exlain or advise how to achieve this?
TIA
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 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;
I want to extract some data and create a csv file. This is how my attributes table looks like. you can see it in the picture:
HERE
This is my code, what i tried:
$select = mysql_query("select * from attributes");
$final ="";
$i = 0;
while($row = mysql_fetch_array($select)) {
$id_produs = $row['id_produs'];
$n_attr = $row['nume_attr'];
$val = $row['val_attr'];
$final .= $id_produs . "%%" . $val . "%%";
$csv_array_attributes[$i] = $final;
$i++;
}
This is the part when i create the CSV file:
$file = fopen("attributes.csv", "w+");
foreach ($csv_array_attributes as $line) {
fputcsv($file, explode('%%', $line), "^", "`");
}
fclose($file);
AND this would be the wanted result: HERE. So, the nume_attr should be the header for every column in the csv and the val_attr should be the values for every nume_attr (see the image).
I tried many ways but I don't get this result from the image. I have to mention that my table "attributes" has more than 74000 rows.
This is the table structure:
CREATE TABLE `attributes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_produs` text NOT NULL,
`nume_attr` text NOT NULL,
`val_attr` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=673912 DEFAULT CHARSET=latin1;
/*Try following code */
$select = mysql_query("select * from attributes");
$i = 0;
$csv_array_attributes[$i]=array('sku','manufacturer_article','manufacturer');
$i++;
while($row = mysql_fetch_array($select)) {
$csv_array_attributes[$i] =array('sku'=>$row['id_produs'],'manufacturer_article'=>$row['nume_attr'],'manufacturer'=>$row['val_attr']);
$i++;
}
$file = fopen("attributes.csv", "w+");
foreach ($csv_array_attributes as $line) {
fputcsv($file,$line);
}
fclose($file);
Let's assume speed isn't the issue here and neither is concurrency, i.e. you just want the result now no matter how good, bad or ugly the solution is ;-)
First query all the attribute names via SELECT DISTINCT nume_attr FROM attributes
Store those names as keys of an array with empty string values, i.e. you should have an array like
$template = array(
'Manufacturer Article' => '',
'Manufacturer' => '',
...
)
Make a variable that stores the currently processed id_produs (start with false).
Make a variable that stores the current "csv"-record ( again start with false )
Query all records ordered by id_produs and iteratore over the result.
If the current record has a different id_produs than the "currently processed" write out the current "csv"-array and start anew with the template array created in the first step and the current id_produs as ...the current id_produs. For each record write the val_attr value to the key nume_attr in the csv array.
You will have to check/write the last record after the iteration.
/* try following code,and reply if it will helpful to you or not */
$select = mysql_query("select * from attributes");
$i = 0;
$i++;
while($row = mysql_fetch_array($select)) {
$csv_array_attributes[$row['id_produs']][$row['nume_attr']] =$row['val_attr'];
$i++;
}
$arraytempheader=array();
$arraytemp=array();
$arraytempheader[0]="";
$j=1;
foreach ($csv_array_attributes as $Colname=>$alline) {
if($j!=1)
{
foreach($arraytempheader as $key=>$val)
{
if($key!=$j && $key!=0)
$arraytemp[$Colname][$key]="";
}
}
foreach ($alline as $keyline=>$valline)
{
$arraytempheader[$j]=$keyline;
$arraytemp[$Colname][$j]=$valline;
$j++;
}
}
$file = fopen("attributes.csv", "w+");
fputcsv($file,$arraytempheader);
foreach ($arraytemp as $Colname=>$alline) {
$finalArray=array();
$finalArray[]=$Colname;
$finalArray=array_merge($finalArray,$alline);
fputcsv($file,$finalArray);
}
fclose($file);
Try to fix this in other way.
Here you select the attributes and store them into array
$select = mysql_query("select * from attributes");
$rezultat=array();
while($row = mysql_fetch_array($select)) {
$id_produs = $row['id_produs'];
$n_attr = $row['nume_attr'];
$val = $row['val_attr'];
//$final .= $id_produs . "%%" . $val . "%%";
$rezultat[] = array('id'=>$id_produs,'attr'=>$val);
}
And here you write them to the file.
$file = fopen("attributes.csv", "w+");
foreach ($rezultat as $line) {
fputcsv($file, $line, "^", "`");
}
fclose($file);
I want to know that how can I replace a specific word/string of a particular line into a text file with php.
Contents of text file is as below:
1|1|1
nikki|nikki#yahoo.com|nikki
nikki|nikki#gmail.com|nikki
nikki|nikki#hotmail.com|nikki
DETAILS OF FIELDS:
COLUMN:0 = $name,
COLUMN:1 = $email,
COLUMN:2 = $nickname,
DETAILS OF REPLACEMENT:
COLUMN:0 = $newName,
COLUMN:1 = $newEmail,
COLUMN:2 = $newnickName,
From the above content you can guess that the find/search is based on the column:1. Ans if match found, than replace the column:0 OR column:2 [based on the choice].
I tried [for finding the column:1]:
$fileData = file("file.txt");
foreach($fileData as $Key => $Val) {
$Data[$Key] = explode("|", $Val);
if ( trim($Data[$Key][1]) == $email ){
unset($fileData[$Key]);
//REPLACE TAKE PLACE HERE
break;
}
}
[for replace]:
/* REPLACE NAME */
$file = "file.txt";
$oname = "|$name|";$nname = "|$newName|";
file_put_contents($file, str_replace($oname, $nname, file_get_contents($file)));
/* REPLACE NICKNAME */
$file = "file.txt";
$onickname = "|$nickname|";$nnickname = "|$newnickname|";
file_put_contents($file, str_replace($onickname, $nnickname, file_get_contents($file)));
But it was replacing all the matching "$name".
I also tried in the following way:
$fileData[$Key] = str_replace($name, $newName, $fileData[$Key]);
file_put_contents($file,$fileData);
/* $name & $newName -:> $nickname & $newnickname
But it doesn't works.
If i want to replace column:0 ["nikki"] of "nikki#gmail.com" with "nikkigmail", then the data should be:
1|1|1
nikki|nikki#yahoo.com|nikki
nikkigmail|nikki#gmail.com|nikki
nikki|nikki#hotmail.com|nikki
And, if want to replace column:2 ["nikki"] of "nikki#hotmail.com" with "hotmail", then:
1|1|1
nikki|nikki#yahoo.com|nikki
nikkigmail|nikki#gmail.com|nikki
nikki|nikki#hotmail.com|hotmail
May i get the code to be corrected ?
Here is how I would replace something like this. Instead of worrying about str_replace, why not actually modify the array returned by file?
<?php
$email = "nikki#gmail.com"; // Search email
$data = file("file.txt", FILE_IGNORE_NEW_LINES); // Read in the data
foreach($data as $key => $line) {
$bits = explode("|", $line);
if($bits[1] === $email) {
// Update this in place,
$bits[0] = "nikkigmail";
$data[$key] = implode("|", $bits);
}
}
$write = implode("\n", $data); // the data to write however you please.
Keep in mind this can also be expanded to suit your row/column needs. For example, you could use something like this.
/**
* The reason these are named differently is because they don't always
* search/replace. For example, you can find nikki#gmail.com in one row,
* but just be setting a different column in that row to a value..
*/
$match = array('col' => 1, 'str' => 'nikki#gmail.com'); // Search data at row
$update = array('col' => 0, 'str' => 'nikkigmail'); // Replace data at row
$data = file("file.txt", FILE_IGNORE_NEW_LINES); // Read in the data
foreach($data as $key => $line) {
$bits = explode("|", $line);
if($bits[$match['col']] === $match['str']) {
// Update this in place,
$bits[$update['col']] = $update['str'];
$data[$key] = implode("|", $bits);
}
}
$write = implode("\n", $data); // the data to write however you please.