while inside while runs just once - php

I have a problem with this code, the thing is that the inner while just runs once while the outer while does it right. What could be the problem?
Note: $producto_id is an array with ids.
$st_column = 0;
$nd_column = 1;
$posicionArray = 0;
if (($handle = fopen($ruta, "r")) != FALSE) {
fgetcsv($handle);
mysqli_query($link, "BEGIN");
while($producto_id[$posicionArray]){
$ins_producto = mysqli_query ($link, "INSERT INTO productos (encuesta_id, producto_id, nom_producto) VALUES ('".$encuesta_id."', '".$producto_id[$posicionArray]."', '".$nombre_producto[$posicionArray]."')");
while (($data = fgetcsv($handle, 0, "$delimiter")) != FALSE) {
if($producto_id[$posicionArray] == $data[$st_column]){
$ins_cupon = mysqli_query ($link, "INSERT INTO cupones (encuesta_id, producto_id, cupon, estado) VALUES ('".$encuesta_id."', '".$producto_id[$posicionArray]."', '".$data[$nd_column]."', 0)");
}
}
$posicionArray ++;
}
fclose($handle);
}

I believe you have a csv, which holds ids and coupons. It seems you are trying to go through your producto_id array and check if that exists in your CSV. This is what I would do:
CSV:
id,cupon
1,15165165
1,16516151
2,16841684
PHP:
function turn_csv_to_array($csv) {
$result = array();
if (($h = fopen($csv, "r")) != FALSE) {
$header = fgetcsv($h);
while ($row = fgetcsv($h)) {
$result[] = array_combine($header, $row);
}
fclose($h);
}
return $result;
}
$coupons = turn_csv_to_array("test.csv");
$product_ids = [1, 2, 3, 4];
foreach ($product_ids as $pid) {
// INSERT PRODUCT TO PRODUCT_DB
foreach ($coupons as $c) {
if ($pid == $c['id']) {
// INSERT PRODUCT TO COUPONS_DB
}
}
}

