printing array generated from fgetcsv is throwing undefined index - php

I want to get data from csv file having header row. I want to use the data using header row index. But it is showing undefined index. The code is as follows:
$count = 0;
$total = 0;
if ( false === $handle = fopen('hw_product.csv', 'r') )
throw new Exception('File open failed.');
$headers = fgetcsv($handle);
while ( false !== $fields = fgetcsv($handle) ) {
$fields = array_combine($headers, $fields);
$total++;
$p_id = $fields['id_product'];
$sku = $fields['sku'];
$url = $fields['url_key'];
$query = "UPDATE hw_product_lang SET link_rewrite = '$url' WHERE id_product = $p_id AND id_lang = 1";
if(mysqli_query($link,$query)){
$count++;
}
}
fclose($handle);
echo $count." rows processed out of ".$total;
Please help me what i am missing. Thanks

Related

Display array with array_search

I have an array of csv elements and I want to retrieve the key of the column 'Due Date' (the result is 10) and display the array at the column 10. However, it doesn't display the result but it will show the column 1 and I don't know why.
Code:
while (($line = fgetcsv($file)) !== FALSE) {
//$line is an array of the csv elements
$value = array_search('Due Date', $line);
print_r($line[$value]);
}
Just do it like this so you can easily get the column number 10:
$var = array();
while($row = fgetcsv($yourFile)) {
$var[] = $row;
}
//Get Column 10
$var[] = $row[9];
Edit:
<?php
$valueOfSearch = "YOUR VALUE OF SEARCH";
$linesOfCsv = file('YOUR PATH.csv');
$lineNumberOfCSV = false;
while (list($key, $line) = each($linesOfCsv) and !$lineNumberOfCSV) {
$lineNumberOfCSV = (strpos($line, $valueOfSearch) !== FALSE);
}
if($lineNumberOfCSV){
//Add YOUR CONDITION
}
?>
Open the fine and take csv values inside an array and close the file. After that try your logic.
So to get value you can use:
$file = 'file.csv';
$line = array();
$file = fopen($file,"r");
while(! feof($file))
{
$line = fgetcsv($file);
}
fclose($file);
$key = array_search('Due Date', $line);
print_r($line[$key]);

Implode Uploaded CSV Data for an Update Query

