Export mysql data in CSV in CakePHP - php

In CakePHP, with the following code i am trying to Export users email in CSV.
I am getting Errors.
Code Refrence site
Error:
Notice (8): Undefined offset: 0 [APP\View\Frontusers\admin_exportemails.ctp, line 12]
Warning (2): fputcsv() expects parameter 2 to be array, null given [APP\View\Helper\CsvHelper.php, line 36]
Notice (8): Undefined offset: 1 [APP\View\Frontusers\admin_exportemails.ctp, line 12]
Warning (2): fputcsv() expects parameter 2 to be array, null given [APP\View\Helper\CsvHelper.php, line 36]
admin_exportemails.ctp
$line= $useremails[0]['Frontuser'];
$this->CSV->addRow(array_keys($line));
foreach ($useremails as $key => $useremail)
{
$line =$useremail[$key]['Frontuser'];
$this->CSV->addRow($line);
}
$filename='useremails';
echo $this->CSV->render($filename);

You're messing up your foreach. You split it up in the $key and the $useremail sub-array, which is OK. But then you iterate over it and try to access $useremail[$key]['Frontuser'] again, which is nonexistent at that point.
foreach ($useremails as $key => $useremail)
This causes the [0] and [1] in the original $useremails array to be set as $key, but you iterate over all the items over the $useremails, so you can simply:
$line = $useremail['Frontuser'];
You don't need the $key, since that's not part of the iterated item, e.g. the first time your foreach runs, it sees this:
[Frontuser] => Array
(
[name] => Rash
[email] => rash.com
)
And on the second iteration it sees this:
[Frontuser] => Array
(
[name] => John
[email] => john#gmail.com
)
So there is no [0] or [1] index anymore.

$useremail[$key]['Frontuser'];
should be
$useremail['Frontuser'];
Actually there's no need for your code to include the key in the foreach loop at all.
That's PHP 101, so for further information please refer to the manual: http://php.net/foreach

You can simply pass your data array in that function and your csv generated in webroot folder.
Note:- 1. You should put blank csv file at webroot folder.
2. you should store all information in a sub array which contain only values not Model index.
function generate_csv($data_array=array()){
// pr($data_array);die;
foreach ($data_array as $key => $value) {
$newdata[] = $key.','.$value;
}
// pr($newdata);die;
$f = fopen(APP.'webroot/csv_file.csv', 'w+');
foreach ($newdata as $line) {
fputcsv($f, array($line), ',');
}
fseek($f, 0);
fclose($f);
}

you made mistake in the for loop and iterated it in wrong way.just ommit the below line from the foreach loop.
$line =$useremail[$key]['Frontuser'];

Here have tow options
1. save csv file in folder not sent output to browser and
2. send output to browser
function generate_csv($data_array = array()) {
//$f = fopen(APP . 'webroot/files/unsaved_bars.csv', 'w+'); // for save csv file in folder not sent output to browser
$f = fopen("php://output", "a"); // for send output to browser
$headers[] = array('id','name','other_info'); // for header row
$data_array = array_merge($headers, $data_array);
foreach ($data_array as $line) {
fputcsv($f, $line, ',');
}
//fseek($f, 0);
fclose($f);
}

Related

php var with multiple assoc arrays, get values one array at a time