It all depends on what you meant by:
($data = fgetcsv($handle, 0, "$delimiter")
if you meant:
($data == fgetcsv($handle, 0, "$delimiter"))
that is the value of data is equal to the result of fgetcsv
then your code is wrong. and switch to "=="
if you mean:
($data = fgetcsv($handle, 0, "$delimiter"))
and fgetcsv can return a "0" then that is why.
using "assignments" in the middle of if statements is always bad practice.
if you do an assignment in the middle of your if statement, the value of the assignment is passed on to the boolean expression. Any value other than 0 is considered true. otherwise a 0 is considered false.

Related

how to insert multiple array in mysql table

Im trying to insert array in mysql table... but my code doesn't work
$File = 'testfile.csv';
$arrResult = array();
$handle = fopen($File, "r");
$row = 0;
if(empty($handle) === false) {
while(($data = fgetcsv($handle, 1000, ";")) !== FALSE){
$arrResult[] = $data;
$num = count($data); //2100 resultats in my testfile
$row++;
if($row>1){ //ignore header line
for ($c=0; $c < $num; $c++) { //start loop
$sql = '
INSERT INTO MyTable (name, class, level, ability)
VALUES ("'.$data[0].'","'.$data[1].'","'.$data[2].'","'.$data[3].'")
';
$Add=$db->query($sql);
}
}
}
fclose($handle);
};
Result in Mytable:
1,Hero1, Warrior, 65, vitality;
2,Hero1, Warrior, 65, vitality;
3,Hero1, Warrior, 65, vitality;
4,Hero1, Warrior, 65, vitality;
...
You don't need the inner for loop. You're inserting the same row multiple times, since $count is the number of fields in the CSV.
And instead of checking $row each time through the loop, you can simply read the first line and ignore it before the loop.
if(empty($handle) === false) {
fgets($handle); // skip header line
while(($data = fgetcsv($handle, 1000, ";")) !== FALSE){
$sql = '
INSERT INTO MyTable (name, class, level, ability)
VALUES ("'.$data[0].'","'.$data[1].'","'.$data[2].'","'.$data[3].'")
';
$Add=$db->query($sql);
}
}
// remove `for` loop
if($row>1){ //ignore header line
$sql = '
INSERT INTO MyTable (name, class, level, ability)
VALUES ("'.$data[0].'","'.$data[1].'","'.$data[2].'","'.$data[3].'")
';
$Add=$db->query($sql);
}
And of course move to prepared statements to make your code more secure.

Skipping blank rows with fopen();

I currently have some code like this:
$handle = fopen($_FILES['file']['tmp_name'], "r");
$i = 0;
while (($data = fgetcsv($handle, 1000, ",")) !== false) {
if($i > 0) {
$sql = "
insert into TABLE(A, B, C, D)
values ('$data[0]', '$data[1]', '$data[2]', '$data[3]')
";
$stmt = $dbh -> prepare($sql);
$stmt->execute();
}
$i++;
}
fclose($handle);
This allows me to write to a certain table the contents of a CSV file, excluding the first row where all the names are. I want to be able to extract only the filled rows. How would I use so using this code?
fgetcsv returns an array consisting of a single null if the rows are empty
http://www.php.net/manual/en/function.fgetcsv.php
so you should be able to do a check based on that.
if ($data[0]===null)
{
continue;
}
or something like that
fgetcsv() returns an array with null for blank lines so you can do something like below.
$handle = fopen($_FILES['file']['tmp_name'], "r");
$i = 0;
while (($data = fgetcsv($handle, 1000, ",")) !== false) {
if (array(null) === $data) { // ignore blank lines
continue;
}
if($i > 0) {
$sql = "
insert into TABLE(A, B, C, D)
values ('$data[0]', '$data[1]', '$data[2]', '$data[3]')
";
$stmt = $dbh -> prepare($sql);
$stmt->execute();
}
$i++;
}
fclose($handle);
Based on the documentation, fgetcsv will return an array consisting of a single null value for empty rows, so you should be able to test the return value against that and skip blank lines that way.
The following example code will skip processing blank lines. Note that I have changed the file and removed some other logic to make it more easily testable.
<?php
$handle = fopen("LocalInput.txt", "r");
$i = 0;
while (($data = fgetcsv($handle, 1000, ",")) !== false) {
if($data== array(null)) continue;
var_dump($data);
$i++;
}
fclose($handle);
?>

Getting out of the inner loop and contnuing with the outer loop

i have a while loop which is fetching data from csv.Inside while loop there is a condition(if condition) if the condition is true foreach loop will get executed where we want to insert one row at a time into the database.This should continue for every row of the csv. if I have 10 rows in csv,it should insert all 10 rows in the database.But mycode is inserting the first row 10 times.
$handle = fopen($_FILES['upcsv']['tmp_name'], "r");
$count = count(file($_FILES['upcsv']['tmp_name']));
fgetcsv($handle, 1000, ",");
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE)
{
$clt = mysql_query("select MCLNTLKNOFLG,MCLNTDKTRNGFRM,MCLNTDKTRNGTO from mclientmst where MCLNTCD ='".$data[1]."'");
if(mysql_num_rows($clt)>0)
{
$clts = mysql_fetch_array($clt);
if($clts['MCLNTLKNOFLG']==1)
{
$i=1 ;
foreach(range ($clts['MCLNTDKTRNGFRM'], $clts['MCLNTDKTRNGTO']) as $num)
{
$dkt = mysql_query("select XCMPCD from xdockethdr where XDKTNO ='$num'");
$ndkt = mysql_query("select XCMPCD from xtempdockethdr where XDKTNO ='$num'");
if(mysql_num_rows($dkt)==0 && mysql_num_rows($ndkt)==0)
{
$date = explode('/',$data[3]);
$dt = $date[2].'-'.$date[1].'-'.$date[0];
$dktid = mysql_query("select MAX(XDKTID) as maxid from xtempdockethdr");
$maxid = mysql_fetch_array($dktid);
$max = $maxid['maxid'] +1;
$query = mysql_query("insert into xtempdockethdr (XCMPCD,XCLNTCD,XDKTNO,XCNSGCD,XDKTPUDATE,XDKTPUTIME,XDKTNOPKGS,XDKTMODLV,XDKTHTOCONCD,XDKTDCTVAL,XDKTDIMWT,XDKTACTWT,XUNIQUEID,XDKTID) VALUES ('".$data[0]."','".$data[1]."','".$num."','".$data[2]."','".$dt."','".$data[4]."','".$data[5]."','".$data[6]."','".$data[7]."','".$data[8]."','".$data[9]."','".$data[10]."','".$data[11]."','".$max."')");
$i++;
}
}
}
}
}
fclose($handle);
header('Location:upload_docketentry.php');
You need to set a break; after your code.
It will close first loop (foreach) and goes down.
Add continue 2; after sql inserts.
this will end this loop and goes to the begining of while loop and continue work.
$handle = fopen($_FILES['upcsv']['tmp_name'], "r");
$count = count(file($_FILES['upcsv']['tmp_name']));
fgetcsv($handle, 1000, ",");
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) // **#1 point**
{
$clt = mysql_query("select MCLNTLKNOFLG,MCLNTDKTRNGFRM,MCLNTDKTRNGTO from mclientmst where MCLNTCD ='".$data[1]."'");
if(mysql_num_rows($clt)>0)
{
$clts = mysql_fetch_array($clt);
if($clts['MCLNTLKNOFLG']==1)
{
$i=1 ;
foreach(range ($clts['MCLNTDKTRNGFRM'], $clts['MCLNTDKTRNGTO']) as $num)
{
$dkt = mysql_query("select XCMPCD from xdockethdr where XDKTNO ='$num'");
$ndkt = mysql_query("select XCMPCD from xtempdockethdr where XDKTNO ='$num'");
if(mysql_num_rows($dkt)==0 && mysql_num_rows($ndkt)==0)
{
$date = explode('/',$data[3]);
$dt = $date[2].'-'.$date[1].'-'.$date[0];
$dktid = mysql_query("select MAX(XDKTID) as maxid from xtempdockethdr");
$maxid = mysql_fetch_array($dktid);
$max = $maxid['maxid'] +1;
$query = mysql_query("insert into xtempdockethdr (XCMPCD,XCLNTCD,XDKTNO,XCNSGCD,XDKTPUDATE,XDKTPUTIME,XDKTNOPKGS,XDKTMODLV,XDKTHTOCONCD,XDKTDCTVAL,XDKTDIMWT,XDKTACTWT,XUNIQUEID,XDKTID) VALUES ('".$data[0]."','".$data[1]."','".$num."','".$data[2]."','".$dt."','".$data[4]."','".$data[5]."','".$data[6]."','".$data[7]."','".$data[8]."','".$data[9]."','".$data[10]."','".$data[11]."','".$max."')");
$i++;
// continue 2; // Goes to #1
// break; // Goes to #2
}
} // #2 point
var_dump(__LINE__); // This will executed if you place break operator
}
}
}
fclose($handle);
header('Location:upload_docketentry.php');

