I know about fgetcsv, but it doesn't really do what I'm looking for.
I have the following csv file:
productId,productName,productActive
1,test product,1
2,test product2,0
I'm looking for something that will create an array that looks like this:
array (0)
['productId'] => 1
['productName'] => test product
['productActive'] => 1
array (1)
['productId'] => 2
['productName'] => test product2
['productActive'] => 0
any ideas?
// open the file.
if (($handle = fopen("in.csv", "r")) !== FALSE) {
// read the column headers in an array.
$head = fgetcsv($handle, 1000, ",");
// read the actual data.
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
// create a new array with the elements in $head as keys
// and elements in array $data as values.
$combined = array_combine($head,$data);
// print.
var_dump($combined);
}
// done using the file..close it,
fclose($handle);
}
See it
Try something like this:
$rows = array();
$headers = fgetcsv($file);
while($line = fgetcsv($file)) {
$row = array();
foreach($line as $key => $value) {
$row[$headers[$key]] = $value;
}
$rows[] = $row;
}
You would have to write your own function for that. It has all sorts of implicit requirements such as the first line being the key indices. If that's what you always want then you can do:
if (($handle = fopen("test.csv", "r")) !== FALSE) {
$row_headers = fgetcsv($handle);
$output = array();
//don't specify a limit to the line length (i.e. 1000).
//just grab the whole line
while (($data = fgetcsv($handle)) !== FALSE) {
$num = count($data);
$row++;
$row_array = array();
//For each column, create a row array with the index being
//the column heading and the data being the row data.
for ($c=0; $c < $num; $c++) {
$row_array[$row_headers[$c]] = $data[$c];
}
//Add each row to the output
$output[] = $row_array;
}
print_r($output);
}
Giving the result of:
Array ( [0] => Array ( [productId] => 1 [productName] => test product [productActive] => 1 ) [1] => Array ( [productId] => 2 [productName] => test product2 [productActive] => 0 ) )
Related
i have two columns in csv file Name and Phone . If i given phone number as a variable $searchStr = "6059574150"; it has to find number in csv file and i need that contact name to get access dynamicaly like this $data['Name'] instead of $data['0']
MY php code
$header = array();
$final_result = array();
$file = fopen('example.csv', 'r');
if($file){
$row = 1;
while ($data = fgetcsv($file, 10000, ",")){
if($row == 1){
$header = array_values($data);
}
else{
$final_result[] = array_combine($header, array_values($data));
}
$row++;
}
}
echo "<pre>";
print_r($final_result);
my output is like this
Array
(
[0] => Array
(
[Names] => MICHAEL
[Phone] => 6059342614
)
[1] => Array
(
[Names] => GLENN
[Phone] => 6056296061
)
)
how to directly access column ? like this $data['Name']
If phone numbers are unique, you could do something like this:
<?php
$final_result = array();
$file = fopen('example.csv', 'r');
if($file) {
$header = fgetcsv($file, 10000, ",");
while ($data = fgetcsv($file, 10000, ",")) {
$final_result[$data[1]] = $data[0];
}
}
?>
If you have more than one name (person) for each phone number, you can concatenate them $final_result[$data[1]] .= ',' . $data[0];.
Example result:
array (
phone1 => 'name1',
phone2 => 'name2',
phone3 => 'name3',
)
To search a name from a phone number you have to do: $final_result[phone_number] and you get the name.
In your output array "$final_result" you can look for a Name by phone number this way:
$foundKey = array_search('pone_number_to_search', array_column($final_result, "Phone"));
$foundNames = $final_result[$foundKey]["Names"];
i have a csv-file where i have headings. the first column has a unique id.
im using following code for the output in arays and headings as keys:
function csv_to_array($filename='', $delimiter=',') {
if(!file_exists($filename) || !is_readable($filename))
return FALSE;
$header = NULL;
$data = array();
if (($handle = fopen($filename, 'r')) !== FALSE)
{
while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE)
{
if(!$header)
$header = $row;
else
$data[] = array_combine($header, $row);
}
fclose($handle);
}
return $data;
}
Now i get the output
Array
(
[0] => Array
(
[id] => 2548
[description ] => MyDescription
[value] => 5
)
[1] => Array
(
[id] => 2549
[description ] => MyDescription
[value] => 10
)
i want to put the "id" as key for the group array like
Array
(
[2548] => Array
(
[id] => 2548
[description ] => MyDescription
[value] => 5
)
[2549] => Array
but i cant call the id one group before.
You can just grab the ID first an put it into the $data array as an index. Do you want to keep the ID in the data? See the comments in the code
function csv_to_array($filename='', $delimiter=',') {
if(!file_exists($filename) || !is_readable($filename))
return FALSE;
$header = NULL;
$data = array();
if (($handle = fopen($filename, 'r')) !== FALSE)
{
while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE)
{
if(!$header)
$header = $row;
else{
$id = $row[0]; // grab the ID from the row / expectiong that the ID is in the first column of your CSV
//unset($row[0]); // <-- uncomment this line if you want to remove the ID from the data array
$data[$id] = array_combine($header, $row);
}
}
fclose($handle);
}
return $data;
}
I am trying to create a multidimensional array using CSV file so that for example:
"a","b","c"
1,2,3
4,5,6
would return as:
array(
'a' => array(1, 4),
'b' => array(2, 5),
'c' => array(3, 6),
)
But the code I have:
<?php
function readCSV($csvFile) {
$aryData = [];
$header = NULL;
$handle = fopen($csvFile, "r");
if($handle){
while (!feof($handle)){
$aryCsvData = fgetcsv($handle);
if(!is_array($aryCsvData)){
continue;
}
if(is_null($header)){
$header = $aryCsvData;
}
elseif(is_array($header) && count($header) == count($aryCsvData)){
$aryData[] = array_combine($header, $aryCsvData);
}
}
fclose($handle);
}
return $aryData;
}
print_r(readCSV("Book1.csv"));
?>
Returns it as:
Array(
[0] => Array ( [a] => 1 [b] => 2 [c] => 3 )
[1] => Array ( [a] => 4 [b] => 5 [c] => 6 )
)
Would appreciate any help!
Instead of building the end array as you go along. This code reads the header row before the loop, then just reads all of the data lines into another array. It then combines each element of the header array with the matching column from the data array (using array_column() and the position of the header element)...
function readCSV($csvFile) {
$aryData = [];
$output = [];
$header = NULL;
$handle = fopen($csvFile, "r");
if($handle){
$header = fgetcsv($handle);
while ($aryData[] = fgetcsv($handle));
foreach ( $header as $key=>$label) {
$output[$label] = array_column($aryData, $key);
}
fclose($handle);
}
return $output;
}
Read the first row of the file and create the associative array with empty columns. Then read each remaining row and loop through it, pushing the values onto the column arrays.
<?php
function readCSV($csvFile) {
$aryData = [];
$handle = fopen($csvFile, "r");
if($handle){
$headerRow = fgetcsv($handle);
if (!$headerRow) {
return $aryData;
}
foreach ($headerRow as $colname) {
$aryData[$colname] = [];
}
while ($aryCsvData = fgetcsv($handle)){
foreach ($headerRow as $colname) {
$aryData[$colname][] = each($aryCsvData);
}
}
fclose($handle);
}
return $aryData;
}
I'm trying to get a useable array.
This is what I did to get the following array from my .csv file.
$csv = array_map('str_getcsv', file($file));
array_walk($csv, function(&$a) use ($csv) {
$a = array_combine($csv[0], $a);
});
array_shift($csv);
Right now I've got an array with these keys and values:
[0] => Array
(
[Label;Account;Registered;Licensed;User;UserLicense] => Test;Test;No;No;test;no;
)
And I want to get an array like:
[0] => Array
(
[Label] => Test
[Account] => Test
[Registered] => No
[Licensed] => No
[User] => test
[UsreLicense] => no
)
Can anyone help me?
Thanks.
class arrCsv {
private $arr;
private function getValFromArray($item, $key) {
$arrKeys = explode(';', $key);
$arrVal = explode(';', $item);
array_pop($arrVal); // remove last empty item
$this->arr[] = array_combine($arrKeys, $arrVal);
}
function setNewArr($arItems) {
array_walk_recursive($arItems, array($this, 'getValFromArray'));
}
function getNewArr() {
return $this->arr;
}
}
$r = new arrCsv;
$r->setNewArr($csvArray);
$vals = $r->getNewArr();
The answer I found:
$usersCsv = array();
if (($handle = fopen($file, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
$usersCsv[] = $data;
array_walk($usersCsv, function(&$a) use ($usersCsv) {
$a = array_combine($usersCsv[0], $a);
});
}
fclose($handle);
array_splice($usersCsv, 0, 1);
}
Thanks for the help anyways!
my_custom_table:
id int(11)
product_type varchar(210)
product_serial varchar(210)
created_at datetime
//Upload CSV File
if (isset($_POST['submit'])) {
if (is_uploaded_file($_FILES['upload_csv']['tmp_name'])) {
echo "<h1>" . "File ". $_FILES['upload_csv']['name'] ." uploaded successfully." . "</h1>";
}
//Import uploaded file to Database
$handle = fopen($_FILES['upload_csv']['tmp_name'], "r");
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$wpdb->insert("my_custom_table", array(
"product_type" => $data[0],
"product_serial" => $data[1],
"created_at" => current_time('mysql', 1)
));
}
fclose($handle);
print "Import done";
}
Print $data output with delimiter ,:
Array
(
[0] => Product Name;product_serial
)
Array
(
[0] => iPhone 6;iphone-002
)
Array
(
[0] => iPhone 6;iphone-003
)
Print $data output with delimiter ;:
Array
(
[0] => Product Name
[1] => product_serial
)
Array
(
[0] => iPhone 6
[1] => iphone-002
)
Array
(
[0] => iPhone 6
[1] => iphone-003
)
Using above, Product Name and product_serial also gets inserted in DB which should be prevented. Also delimiter , does not output correct array while ; does.
How can I prevent CSV column names insertion and insert correct value in Database?
P.S: Using OpenOffice for CSV data insertion. Could formatting be an issue with delimiter ?
The general rule of thumb is the first line of CSV is the column names, therefore a quick skip counter will remove the first row for you:
$counter = 0;
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
// Skip the first row as is likely column names
if ($counter === 0) {
$counter++;
continue;
}
// Insert the row into the database
$wpdb->insert("my_custom_table", array(
"product_type" => $data[0],
"product_serial" => $data[1],
"created_at" => current_time('mysql', 1)
));
}
The other problem is CSV files can have varying column and row delimiters (AKA sometimes columns are sperated by comma, and other times semi colons ...etc) making parsing CSV quite difficult. I this example it seems your column delimiter is semi-colon so modifying your function parameters may fix it for you:
while (($data = fgetcsv($handle, 1000, ";")) !== FALSE) {
If you really must support multiple types of delimiter, the following code snippet may help you:
$csvFilePath = $_FILES['upload_csv']['tmp_name'];
$delimiter = $this->detectDelimiter($csvFilePath);
public function detectDelimiter($csvFile)
{
$delimiters = array(
';' => 0,
',' => 0,
"\t" => 0,
"|" => 0
);
$handle = fopen($csvFile, "r");
$firstLine = fgets($handle);
fclose($handle);
foreach ($delimiters as $delimiter => &$count) {
$count = count(str_getcsv($firstLine, $delimiter));
}
return array_search(max($delimiters), $delimiters);
}
Detect snippet taken from: HERE
Hope this helps.