Originally I was taking an uploaded .csv file and iterating through the values one row at a time.. with the below while loop.
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
var_dump($data);
$importIt = $repo->impThreeCSV($which, $data);
}
I have redone the .csv upload functionality to now be a web form where I send json to the PHP file on a 'save button'. I now have a variable with multiple associative arrays in it..
$fd = json_decode($df, true);
var_dump($fd);
For instance the dump above contains multiple arrays such as below: i.e. (~300 similar arrays as below).
array (size=806)
0 =>
array (size=18)
'ATM_ID' => string 'AFF-MIL-TWR' (length=11)
'FAC_IDENT' => string 'AFF' (length=3)
'LG_NAME' => string 'BLACH BLAH ACADEMY' (length=20)
'BASIC_TP' => string 'MIL-TWR' (length=7)
.................
How can I iterate through the VALUES only in these arrays, one at a
time in the same fashion as my original while loop.. (this would be
ideal so I don't have to redo the whole back-end).
I am having issues handling the multiple arrays and getting the
values only out..
I have tried the below two attempts, I just get 'arrayarrayarray' or
similar in var_dump. Do I need to break out each array into it's
own var? What am I doing wrong here? Do I need to run a count on how
many arrays consist in my var?
$fd = json_decode($df, true);
var_dump($fd);
$data = array_values($fd);
foreach ($data as $array_key) {
echo $array_key;
}
$array_keys = array_keys($fd);
foreach ($array_keys as $array_key) {
echo $array_key;
}
P.S. No, I can't use pandas, I wish.
Assuming you want to process the data in the same way as your original piece of code, you would just use something like:
foreach ($fd as $data) {
$importIt = $repo->impThreeCSV($which, array_values($data));
}
Note I've used array_values to convert $data from an associative array to a numerically indexed one, i.e. the same format as fgetcsv returns. This may - dependent on your $repo->impThreeCSV code - not be necessary.
You need to do a foreach to loop through each array, and then do another foreach to loop through every value of the array you're looping through.
$decodedJson = [
[
'ATM_ID' => 'AFF-MIL-TWR 1',
'FAC_IDENT' => 'AFF',
'LG_NAME' => 'BLACH BLAH ACADEMY',
'BASIC_TP' => 'MIL-TWR',
],
[
'ATM_ID' => 'AFF-MIL-TWR 2',
'FAC_IDENT' => 'AFF',
'LG_NAME' => 'BLACH BLAH ACADEMY',
'BASIC_TP' => 'MIL-TWR',
],
];
foreach ($decodedJson as $array) {
foreach ($array as $item) {
print $item; # => AFF-MIL-TWR 1
}
}

Write to CSV with PHP function fputcsv

I am using fputcsv to write to a CSV from MySQL results:
$list = array("group, variable, value \r\n");
while ($row = mysqli_fetch_assoc($result)) {
array_push($list, $row['strand_pk'] . ',' . $row['unit_name']. "\r\n");
}
$fp = fopen('../reports/data.csv', 'w');
fputcsv($fp, $list);
fclose($fp);
The array when printed on the browser page looks like:
Array
(
[0] => group, variable, value
[1] => 1,Integrated Medical Systems 1
[2] => 1,Integrated Medical Systems 2
[3] => 1,Integrated Medical Practice 1
...
)
The CSV with output looks like:
"group, variable, value
","1,Integrated Medical Systems 1
","1,Integrated Medical Systems 2
","1,Integrated Medical Practice 1
..."
What I need is the CSV to look like:
group,variable,value
1,IMP 3,40
1,IMP 2,8
1,IMP 1,54
1,IMS 2,10
What am I doing wrong here?
fputcsv expects proper, one-dimensional arrays (not comma-separated strings).
Your code should look something like this:
$list = ['group', 'variable', 'value'];
while ($row = mysqli_fetch_assoc($result)) {
$list[] = [$row['strand_pk'], $row['unit_name']]; // you're missing a value here though
}
Then you'll need to loop over the array before writing into the file:
foreach ($list as $row) {
fputcsv($fp, $row);
}
Note that you might not need to build $list at all if you only need to create the CSV with it. Use fputcsv directly within your while loop then.

Use array for array push instead of a string

I'm using the following code:
$patients_with_site = [];
if (in_array($zip_code, $current_zip_codes)) {
echo "The referral id is: ".$referral_id;
array_push($patients_with_site,$referral_id);
print_r($patients_with_site);
}
I'm then trying to push it to a CSV file with this code:
$fp = fopen('patients_with_site.csv', 'w');
foreach ($patients_with_site as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
I'm getting an error saying that the $patients_with_site is a string and fputcsv requires an array.
If fputcsv requires array - provide array:
foreach ($patients_with_site as $fields) {
fputcsv($fp, [$fields]);
}
And yes, every value of $patients_with_site is a string and not array.
Your $patients_with_site's elements are strings.
The second argument of fputcsv must be an array, so unless you have a multidimensional array for $patients_with_site you shouldn't loop through it.
So it should work if you only call fputcsv($fp, $patients_with_site).
See PHP fputcsv

Access php array index issue

After use fgetcsv() function I get an array, then I use a foreach() and I get a "simple" associative array like:
Array
(
[ix,radical,variant,simplified,pinyin,english,strokes] => 1,一,,,yi1,one,1
)
Then I try to access any element and I fail:
echo $record['ix'];
Notice: Undefined index: ix
echo next($record); // return nothing!
Maybe is offtopic (not centred in php language) but I'm using some lib (not necessary of course from PHP commenter in http://php.net/manual/es/function.fgetcsv.php)
<?php
require "..\CsvImporter.lib.php";
$importer = new CsvImporter('my_route\\my.csv',true);
while($records = $importer->get())
{
// debug
print_r($records[0]);
exit;
foreach ($records as $record)
{
\\ ..
}
}
And my screen output is
Array ( [ix,radical,variant,simplified,pinyin,english,strokes] => 1,一,,,yi1,one,1 )
My data:
ix,radical,variant,simplified,pinyin,english,strokes
1,一,,,yi1,one,1
2,丨,,,gun3,line,1
3,丶,,,zhu3,dot,1
So how is possible I'm unable to access any key ?
As you posted your data above. Your csv importer giving you each row with comma. So you need to explode it then use however you want to use
Example code \
$i=0;
while($records = $importer->get())
{
if($i>0) //skip first row it is heading
{
$data = explode(',',$records);
print_r($data);
// now `$data[0]` contains `ix` value for your first csv row and so on
}
$i++;
}
I used some lib and the default delimiter was "\t" so something like 'ix,radical,variant,simplified,pinyin,english,strokes' was THE key and '一,,,yi1,one,1' the only value
Now, I see the problem I can do it easy:
$f = 'file.csv';
$separator = ',';
$file = file_get_contents($f);
// bi-dimensional array
$regs = array_map(function($reg){return (explode($separator,$reg));},explode("\n",$file));
Thanks all!

Export Subarray and email each section

I have a multidimensional array that is like this:
Array (
[email1#fake.com] => Array (
[0] => Array (
[asin] => B004HFS6Z0
[title] => Kindle, Wi-Fi, Graphite, 6" Display
[price] => 114.00
[map] => 125.00 ) )
[email2#fake.com] => Array (
[0] => Array (
[asin] => B004CYX17O
[title] => Rizzy Home Apple 10-Piece Comforter Set, King
[price] => 502.80
[map] => 520.00 ) ) )
What I am trying to do is export the sub array under the email address into a file, then email it to the email address. So far, I've only been able to export both subarrays into a single file and haven't been able to get it to overwrite the file for the second sub array.
Here is the code I am working with:
require('export-xls.class.php');
$filename = 'email.xls';
$xls = new ExportXLS($filename);
$header[] = "ASIN";
$header[] = "Title";
$header[] = "Retail";
$header[] = "MAP";
$xls->addHeader($header);
//create temp csv file and email from subarray
foreach($map_check2 as $email => $value) {
//$fp = fopen('uploads/email.csv', 'w+');
foreach($value as $subkey => $subvalue) {
//echo $email . "<br>";
//print_r($subvalue) . "<br>";
//fputcsv($fp, $subvalue);
$xls->addRow($subvalue);
}
$xls->emailFile();
}
I need to export it to an excel file and have been using the export-xls.class to do so. I would have used the csv but periodically there will be commas in values in the array.
emailFile() is:
public function emailFile() {
#build the xls
$xls = $this->buildXLS();
$fp = fopen("uploads/email.xls", "w+");
fwrite($fp, $xls);
fclose($fp);
}
Does anyone have any thoughts? Or does that make sense?
It seems in your inner foreach loop, where you are doing $xls->addRow($subvalue), it keeps on adding all email sub-arrays. I think you should call some function inside the outer foreach but before the inner one, to clean the rows that have already been added to $xls.
Here is a test run that I could think of:
first call to the outer foreach is made - $email = email1#fake.com
first call to the inner foearch is made - calls $xls->addrow() for each of the values of the "email1#fake.com" array
first call to $xls->emailFile() is called that opens "email.xls" in w+ mode and writes the contents to the file
second call to the outer foreach is made - $email = email2#fake.com
second call to the inner foearch is made - calls $xls->addrow() for each of the values of the "email2#fake.com" array. Note - I think at this point the rows added earlier to $xls in step 2 still exist and this might be the issue. If yes, you need to some cleanup either before the inner foreach starts or in the $this->buildXLS() method
second call to $xls->emailFile() is called that opens "email.xls" in w+ mode and writes the contents to the file that includes values for both the subarrays.
I'm not sure what is the purpose of $this->buildXLS() and have ignored it for my explanation above.
Does the above make sense?

Categories