I have the following code to insert records into a database via a csv file
$get_columns = $db_website->prepare("SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'mytable' AND TABLE_NAME = 'products'");
$get_columns->execute();
while ($row = $get_columns->fetch(PDO::FETCH_ASSOC)) {
$want[] = $row['COLUMN_NAME'];
}
$file = fopen($_FILES['filename']['tmp_name'], "r");
$counter = 0;
while (!feof($file)) {
if ($counter === 1)
break;
$have = fgetcsv ($file, 5000);
++$counter;
}
fclose ($file);
$map = array_intersect($have, $want);
$num_feilds = implode($map);
$fields = "`".implode("`,`",$map)."`";
if ($num_feilds != '') {
$file = fopen($_FILES['filename']['tmp_name'], "r");
$line = fgetcsv($file, 1000, ",");
while (($line = fgetcsv($file)) !== FALSE) {
$data = array_intersect_key($line, $map);
$implode = str_replace("'", ''', $data);
$implode = str_replace("£", '£', $implode);
$implode = "'".implode("','",$implode)."'";
$query = $db_website->prepare("SELECT p.stock_id
FROM products AS p
WHERE p.stock_id = :data");
$query->bindValue(':data', $data[0], PDO::PARAM_INT);
$query->execute();
$product_exists = $query->rowCount();
if ($product_exists == 0) {
$product_import = "INSERT INTO products ($fields, token, date_created) VALUES ($implode, :token, :date_created)";
$product_import = $db_website->prepare($product_import);
$product_import->execute(array(':token'=>$token, ':date_created'=>$todays_date_time));
$update_slug = "UPDATE products SET slug = LOWER(title),
slug = replace(slug, char(128), '')
WHERE token = :token";
$update_slug = $db_website->prepare($update_slug);
$update_slug->execute(array(':token'=>$token));
} else {
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
$stock_id = $row['stock_id'];
$product_import = "UPDATE products SET $this_is_the_variable_i_need_to_create_from_the_implode, token = :token, date_updated = :date_updated
WHERE stock_id = :stock_id";
$product_import = $db_website->prepare($product_import);
$product_import->execute(array(':stock_id'=>$stock_id, ':token'=>$token, ':date_updated'=>$todays_date_time));
}
$update_slug = "UPDATE products SET slug = LOWER(title),
slug = replace(slug, char(128), '')
WHERE token = :token";
$update_slug = $db_website->prepare($update_slug);
$update_slug->execute(array(':token'=>$token));
}
}
fclose($file);
}
My problems lies in that I want it to update existing products as well as create new ones.
In the code above I have begun by doing a query to check whether the stock id exists and if it doesn't insert the record with an else to say update if it does.
The part I am struggling on is how do I make it implode the COLUMN_NAME and the data that is sent in the csv file.
Any tip in the right direction would be greatly appreciated.
Thank you
Dan
If I'm understanding you correctly, you need to create a series of set clauses based on what's in the $data array (which is an array containing the values from a single line of your CSV). Excluding any kind of validation (either of the columns in your import file, or the data in your import file) you could do something like this:
$sets = array();
$update_values = array();
foreach( $data as $index => $val )
{
if(empty($have[ $index ]))
continue;
$field_name = $have[ $index ];
$update_values[] = $val;
$sets[] = "{$field_name} = ':val{$index}'";
}
if( $sets )
{
$update_values[] = $stock_id;
$set_clause = implode(',',$sets);
$product_import = $db_website->prepare("UPDATE products SET {$set_clause} WHERE stock_id = :stock_id");
$product_import->execute( $update_values );
}
Again, you're going to want validate your input, but this should give you the idea.
Thank you oliakaoil,
This is the code I used in the end for anybody else who may need it in the future
$sets = array();
$update_values = array();
foreach ($data as $index => $val) {
if (empty($have[$index]))
continue;
$field_name = $have[$index];
$update_values[] = $val;
$sets[] = "{$field_name} = '{$val}'";
}
if ($sets) {
$update_values[] = $stock_id;
$set_clause = implode(',',$sets);
$product_import = "UPDATE products SET {$set_clause}, token = :token
WHERE stock_id = :stock_id";
$product_import = $db_website->prepare($product_import);
$product_import->execute(array(':stock_id'=>$update_values[0], ':token'=>$token));
}

CSV - not uploading all records

I'm trying to parse a small CSV file and insert the records into MySQL.
The problem I'm having is that the CSV has 150 rows, but only 2 seem to be inserted:
$file = new SplFileObject($uploadedFile);
$separator = ',';
$rowCounter = 1;
$errors = array();
$fh = fopen($uploadedFile, 'r');
if(!$fh) die('File no good!');
// Get headings
$headings = fgetcsv($fh, 0, ',');
$num_cols = count($headings);
$num_rows = 1;
// Read the file as csv
while ($row = $file->fgetcsv($separator)) {
//missed product if num columns in this row not the same as num headings
if (count($row) != $num_cols) {
$row = array_pad($row, $num_cols, NULL);
}
for ($i=0; $i<count($headings); $i++) {
$raw_prod[$headings[$i]] = $row[$i];
}
$item = new Item();
$item->name = $raw_prod['NAME'];
$item->age = $raw_prod['AGE'];
$item->location = $raw_prod['LOCATION'];
$item->save();
}
If I var_dump($item) I get all 150 records, but only 2 ever get inserted.
I just don't understand why this is happening
Thanks
This line
while ($row = $file->fgetcsv($separator)) {
should be
while (($row = $file->fgetcsv($separator)) !== false) {

invalid argument when imploding in php

Im getting invalid argument error when running the following code. Im trying to change the value of a line in the $info array, then implode it, implode its parent array, and then save the whole shebang back to whence it came.
$rowpre = $_GET['row'];
$newfieldvalue = $_GET['nfv'];
$row = --$rowpre;
$data = file_get_contents("temp.php");
$csvpre = explode("###", $data);
$i = 0;
foreach ( $csvpre AS $key => $value){
$i++;
if($i = $row){
$info = explode("%%", $value);
$info[$target] = $newfieldvalue;
$presave = implode("%%", $info);
}
}
$save = implode("###", $presave);
$fh = fopen("temp.php", 'w') or die("can't open file");
fwrite($fh, $save);
fclose($fh);
update below
$rowpre = $_GET['row'];
$newfieldvalue = $_GET['nfv'];
$target = $_GET['target'];
$row = --$rowpre;
$data = file_get_contents("temp.php");
$csvpre = explode("###", $data);
$i = 0;
foreach ( $csvpre AS $key => $value){
$i++;
if($i == $row){
$info = explode("%%", $value);
$info[$target] = $newfieldvalue;
$csvpre[$key] = implode("%%", $info);
}
}
$save = implode("###", $csvpre);
$fh = fopen("temp.php", 'w') or die("can't open file");
fwrite($fh, $save);
fclose($fh);
Target is the field within the selected Row that i wish to update with the newfieldvalue data.
$save = implode("###", $presave);
At that point, $presave is a string, and should be an array to work with implode. Create an array where you push the $presave-values, and implode that one.
$presave contains the last processed line (i.e. a string) and implode expects an array. To store the line back in the original array, change:
$presave = implode("%%", $info);
to:
$csvpre[$key] = implode("%%", $info);
And to convert the whole CSV array into a string, change:
$save = implode("###", $presave);
to:
$save = implode("###", $csvpre);
And one more problem:
if($i = $row){
should be:
if($i == $row){
because you want to compare the variables, not assign $i.

change value of a line in an array

I need to change the value of a line within an array to a given string, then implode and save the data. Im using the code below.
row is the row of the table.
target is the specific line in the array which i want to update.
nfv is the new string i want to put into the array.
<?
$rowpre = $_GET['row'];
$newfieldvalue = $_GET['nfv'];
$row = --$rowpre;
$data = file_get_contents("temp.php");
$csvpre = explode("###", $data);
$i = 0;
foreach ( $csvpre AS $key => $value){
$i++;
if($i = $row){
$info = explode("%%", $value);
$j = 0;
foreach ( $info as $key => $value ){
$j++;
if($j == $target){
/*change the value of this line to $newfieldvalue*/
}
}
}
}
$presave = implode("%%", $info);
$save = implode("###", $presave);
$fh = fopen("temp.php", 'w') or die("can't open file");
fwrite($fh, $save);
fclose($fh);
?>
You do realize that you can index into an array? If you already have the numeric index of an array element, just go ahead and change it:
$arr[$index] = "some new stuff";
Magically updated.

Categories