Count values in CSV

The .csv file:
question1,question2,question3,question4,question5,question6,question7,question8,question9,question10
yes,response,response,response,response,response,response,response,response,response
yes,response2,response2,response2,response2,response2,response2,response2,response2,response2
no,response3,response3,response3,response3,response3,response3,response3,response3,response3
I want to get this result in php.
$question = "the_question_goes_here"
question1
yes = 2
no = 1
The code must find the unique responses for each question and count how many of each.
Can anyone help?
str_getcsv() can be used to get a csv string as an array.
Using this you can write a loop over the array which counts up values (in pseudocode):
counts = array;
//Loop over each row
for(row in csvrows){
for(cell in row){
counts[rowHeader][cellValue] = counts[rowHeader][cellValue]+1;
}
}
This should do the trick reading the file contents into PHP
$data= array();
$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
foreach ($data as $position => $value) {
if($row == 1) {
$data[$position]['question'] = $value;
$data[$position]['yes'] = 0;
$data[$position]['no'] = 0;
continue;
}
if ($value == 'yes') {
$data[$position]['yes'] = $data[$position]['yes'] + 1
} elseif ($value == 'no') {
$data[$position]['no'] = $data[$position]['no'] + 1
}
}
$row++;
}
fclose($handle);
}
This will return a array which you can read like this
Array value
'question' key holding text
'yes' key holding numOf yes
'no'key holding numOf no

CSV to Json with header row as key

I would like to convert a CSV to Json, use the header row as a key, and each line as object. How do I go about doing this?
----------------------------------CSV---------------------------------
InvKey,DocNum,CardCode
11704,1611704,BENV1072
11703,1611703,BENV1073
---------------------------------PHP-----------------------------------
if (($handle = fopen('upload/BEN-new.csv'. '', "r")) !== FALSE) {
while (($row_array = fgetcsv($handle, 1024, ","))) {
while ($val != '') {
foreach ($row_array as $key => $val) {
$row_array[] = $val;
}
}
$complete[] = $row_array;
}
fclose($handle);
}
echo json_encode($complete);
Just read the first line separately and merge it into every row:
if (($handle = fopen('upload/BEN-new.csv', 'r')) === false) {
die('Error opening file');
}
$headers = fgetcsv($handle, 1024, ',');
$complete = array();
while ($row = fgetcsv($handle, 1024, ',')) {
$complete[] = array_combine($headers, $row);
}
fclose($handle);
echo json_encode($complete);
I find myself converting csv strings to arrays or objects every few months.
I created a class because I'm lazy and dont like copy/pasting code.
This class will convert a csv string to custom class objects:
Convert csv string to arrays or objects in PHP
$feed="https://gist.githubusercontent.com/devfaysal/9143ca22afcbf252d521f5bf2bdc6194/raw/ec46f6c2017325345e7df2483d8829231049bce8/data.csv";
//Read the csv and return as array
$data = array_map('str_getcsv', file($feed));
//Get the first raw as the key
$keys = array_shift($data);
//Add label to each value
$newArray = array_map(function($values) use ($keys){
return array_combine($keys, $values);
}, $data);
// Print it out as JSON
header('Content-Type: application/json');
echo json_encode($newArray);
Main gist:
https://gist.github.com/devfaysal/9143ca22afcbf252d521f5bf2bdc6194
For those who'd like things spelled out a little more + some room to further parse any row / column without additional loops:
function csv_to_json_byheader($filename){
$json = array();
if (($handle = fopen($filename, "r")) !== FALSE) {
$rownum = 0;
$header = array();
while (($row = fgetcsv($handle, 1024, ",")) !== FALSE) {
if ($rownum === 0) {
for($i=0; $i < count($row); $i++){
// maybe you want to strip special characters or merge duplicate columns here?
$header[$i] = trim($row[$i]);
}
} else {
if (count($row) === count($header)) {
$rowJson = array();
foreach($header as $i=>$head) {
// maybe handle special row/cell parsing here, per column header
$rowJson[$head] = $row[$i];
}
array_push($json, $rowJson);
}
}
$rownum++;
}
fclose($handle);
}
return $json;
}

Categories