4

I need to insert entries to mysql table from the form below. 1-form contains many rows. 2-entry will not be always consecutive in the rows (meaning row 1 can be empty and next row not) 3-all rows containing entries should be saved in the db table.

i want to INSERT INTO oz2ts_custompc_details (part_id, quantity, price)

Here is my entry form (custompc_form2.php)

<!DOCTYPE html>
<html>
<body>

<form action="../subs/custompcorder2.php/" method="post" id="form">

            <p><input id="name" name="part_id[]"/> 
               <input type="text"  id="quantity" name="quantity[]"/>  
               <input id="name-data" type="text" name="price[]"/></p>

            <p><input id="name" name="part_id[]"/> 
               <input type="text" id="quantity" name="quantity[]"/>  
               <input id="name-data" type="text" name="price[]"/></p>

            <p><input id="name" name="part_id[]"/> 
               <input type="text" id="quantity" name="quantity[]"/> 
               <input id="name-data" type="text" name="price[]"/></p>

            <p><input id="name" name="part_id[]"/> 
               <input type="text" id="quantity" name="quantity[]"/> 
               <input id="name-data" type="text" name="price[]"/></p>   


    <input id="submit" type="submit" value="Submit Order" name="submission"/>


</form>
</body> 
</html>

here is What I came up with but still not working. here is the summary of how it is working: ||Rows 1 to 4 has data > all 4 are saved || row 1 is empty and rows 2 to 3 contains data > only rows 2 and 3 are saved not row 4|| Row 2 only has data all other are empty > Data not saved || Rows 2 and 3 has data > Row 2 only is saved

 <?php
include '../db/connect.php';


foreach (array('part_id', 'quantity', 'price') as $pos) {
foreach ($_POST[$pos] as $id => $row) {
    $_POST[$pos][$id] = mysqli_real_escape_string($con, $row);
}
}

$ids = $_POST['part_id'];
$quantities = $_POST['quantity'];
$prices =  $_POST['price'];

$items = array();

$size = count($ids);

for($i = 0 ; $i < $size ; $i++){
// Check for part id
if (empty($ids[$i]) || empty($quantities[$i]) || empty($prices[$i])) {
    continue;
}
$items[]=array(
    "part_id"     => $ids[$i], 
    "quantity"    => $quantities[$i],
    "price"       => $prices[$i]
);
}

if (!empty($items)) {
$values = array();
foreach($items as $item){
    $values[] = "('{$item['part_id']}', '{$item['quantity']}', '{$item['price']}')";
}

$values = implode(", ", $values);

$sql = "INSERT INTO oz2ts_custompc_details (part_id, quantity, price) VALUES     {$values}    ;
" ;
$result = mysqli_query($con, $sql );
if ($result) {
    echo 'Successful inserts: ' . mysqli_affected_rows($con);
} else {
    echo 'query failed: ' . mysqli_error($con);  

}
}

?> 

The first is a simplified entry form. The reel entry form looks like this:

    <!DOCTYPE html>
    <html>
    <head></head>
    <body>

    <form action="../subs/custompcorder2.php/" method="post" id="form">

          <div id="orderwrap">
         <div id="orderheather">
        <select id="platform" name="platform">
        <option selected="selected" disabled="disabled">Select the 
                    platform</option>
        <option value="Intel">Intel</option>
        <option value="AMD">AMD</option>
       </select> 
    </div> 

       <div id="orderbody">

         <p><select id="part_id" name="part_id[]">
                        <option selected="selected" disabled="disabled">Choose part1 </option>
                 <?php  query() ?> 
                 < /select>
                         <input type="text" id="quantity" name="quantity[]"/> 
                         <input id="name-data" type="text" name="price[]"/></p>

         <p><select id="part_id" name="part_id[]">
                        <option selected="selected" disabled="disabled">Choose part2 </option>
                 <?php  query2() ?> 
                 < /select>
                         <input type="text" id="quantity" name="quantity[]"/> 
                         <input id="name-data" type="text" name="price[]"/></p> 

         <p><select id="part_id" name="part_id[]">
                        <option selected="selected" disabled="disabled">Choose part3 </option>
                 <?php  query3() ?> 
                 < /select>
                         <input type="text" id="quantity" name="quantity[]"/> 
                         <input id="name-data" type="text" name="price[]"/></p> 

         <p><select id="part_id" name="part_id[]">
                        <option selected="selected" disabled="disabled">Choose part4 </option>
                 <?php  query4() ?> 
                 < /select>
                         <input type="text" id="quantity" name="quantity[]"/> 
                         <input id="name-data" type="text" name="price[]"/></p>  



        <input id="submit" type="submit" value="Submit Order"name="submission"/>

       </div>
      </div>    
        </form>


      </body> 

     </html>

