Alex
Alex

Reputation: 181

PHP: How to correctly loop through multi-dimen post arrays

If I have a form with fields like this.

THERE WILL BE MULTIPLE ROWS OF THESE FIELDS HENCE THE SQUARE BRACKETS

<input type="text" name="txt-receipt-number[]" value="" />
<input type="text" name="txt-stock-number[]"  value="" />
<input type="text" name="txt-repair-code[]" value="" />

How do I loop through the $_POST variable to get the values because its getting the field names but not the values, what am I doing wrong please?

$fields = array();
$values = array();

foreach($_POST as $field => $value) {
   $fields[] = $field;
   echo $value;

}

Output:

ArrayArrayArrayArrayArrayArrayArrayArrayArray

Update:

Sorry, quick edit for correct output...

Further Update:

Lets ignore the insert, how do I get the values please?

Upvotes: 0

Views: 925

Answers (5)

Dr Casper Black
Dr Casper Black

Reputation: 7468

This is a little bit strange but try it :

<?php
foreach($_POST['txt-receipt-number'] as $k=>$v){
   $array[$k]['txt-receipt-number']      =  $_POST['txt-receipt-number'][$k];
   $array[$k]['txt-stock-number']        =  $_POST['txt-stock-number'][$k];
   $array[$k]['txt-repair-code']         =  $_POST['txt-repair-code'][$k];

}
$fields = array();
$values = array();
foreach($array as $row) {
foreach($row as $field => $value) {
    $values[] = $value;
    $fields[] = $field;
}
}

var_dump($fields);
var_dump($values);

?>

<form method='post' action=''>
<input type="text" name="txt-receipt-number[]" value="" /><br>
<input type="text" name="txt-stock-number[]"  value="" /><br>
<input type="text" name="txt-repair-code[]" value="" /><br>
----

<input type="text" name="txt-receipt-number[]" value="" /><br>
<input type="text" name="txt-stock-number[]"  value="" /><br>
<input type="text" name="txt-repair-code[]" value="" /><br>
<input type="submit" value="go">

</form>

Upvotes: 0

N.B.
N.B.

Reputation: 14091

foreach($_POST as $field => $value)
{
    if(is_array($value))
    {
        foreach($value as $k => $val)
        {
            echo $val;
        }
    }
    else
    {
        echo $value;
    }
}

Works for regular fields and one-dimensional _POST fields.

Upvotes: 0

binaryLV
binaryLV

Reputation: 9122

To be honest, I see many problems in this code...

  1. Using foreach to build dynamic list of fields that need to be inserted. Don't you have, for example, anything like <input type='submit' name='add_data'/>? It's common to have submit buttons, and, with your code, you would try to edit DB table's field named add_data. This is also unsafe, as it (a) reveals table structure and (b) gives possibility to make SQL errors by manually changing field names, which may lead to another security/stability issues.
  2. Lack of escaping field names. May lead to SQL injections.
  3. Using - sign in field names. insert into table(sales_receipt-number, ... just won't work.

As for handling posted arrays...

<form method='post' action=''>
    <table border='1'>
        <tr>
            <td><input type='text' name='receipt_number[]'/></td>
            <td><input type='text' name='stock_number[]'/></td>
            <td><input type='text' name='repair_code[]'/></td>
        </tr>
        <tr>
            <td><input type='text' name='receipt_number[]'/></td>
            <td><input type='text' name='stock_number[]'/></td>
            <td><input type='text' name='repair_code[]'/></td>
        </tr>
        <tr>
            <td><input type='text' name='receipt_number[]'/></td>
            <td><input type='text' name='stock_number[]'/></td>
            <td><input type='text' name='repair_code[]'/></td>
        </tr>
        <tr>
            <td colspan='3'>
                <input type='submit' name='add_items'/>
           </td>
        </tr>
    </table>
</form>

<pre>
<?php

function handleAddingItem() {
    if ( !isset($_POST['receipt_number'], $_POST['stock_number'], $_POST['repair_code']) ) {
        trigger_error("Some field is undefined");
        return false;
    }
    if ( !is_array($_POST['receipt_number']) || !is_array($_POST['stock_number']) || !is_array($_POST['repair_code']) ) {
        trigger_error("Some field is not an array");
        return false;
    }
    $keys = array_keys($_POST['receipt_number']);
    if ( array_keys($_POST['stock_number']) !== $keys || array_keys($_POST['repair_code']) !== $keys ) {
        trigger_error("Posted arrays have different keys");
        return false;
    }
    foreach ( $keys as $key ) {
        if ( empty($_POST['receipt_number'][$key]) && empty($_POST['stock_number'][$key]) && empty($_POST['repair_code'][$key]) ) {
            continue;
        }
        $receiptNumber = mysql_real_escape_string($_POST['receipt_number'][$key]);
        $stockNumber = mysql_real_escape_string($_POST['stock_number'][$key]);
        $repairCode = mysql_real_escape_string($_POST['repair_code'][$key]);
        $sql = "
            insert into table_name set
                receipt_number = '{$receiptNumber}',
                stock_number   = '{$stockNumber}',
                repair_code    = '{$repairCode}'
        ";
        echo $sql;
    }
    return true;
}

function handlePost() {
    print_r($_POST);
    if ( isset($_POST['add_items']) ) {
        handleAddingItem();
    }
}

if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) {
    handlePost();
}


?>

Output:

Array
(
    [receipt_number] => Array
        (
            [0] => 123
            [1] => 
            [2] => 
        )

    [stock_number] => Array
        (
            [0] => 
            [1] => 
            [2] => 
        )

    [repair_code] => Array
        (
            [0] => 
            [1] => 
            [2] => 
        )

    [add_items] => Submit Query
)

            insert into table_name set
                receipt_number = '123',
                stock_number   = '',
                repair_code    = ''

Common practice might be to pass additional field - row's ID. If it has a value, then action is "edit", if it is empty, action is "create".

Upvotes: 0

Michael Berkowski
Michael Berkowski

Reputation: 270767

You will have some other problems though, with column names like sales_receipt-number, etc. You should enclose those in backquotes, and you must also escape them since they are going directly into your SQL statement. They are just as vulnerable to SQL injection as the VALUES().

$fields[] = "`" . mysql_real_escape_string($field) . "`";

Update 2

To get the values and do the insert in a loop, the SQL needs to be reconstructed each time in the loop, using one set of array values.

// Find the number of loops necessary
// Unless all fields are always required, this will need to be the $_POST key with the most values
$numLoops = count($_POST['txt-receipt-number']);

fields = array();
$values = array();

for ($i = 0; $i < count($_POST); $i++) {
  foreach($_POST as $field => $value) {
     $fields[] = "`" . mysql_real_escape_string($field) . "`";
     $values[] = mysql_real_escape_string($_POST[$field][$i]);

     // Now build the SQL for this loop iteration.
     $sql = 'insert into table(' . join(',', $fields) . ') values(' . join(',', $values) . ')';
  }
}

Upvotes: 0

xdazz
xdazz

Reputation: 160943

Remove the [] of your text input, or you will get $value of array type.

<input type="text" name="txt-receipt-number" value="" />
<input type="text" name="txt-stock-number"  value="" />
<input type="text" name="txt-repair-code" value="" />

And don't forget to quote your values.

Upvotes: 1

Related Questions