I am currently doing the below in PHP; to convert a CSV file to usable JSON. This is working.... however,
$tmpName = $_FILES['csv']['tmp_name'];
move_uploaded_file($tmp_name, "/files/locations/");
$fh = fopen($tmpName, "r");
$csvData = array();
$keys = fgetcsv($fh, 0, ",");
while (($row = fgetcsv($fh, 0, ",")) !== FALSE) {
$csvData[] = array_combine($keys, $row);
}
// echo json_encode($csvData);
file_put_contents("/files/locations/locations.json",json_encode($csvData))
It is outputting the JSON like this:
{"Zipcode":"90210","City":"Something","Primary State":"Utah","County Code":"49530","County":"Loudoun"}
I would like the Zipcode field and it's value to be the header. So, like below, so I can use the Zipcode value as the ID of the data set. Is this possible?
{
"Zipcode":"90210": {
"City":"Something",
"Primary State":"Utah",
"County Code":"49530",
"County":"Loudoun"
}
Instead of pushing the row onto the array, assign to an array key.
$csvData[$row[0]][] = array_combine($keys, $row);
This assumes the zip code is in the first field in the row (as it appears to be from your example of the original JSON).
Using [] makes each zip code entry an array of locations. So the result will look like:
{ "90210": [
{
"Zipcode": "90210",
"City":"Something",
"Primary State":"Utah",
"County Code":"49530",
"County":"Loudoun"
}]
}
If you don't want the zip code to be redundantly included in the array elements, you can remove it from the key and values.
$keys = array_slice($keys = fgetcsv($fh, 0, ","), 1);
and
$zip = array_shift($row);
$csvData[$zip][] = array_combine($keys, $row);
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);
Let's assume I have a CSV file, which looks like:
[Line 1]: ID, Name, Birthday, Phonenumber, Email
[Line 2]:
[Line 3]: 1, Jim, 1978-02-01, 555-23-256, jim.doe#donotreply.com
[Line 4]: 2, Mia, 1985-12-21, 555-23-876, mia#donotreply.com
[Line 5]: 3, Wil, 1962-05-07, 555-23-456, wil.doe#donotreply.com
Now I am trying to wrap my head around this question:
How can I parse this file with PHP to get the following array?
$people = array(
[1] = array(
[Name] => "Jim",
[Birthday] => "1978-02-01",
[Phonenumber] = "555-23-256",
[Email] => "jim.doe#donotreply.com",
),
...
);
Any idea?
Use fopen and fgetcsv
In order to do this you need to first write a function for retrieving the data from the CSV and storing it in a variable, the function below will do this using fopen.
First, you'll need a function to read the CSV:
function utf8_fopen_read($fileName) {
$fc = iconv('windows-1250', 'utf-8//IGNORE', file_get_contents($fileName));
$handle = fopen("php://memory", "rw");
fwrite($handle, $fc);
fseek($handle, 0);
return $handle;
}
Once you've done this you'll want to manipulate the data you've just retrieved so you can create a multi-dimensional array of the results, populating the data into the associative keys like you described in your question.
Now we are going to make a call to the function above and store the results in $data, using a while loop we are going to iterate through the entire CSV and store all of the information into $people row by row.
Populating your array:
$people = [];
if(($handle = utf8_fopen_read('path/to/csv.csv')) !== FALSE) {
while(($data = fgetcsv($handle, 0, ',')) !== FALSE) {
$people[$i] = [];
for($c = 0; $c < count($data); $c++) {
$info = $data[$c];
if($i == 0) $fields[$c] = str_replace(' ', '', $info);
if($i > 0) $people[$ii][$fields[$c]] = $info;
}
if($i > 0) $ii++;
$i++;
}
fclose($handle);
}
Is there a way I can change specific key values into boolean or string. The conversion changes all the Data into string. For example the Key value "Date" should be an integer instead of a string.
<?php
function csvToJson($fname) {
if (!($fp = fopen($fname, 'r') )) {
die("Can't open file");
}
$key = fgetcsv($fp, "1024", ",");
$json = array();
while ($row = fgetcsv($fp, "1024", ",")) {
$json[] = array_combine($key, $row);
}
fclose($fp);
foreach ( $json as $k=>$v ) {
$json[$k]['dateRequested'] = $json[$k]['DATE'];
$json[$k]['assignedAgent'] = $json[$k]['AGENT'];
$json[$k]['finalCompanyName'] = $json[$k]['COMPANY NAME'];
unset($json[$k]['DATE']);
unset($json[$k]['AGENT']);
unset($json[$k]['COMPANY NAME']);
}
return json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
}
?>
<?php
$json_data = csvToJson("lms.csv");
?>
Try this:
while ($row = fgetcsv($fp, "1024", ",")) {
// here $row contains all the columns in it in a numeric array
// Means 0 => first column of csv, 2 => second column of csv and so on
// you can convert any specific column value like
$json[] = array($row[0], setype($row[0], "string"), and so on);
}
You can do like this:
$json[$k]['dateRequested'] = (int)($json[$k]['DATE']);
$json[$k]['assignedAgent'] = $json[$k]['AGENT'];
$json[$k]['finalCompanyName'] = $json[$k]['COMPANY NAME'];
Sample usage :
$int = (int)(123);
$bool = (bool)(1);
$string = (string)(1234);
var_dump($int);
var_dump($bool);
var_dump($string);
I have a file and I need the save the content of the file in my MySQL database. Here is the code that I am using to parse the file:
$lines = file($tmp_filename);
$data = array();
if (($handle = fopen($tmp_filename, 'r')) !== FALSE)
{
while (($row = fgetcsv($handle, 1000, ";", "\"", "\n")) !== FALSE)
{
$key = array_shift($row);
$data[$key] = $row;
}
fclose($handle);
}
and here are the contents of the file that I am parsing:
HDR;Payroll Interface;5496;2012-07-20
NM1;082;IN2;12345678;2001-01-15;Mr;Marcial;Gustav;Gustav,Marcial;PRI;Marcial
PR1;082;IN2;12345678;7 The School;Alvarez;Bahaghari; ;Gandum
PR2;082;IN2;12345678;400006;IND;M;M;2007-10-16;1976-03-31
PR3;082;IN2;12345678; ; ;A;
**truncated**
Click Here for full data
There are scenarios where the array has the same index and the same value but I still need to save these data but array overwriting occurs. What must be added to put the same array to a different array index?
Take a look at this and tell me what i am missing
The data in the array is being overwritten because you are reassigning the value of $key each time it is encountered.
What you want to do is create a secondary array as the $key value and push nodes into that array this way you end up with your expected result.
[
'NM1' => ['...', '...'],
'PR1' => ['...', '...']
]
The code would be,
while (($row = fgetcsv($handle, 1000, ";", "\"", "\n")) !== FALSE) {
$key = array_shift($row);
// Notice the extra []
$data[$key][] = $row;
}
Each key will now contain an array with a node for each row encountered.
try changing:
...
$data[$key] = $row;
to
...
$data[][$key] = $row;
I am new to PHP and would like to be able to read in a csv file which has two columns, one is the number (kind of like a ID) then the other holds a integer value. I have looked up the fgetcsv function but I have not been able to find a way to read a specific column from the csv file.
I would like to get all the values from the second column only, without the heading.
Any way of doing this?
This is what I have so far:
$file = fopen('data.csv', 'r');
$line = fgetcsv($file);
And this is some sample data from the csv file:
ID,Value
1,243.00
2,243.00
3,243.00
4,243.00
5,123.11
6,243.00
7,180.00
8,55.00
9,243.00
Any help would be appreciated.
Thanks.
fgetcsv() only reads a single line of the file at a time. You'll have to read the file in a loop to get it all:
$data = array();
while($row = fgetcsv($file)) {
$data[] = $row;
}
The heading you can skip by doing an fgetcsv once outside the loop, to read/trash the header values. And if you only want the second column, you can do:
$data[] = $row[1];
However, since you've got data in there, maybe it might be useful to keep it, plus key your new array with the ID values in the csv, so you could also have:
$data[$row[0]] = $row[1];
and then your nice shiny new array will pretty much exactly match what's in the csv, but as an array keyed by the ID field.
$csv = array_map("str_getcsv", file("data.csv", "r"));
$header = array_shift($csv);
// Seperate the header from data
$col = array_search("Value", $header);
foreach ($csv as $row) {
$array[] = $row[$col];
}
// Iterate through data set, creating array from Value column
$header = fgetcsv($h);
$rows = array();
while ($row = fgetcsv($h)) {
$rows []= array_combine($header, $row);
}
$fp = fopen($filePath, "r+");
$header = fgetcsv($fp);
while ($members = fgetcsv($fp)) {
$i = 0;
foreach ($members as $mem) {
$membersArray[ $i ][ ] = $mem;
$i++;
}
}
$newArray = array_combine($header, array_map("array_filter",$membersArray));
You can also use this class http://code.google.com/p/php-csv-parser/
<?php
require_once 'File/CSV/DataSource.php';
$csv = new File_CSV_DataSource;
$csv->load('data.csv');
var_export($csv->connect());
?>