Here is the php page containing function query(),query1(),..

<?php
include '../db/connect.php';


function query(){
global $con; 
$myData=mysqli_query($con,"SELECT * FROM oz2ts_mijoshop_product");
while($record=mysqli_fetch_array($myData)){
    echo'<option value="'.$record['product_id'].'">'.$record['model'].'</option>';
    }
}

function query2(){
global $con; 
$myData=mysqli_query($con,"SELECT * FROM oz2ts_mijoshop_product");
while($record=mysqli_fetch_array($myData)){
    echo'<option value="'.$record['product_id'].'">'.$record['model'].'</option>';
    }
}


function query3(){
global $con; 
$myData=mysqli_query($con,"SELECT * FROM oz2ts_mijoshop_product");
while($record=mysqli_fetch_array($myData)){
    echo'<option value="'.$record['product_id'].'">'.$record['model'].'</option>';
    }
}


function query4(){
global $con; 
$myData=mysqli_query($con,"SELECT * FROM oz2ts_mijoshop_product");
while($record=mysqli_fetch_array($myData)){
    echo'<option value="'.$record['product_id'].'">'.$record['model'].'</option>';
    }
}

function close(){
    mysqli_close($con);
    }


?>
user3412978
  • 97
  • 2
  • 3
  • 8
  • I want my insert query to check all the rows and pick collect data when the row is filled. If no move to the next row. Thank you for any advice – user3412978 Mar 22 '14 at 13:28
  • I got lost reading your post, but I suggest looking up [for loops](http://www.php.net/manual/en/control-structures.for.php) :-) – alexpja Mar 24 '14 at 22:47
  • additionally, I am getting this in php error log: PHP Notice: Undefined index: part_id in on line 4 (line 4: is $ids = mysqli_real_escape_string($con,($_POST['part_id']));) PHP Warning: mysqli_real_escape_string() expects parameter 2 to be string, array given in line 5 (line 5: is $quantities = mysqli_real_escape_string($con,($_POST['quantity']));) 'code'PHP Notice: Uninitialized string offset: 0 in line 14 (line 14 is: "part_id" => $ids[$i], )'/code' – user3412978 Mar 25 '14 at 01:55

3 Answers3

5
  1. Sanitize input correctly using array_map
  2. Check for input before adding to array
  3. Only run SQL if anything to be added

Use the following code:

<?php
include '../db/connect.php';

foreach (array('part_id', 'quantity', 'price') as $pos) {
    foreach ($_POST[$pos] as $id => $row) {
        $_POST[$pos][$id] = mysqli_real_escape_string($con, $row);
    }
}

$ids = $_POST['part_id'];
$quantities = $_POST['quantity'];
$prices =  $_POST['price'];

$items = array();

$size = count($ids);

for($i = 0 ; $i < $size ; $i++){
    // Check for part id
    if (empty($ids[$i]) || empty($quantities[$i]) || empty($prices[$i])) {
        continue;
    }
    $items[] = array(
        "part_id"     => $ids[$i], 
        "quantity"    => $quantities[$i],
        "price"       => $prices[$i]
    );
}

if (!empty($items)) {
    $values = array();
    foreach($items as $item){
        $values[] = "('{$item['part_id']}', '{$item['quantity']}', '{$item['price']}')";
    }

    $values = implode(", ", $values);

    $sql = "INSERT INTO oz2ts_custompc_details (part_id, quantity, price) VALUES  {$values}    ;
    " ;
    $result = mysqli_query($con, $sql );
    if ($result) {
        echo 'Successful inserts: ' . mysqli_affected_rows($con);
    } else {
        echo 'query failed: ' . mysqli_error($con);
    }
}
Aziz Saleh
  • 2,687
  • 1
  • 17
  • 27
  • I added echo $sql; after after $sql construction and added the mysqli_error($con); here is what I am getting: INSERT INTO oz2ts_custompc_details (part_id, quantity, price) VALUES ('', '', '') ; Successful inserts: 1 – user3412978 Mar 25 '14 at 01:42
  • additionally in the error log, i have: PHP Notice: Undefined index: part_id in on line 4 (line 4: is $ids = mysqli_real_escape_string($con,($_POST['part_id']));) – user3412978 Mar 25 '14 at 02:02
  • PHP Warning: mysqli_real_escape_string() expects parameter 2 to be string, array given in line 5 (line 5: is $quantities = mysqli_real_escape_string($con,($_POST['quantity']));) – user3412978 Mar 25 '14 at 02:03
  • PHP Notice: Uninitialized string offset: 0 in line 14 (line 14 is: "part_id" => $ids[$i], ) – user3412978 Mar 25 '14 at 02:03
  • Thank you but I am getting this error: PHP Warning: mysqli_real_escape_string() expects exactly 2 parameters, 1 given HERE > $ids = array_map('mysqli_real_escape_string', $_POST['part_id']); en no row is inserted – user3412978 Mar 25 '14 at 02:23
  • thank you it is partially working. it insert only consecutive rows if 1 row is empty, rows after the empty row won't be inserted. – user3412978 Mar 25 '14 at 02:47
  • Change: `$items[$i] = array` to : `$items[] = array` – Aziz Saleh Mar 25 '14 at 02:48
  • it is throwing PHP Notice: Undefined variable: POST in ||foreach ($POST[$pos] as $id => $row)|| – user3412978 Mar 25 '14 at 02:55
  • PHP Warning: Invalid argument supplied for foreach() > same line – user3412978 Mar 25 '14 at 02:56
  • Sorry typo, change `$POST` to `$_POST` – Aziz Saleh Mar 25 '14 at 02:58
  • Also, with $items[$i] = array, If the first row is empty and the 3 following has data, it will save only the second and the 3th row the last row will be ignored. – user3412978 Mar 25 '14 at 03:01
  • Yes, that's why you should change it to $items[] (see above comment). Updated code to reflect. – Aziz Saleh Mar 25 '14 at 03:04
  • Partially working: if row 1 and row 2 has data 2 others are empty, it will save 2 but when aver the first row is skipped, it will save only the first next row filled not the following event consecutive. I also tried row 1 empty, row 2 to 4 filled. it saved only row 2 and 3 not row 4 – user3412978 Mar 25 '14 at 03:16
  • I did the change already and I am getting same result: $items[]=array( "part_id" => $ids[$i], "quantity" => $quantities[$i], "price" => $prices[$i] – user3412978 Mar 25 '14 at 03:22
  • here is the summary of how it is working: ||Rows 1 to 4 has data > all 4 are saved || row 1 is empty and rows 2 to 3 contains data > only rows 2 and 3 are saved not row 4|| Row 2 only has data all other are empty > Data not saved || Rows 2 and 3 has data > Row 2 only is saved. This is with all change you asked me to do. I will edit my original post with code I have now – user3412978 Mar 25 '14 at 03:34
  • Aziz Saleh I copied and pasted the modified code but nothing changed. I hope you will have time to look into it. I am getting crazy because of this. Thank you a lot for all your help. – user3412978 Mar 25 '14 at 03:51
  • Do a `var_dump($_POST)` on the case when the first one is empty and the remaining three are not on top. – Aziz Saleh Mar 25 '14 at 13:22
  • like so include '../db/connect.php'; var_dump($_POST); ? – user3412978 Mar 25 '14 at 14:35
  • I did like above and I am getting this message: array(4) { ["quantity"]=> array(4) { [0]=> string(0) "" [1]=> string(0) "" [2]=> string(3) "102" [3]=> string(3) "105" } ["price"]=> array(4) { [0]=> string(0) "" [1]=> string(0) "" [2]=> string(3) "102" [3]=> string(3) "105" } ["part_id"]=> array(2) { [0]=> string(2) "30" [1]=> string(2) "31" } ["submission"]=> string(12) "Submit Order" } – user3412978 Mar 25 '14 at 14:40
  • Aziz I apologize your code was right. Issue is on my form. Here, I have posted a simple form. On the reel form, 'part_id' is a drop-down list getting data from another table thru php function. I am going to post how the reel form looks like and the php functions. I can't figure out why it is not working with dropdown list – user3412978 Mar 25 '14 at 15:23
  • BIG THANKS AZIZ FOR YOUR AVAILABILITY. Issue finally fixed. My dropdown list was messing me up. I fixed by enabling the default value and assigned an empty value to it. – user3412978 Mar 25 '14 at 19:59
  • This answer should be using a prepared statement. – mickmackusa Aug 15 '20 at 13:31
2

Here is a rough code, modify indeces by your own needs.

$ids = $_POST['part_id'] ;
$quantities = $_POST['quantity'] ;
$prices = $_POST['price'];

$items = array();

$size = count($names);

for($i = 0 ; $i < $size ; $i++){
  $items[$i] = array(
     "part_id"     => $ids[$i], 
     "quantity"    => $quantities[$i], 
     "price"       => $prices[$i]
  );
}


$values = array();
foreach($items as $item){
  $values[] = "('{$item['part_id']}', '{$item['quantity']}', '{$item['price']}')";
}

$values = implode(", ", $values);

$sql = "
  INSERT INTO oz2ts_custompc_details (part_id, quantity, price) VALUES {$values} ;
" ;
sybear
  • 7,837
  • 1
  • 22
  • 38
0

Here's an example of basic issue handling while inserting data. Included in error checks are

  1. Confirm that we received all 3 fields - part_id, quantity and price
  2. If there were 3 rows of part_id, there must be 3 rows of quantity and price
  3. Add safety by preparing INSERT statement
  4. Bind variables to the prepared statements
  5. Pick up only those rows in which all 3 fields (part_id, quantity and price) were entered, and that they were valid numbers

Code that receives POST

<?php

ini_set('display_errors', 'On');
error_reporting(E_ALL);

// debug information. Let's find what the page is receiving
echo '<pre>', print_r($_POST, true), '</pre>';

$postedData = $_POST;

// confirm that we received all 3 fields - part_id, quantity, price
$fieldsReceived = true;
if (   !confirmFields('part_id') 
    || !confirmFields('quantity')
    || !confirmFields('price')
) {
    echo 'part_id, quantity or price has not been received. Exiting.';
    exit;
}

// confirm that each of them have identical item-count
if (   count($postedData['part_id']) !== count($postedData['quantity'])
    || count($postedData['part_id']) !== count($postedData['price'])
) {
    echo count($postedData['price_id']) . 
        ' fields received for price_id, but different number of fields 
        were received for quantity or price. Please ensure that part_id,
        quantity and price have the same number of fields. Exiting.';
    exit;
}

// establish connection using mysqli_connect
$connection = mysqli_connect('localhost', 'user', 'pass', 'selected_db');

// prepare an insert statement
$sql = 'insert into oz2ts_custompc_details 
        (part_id, quantity, price) values 
        (?, ?, ?)';
$statement = mysqli_prepare($connection, $sql);

// bind integer, integer, double to the parameters in insert statement
// corresponding to the question marks
$part = 0;
$qty = 0;
$prc = 0.0000;
mysqli_stmt_bind_param($statement, 'iid', $part, $qty, $prc);

// loop through received data and only insert those that have valid values
// in part_id, quantity and price
$partsReceived = count($postedData['part_id']);
for ($i = 0; $i < $partsReceived; $i++) {

    // if drop down boxes are used and default value for part is
    // Choose part, let's see if user left the selection to default
    // and ignore that line
    if (strpos($postedData['part_id'][$i], 'Choose part') !== false) {
        continue;
    }

    // do we have numeric data in current line?
    // although not done here, one can check if part_id is integer (is_int)
    // quantity is_int and price is_float before proceeding further
    if (   !is_numeric($postedData['part_id'][$i])
        || !is_numeric($postedData['quantity'][$i])
        || !is_numeric($postedData['price'][$i])
    ) {
        echo '<p>Entry # ' . ($i + 1) . '
            will be ignored because of missing 
            or invalid part_id, quantity, or price</p>';
        continue;
    }

    // update bind parameters
    $part = $postedData['part_id'][$i];
    $qty = $postedData['quantity'][$i];
    $prc = $postedData['price'][$i];

    // execute statement and move on to the next one
    try {
        mysqli_stmt_execute($statement);
        echo '<p>Inserted part_id ' . $postedData['part_id'][$i] . '</p>';
    } catch (Exception $e) {
        echo '<p>Could not enter data with part_id '
            . $postedData['part_id'][$i] . '<br>' 
            . 'Error ' . $e->getMessage() . '</p>';
    }
}


// --------------------------
//        FUNCTIONS
// --------------------------

/**
 * Confirm that we received part_id, quantity and price from POST
 *
 * @param string $fieldName Name of the field to verify
 * 
 * @return bool True if fieldname is set as an array; False otherwise
 */
function confirmFields($fieldName) 
{
    global $postedData;
    return 
        (!isset($postedData[$fieldName])) 
        && !is_array($postedData[$fieldName]) ? false : true;
}

?>
zedfoxus
  • 35,121
  • 5
  • 64
  • 63
  • Thank you zfus. the code above works only when all rows are filled up. When there is an empty row(s) it will stop at: 2 fields received for price_id, but different number of fields were received for quantity or price. Please ensure that part_id, quantity and price have the same number of fields. Exiting. – user3412978 Mar 25 '14 at 13:48
  • Normal form will contain about 15 rows and not all will always been filled out. How can I get the code to continue event when there are empty rows? – user3412978 Mar 25 '14 at 13:51
  • Hi @user3412978, I have this exact code running on http://goo.gl/t7gWXk and it works for the tests I did. Can you do some data entry there for testing and provide me a use case that fails? It will help improve my code sample. – zedfoxus Mar 25 '14 at 13:57
  • I removed the first exit; and now it will stop at: 2 fields received for price_id, but different number of fields were received for quantity or price. Please ensure that part_id, quantity and price have the same number of fields. Exiting. Entry # 1 will be ignored because of missing or invalid part_id, quantity, or price Entry # 2 will be ignored because of missing or invalid part_id, quantity, or price. But data not inserted – user3412978 Mar 25 '14 at 14:02
  • Are you using the URL I provided in my comment or are you trying on your own web page? – zedfoxus Mar 25 '14 at 14:38
  • I tried same scenario on my site and on the link you gave me. || First row empty second not empty 3th empty 4th not empty|| on your link the result is Entry # 1 will be ignored because of missing or invalid part_id, quantity, or price Inserted part_id 12 Entry # 3 will be ignored because of missing or invalid part_id, quantity, or price Inserted part_id 10 on mine, || 2 fields received for part_id, but ..... Please ensure that part_id, quantity and price have the of fields. Exiting. Entry # 1 will be ignored because of missing or invalid part_id, quantity, or price Inserted part_id 33 || – user3412978 Mar 25 '14 at 14:55
  • on the link you provided, all cases are working perfectly. What do you thing might be wrong for me? – user3412978 Mar 25 '14 at 15:00
  • Let's figure that out. I have updated my code by adding a debug message (echo) at the top. Can you use the updated code on your site? When you test again you should see output starting with Array on the screen first. Copy and paste the Array preformatted text and we should be able to figure out what happens on your site. Also ensure that the HTML is exactly like you have in your post above. – zedfoxus Mar 25 '14 at 15:06
  • zfus Your code is right problem is probably coming from my form. on my example here, I posted a simple entry form. on the reel form, part_id is a drop-down list getting data from another table via a php query let me post what the reel form looks like and the functions that feed the drop-down list – user3412978 Mar 25 '14 at 15:10
  • Ah, that is quite possible. The piece of code that throws `Please ensure...have the same number of fields` just confirms that if you have a part_id[] field in the row, you must have quantity[] and price[] fields also. Similarly, your real form should have all the fields in each row. The HTML most likely has the issue. – zedfoxus Mar 25 '14 at 15:13
  • Yes the Html has issue and I can't figure out what is wrong. Please if you have a minute can you please take a look at it? I have edited my original post to include my html and functions for drop-down list – user3412978 Mar 25 '14 at 15:52
  • Ah, I think I know what's happening. One or more part_id dropdowns has no value and therefore the data doesn't get to the PHP page correctly. One way to overcome this is by removing disabled="disabled" so that `Choose part` becomes the default selection that goes to PHP. In PHP, we ignore if `Choose part` comes across as part_id. Code appropriately changed. Demo changed also: http://goo.gl/T5z5Zg – zedfoxus Mar 25 '14 at 18:33
  • Issue has been fixed it was my drop down list. I gave an empty valu to the default value and I enabled it:

    – user3412978 Mar 25 '14 at 19:57