PHP - Upload CSV data in custom Wordpress database - php

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.

Related

How to dynamically get column value from csv file using php

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"];

json_encode not working as expected using array source

In my php I am reading a file and successfully getting each row into an array ($line[1] because its a 3 column CSV and I just need the 2nd value):
while (($line = fgetcsv($file, 1000)) !== false)
{
$course[] = array('course' => $line[1]);
}
$course[] correctly contains the array like:
0 =>
array (size=1)
'course' => string 'Course One' (length=68)
1 =>
array (size=1)
'course' => string 'Course Two' (length=45)
Problem is I cannot get the array to convert to json using json_encode
$json_res = json_encode($course);
EDIT: So just to be clear, I have array like this
2 =>
array (size=1)
'course' => string 'Associate Degree of Business Studies' (length=36)
3 =>
array (size=1)
'course' => string 'Associate Degree of Business Administration' (length=43)
$json_encode , gives me
boolean false
ok after taking in consideration all the information you provided, your original code should work. Try this out and let me know if it works.
$file = new SplFileObject("file.csv");
$file->setFlags(SplFileObject::READ_CSV);
$course = array();
foreach ($file as $row) {
$line = array('course' => $row[1]);
array_push($course, $line);
}
$json_res = json_encode($course);
var_dump($json_res);
Update: Try this code and let me know if it works:
$file = fopen('file.csv', 'r');
$course = array();
while (($data = fgetcsv($file, 1000, ",")) !== FALSE) {
$line = array('course' => utf8_decode($data[1]));
array_push($course, $line);
}
$json_res = json_encode($course);
var_dump($json_res)
;

Explode using 2 delimiter for a single line

i need to upload a .txt file in database.
my .txt file is exactly looks like
Name|Code|Email|Designation|Number|Salary|Age\t
syed|101|syed#gmail.com|trainee|7222877798|6000|21\t
hari|102|hari#gmail.com|trainee|9554512582|6000|23\t
i have need to separate it with | and then \t.
while getting array, the first one achieved as what i expect. but i cant able make \t explode.. can any one help me on this forum??
my routine is described below
if ($_POST['frmSubmit']) {
$file = $_FILES['frmUpload']['tmp_name']; // Get Temporary filename
$handle = fopen($file,"r"); // Open the file and read
while($strBookData = fgets($handle, 4096)) { // To get Array from .txt
$strDatas[] = $strBookData;
$strTableColumn = count($strBookData);
}
$strDatas = explode("|",implode($strDatas));
printArray($strDatas); exit;
if ($strDatas) {
$strInsertRecords = 0;
$strDuplicationRecords = 0;
if ($strTableColumn == 7) {
for($k=1; $k<count($strDatas); $k++) { //$k=1 is initialized because $k[0] is a header field array.
$strStatus = doCheckDuplication($strDatas[$k]['2']);
if ($strStatus == 0) {
// Insert Code
$strData = $strDatas[$k];
doInsertEmployeeDetails($strData['0'], $strData['1'], $strDatas[$k]['2'], $strData['3'], $strData['4'], $strData['5'], $strData['6']);
$strInsertRecords++; // To Get Inserted Records Count.
} else {
$strDuplicationRecords++; // To Get Duplication Records Count.
}
}
}
}
Hi this will split the text you provided.
$text = 'Name|Code|Email|Designation|Number|Salary|Age\t
syed|101|syed#gmail.com|trainee|7222877798|6000|21\t
hari|102|hari#gmail.com|trainee|9554512582|6000|23\t';
//remove line endings
$text = str_replace(array("\r\n", "\r", "\n"), "", $text);
$rows = explode('\t', $text);
$data = array();
foreach ($rows as $row){
//don't include empty lines
if(!empty( $row )){
$data[] = explode('|', $row);
}
}
echo '<pre>';
var_export( $data );
Outputs:
array (
0 =>
array (
0 => 'Name',
1 => 'Code',
2 => 'Email',
3 => 'Designation',
4 => 'Number',
5 => 'Salary',
6 => 'Age',
),
1 =>
array (
0 => 'syed',
1 => '101',
2 => 'syed#gmail.com',
3 => 'trainee',
4 => '7222877798',
5 => '6000',
6 => '21',
),
2 =>
array (
0 => 'hari',
1 => '102',
2 => 'hari#gmail.com',
3 => 'trainee',
4 => '9554512582',
5 => '6000',
6 => '23',
),
);
However that said, there is a lot going on in your example, as for reading the file in. If it's not to large the best bet would be to use file_get_contents() that will read the whole file in one go. Otherwise in this part
$handle = fopen($file,"r"); // Open the file and read
while($strBookData = fgets($handle, 4096)) { // To get Array from
$strDatas[] = $strBookData;
$strTableColumn = count($strBookData);
}
You would be better off just concatenating the text.
$strDatas = '';
$handle = fopen($file,"r"); // Open the file and read
while($strBookData = fgets($handle, 4096)) { // To get Array from
$strDatas .= $strBookData;
}
And then splitting like I did above.
I think that you should first explode using '\t' as delimiter to get the substrings separated by \t (Name|Code|Email|Designation|Number|Salary|Age)
and then explode each substring using '|' as delimiter.
I wish that can help you

Why is my PHP array not entering a function as not being empty?

Basically, I am running an if statement if my array is empty.
For example:
$csv = array();
$csv_empty = array_filter($csv);
if (!empty($csv_empty))
{
Other code goes here
}
unset($csv);
Unfortunately, my if statement is not being entered at all. Here is a dump of my array:
Array
(
[0] => Array
(
[0] => email1#foo.com
[1] => email2#foo.com
[2] => email3#foo.com
)
)
If needed, this is how my array is being created, via a CSV file upload (This is NOT the if statement I am reffering to. This if statement runs perfectly fine without the other empty array checking if statement):
if(($handle = fopen($tmpName, 'r')) !== FALSE)
{
$row = 0;
while (($result = fgetcsv($handle)) !== false)
{
$csv[] = $result;
}
fclose($handle);
}
Anyone have any idea to why my if statement is not running? Is it possibly because my array is 2 levels? If I changed my array to single level, would this fix my problem?
Based on what you have provided , I did not see any problem :
$csv = array( 0 => array( 0 => 'email1#foo.com' ,1 => 'email2#foo.com' ,2 => 'email3#foo.com' ) );
$csv_empty = array_filter( $csv );
if( ! empty( $csv_empty ) )
echo 'In If';
else
echo 'In Else';
Displays :
In If
But if I consider the array to have false s as the items , the get filtered by the array_filter :
$csv = array( 0 => false ,1 => false);
$csv_empty = array_filter( $csv );
if( ! empty( $csv_empty ) )
echo 'In If';
else
echo 'In Else';
Displays
In Else
I am thinking your problem might somewhere else probably with the data .
You should really use count($csv_empty)>0 instead of empty in that if.

PHP CSV to Array in a specific way

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 ) )

Categories