-3

I want to insert all values with just a function and I don't want to rewrite the same code many times but I have the problem that this function just inserts the first values (I checked the input name and it's set correctly).

$name = htmlspecialchars($_POST["name"]);  
$prix = htmlspecialchars($_POST["prixing"]); 
$prixn = htmlspecialchars($_POST["quantite"]);  
$uniteing = $_POST['unite']; 
$date = date('Y-m-d');
<?php

$servername = "localhost"; 
$username = "root"; 
$password = "test"; 
$dbname = "test";

// Create connection $conn = mysqli_connect($servername, $username, $password, $dbname);

// Check connection if (!$conn) {   die("Connection failed: " . mysqli_connect_error());    }  // 
  variable $date = date('Y-m-d');

$name = htmlspecialchars($_POST["name"]);      
$name1 = htmlspecialchars($_POST["name1"]); 
$prix = htmlspecialchars($_POST["prixing"]);   
$prix1 = htmlspecialchars($_POST["prixing1"]); 
$prixn = htmlspecialchars($_POST["quantite"]); 
$prixn1 = htmlspecialchars($_POST["quantite1"]); 
$uniteing = $_POST['unite'];    
$uniteing1 = $_POST['unite1'];

$name2 = htmlspecialchars($_POST["name2"]);          
$name3 = htmlspecialchars($_POST["name3"]); 
$prix2 = htmlspecialchars($_POST["prixing2"]);       
$prix3 = htmlspecialchars($_POST["prixing3"]); 
$prixn2 = htmlspecialchars($_POST["quantite2"]);     
$prixn3 = htmlspecialchars($_POST["quantite3"]); 
$uniteing2= $_POST['unite2'];   
$uniteing3 = $_POST['unite3'];

$name4 = htmlspecialchars($_POST["name4"]);          
$name5 = htmlspecialchars($_POST["name5"]); 
$prix4 = htmlspecialchars($_POST["prixing4"]);       
$prix5 = htmlspecialchars($_POST["prixing5"]); 
$prixn4 = htmlspecialchars($_POST["quantite4"]);     
$prixn5 = htmlspecialchars($_POST["quantite5"]); 
$uniteing4 = $_POST['unite4'];  
$uniteing5 = $_POST['unite5'];

$name6 = htmlspecialchars($_POST["name6"]);          
$name7 = htmlspecialchars($_POST["name7"]); 
$prix6 = htmlspecialchars($_POST["prixing6"]);       
$prix7 = htmlspecialchars($_POST["prixing7"]); 
$prixn6 = htmlspecialchars($_POST["quantite6"]);     
$prixn7 = htmlspecialchars($_POST["quantite7"]); 
$uniteing6 = $_POST['unite6'];  
$uniteing7 = $_POST['unite7'];

$name8 = htmlspecialchars($_POST["name8"]);          
$name9 = htmlspecialchars($_POST["name9"]); 
$prix8 = htmlspecialchars($_POST["prixing8"]);       
$prix9 = htmlspecialchars($_POST["prixing9"]); 
$prixn8 = htmlspecialchars($_POST["quantite8"]);     
$prixn9 = htmlspecialchars($_POST["quantite9"]); 
$uniteing8 = $_POST['unite8'];  
$uniteing9 = $_POST['unite9'];

$name10 = htmlspecialchars($_POST["name10"]); 
$prix10 = htmlspecialchars($_POST["prixing10"]); 
$prixn10 = htmlspecialchars($_POST["quantite10"]); 
$uniteing10 = $_POST['unite10'];

//end variable 2

function insert($namex, $prixx,$prixnx, $datex, $uniteingx,$conn)
{
    $sql = "INSERT INTO ingredient 
                VALUES ('$namex','$prixx','$prixnx','$datex','$uniteingx')"; 
    $res = mysqli_query($conn, $sql);

    if ($res) { 
        echo "New record created successfully"; 
        mysqli_error($conn); 
    } else {   
        echo "_error_: " . $sql . "<br>" . mysqli_error($conn);
    }
} 

insert($name, $prix,$prixn, $date, $uniteing,$conn); 
insert($name1, $prix1,$prixn1, $date1, $uniteing1,$conn); 
insert($name2, $prix2,$prixn2, $date2, $uniteing2,$conn); 
insert($name3, $prix3,$prixn3, $date3, $uniteing3,$conn); 
insert($name4, $prix4,$prixn4, $date4, $uniteing4,$conn); 
insert($name5, $prix5,$prixn5, $date5, $uniteing5,$conn); 
insert($name6, $prix6,$prixn6, $date6, $uniteing6,$conn); 
insert($name7, $prix7,$prixn7, $date7, $uniteing7,$conn); 
insert($name8, $prix8,$prixn8, $date8, $uniteing8,$conn); 
insert($name9, $prix9,$prixn9, $date9, $uniteing9,$conn); 
insert($name10, $prix10,$prixn10, $date10, $uniteing10,$conn);

header('Location: ../index.html'); ?>

Here is my form:

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" type="text/css" href="css/style.css">
<meta charset="utf-8">
</head>

<body>
<form action="php/insert-multi-ing.php" method="POST">

<table>
  <tr>
    <th>Nom Ingrédient</th>
    <th>Prix Ingrédient</th>
    <th>Quantite Ingrédient</th>
    <th>Unite</th>
  </tr>
  <tr>
    <td><input type="text" name="name"></td>
    <td><input type="text" name="prixing"></td>
     <td><input type="text" name="quantite"></td>
     <td>

        <select name="unite" id="unites">
          <option value="kg">kg</option>
          <option value="G">G</option>
          <option value="L">L</option>
          <option value="ml">Ml</option>
          <option value="cl">Cl</option>
          <option value="Piece">Piece</option>
        </select>
      </td>
    </tr>
    <tr>
        <td><input type="text" name="name1"></td>
        <td><input type="text" name="prixing1"></td>
        <td><input type="text" name="quantite1"></td>
        <td>

            <select name="unite1" id="">
                <option value="kg">kg</option>
                <option value="G">G</option>
                <option value="L">L</option>
                <option value="ml">Ml</option>
                <option value="cl">Cl</option>
                <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name2"></td>
        <td><input type="text" name="prixing2"></td>
        <td><input type="text" name="quantite2"></td>
        <td>

            <select name="unite2" id="">
                <option value="kg">kg</option>
                <option value="G">G</option>
                <option value="L">L</option>
                <option value="ml">Ml</option>
                <option value="cl">Cl</option>
                <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name3"></td>
        <td><input type="text" name="prixing3"></td>
         <td><input type="text" name="quantite3"></td>
        <td>
    
            <select name="unite3" id="">
                <option value="kg">kg</option>
                <option value="G">G</option>
                <option value="L">L</option>
                <option value="ml">Ml</option>
                <option value="cl">Cl</option>
                <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name4"></td>
        <td><input type="text" name="prixing4"></td>
        <td><input type="text" name="quantite4"></td>
        <td>

            <select name="unite4" id="">
                <option value="kg">kg</option>
                <option value="G">G</option>
                <option value="L">L</option>
                <option value="ml">Ml</option>
                <option value="cl">Cl</option>
                <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name5"></td>
        <td><input type="text" name="prixing5"></td>
        <td><input type="text" name="quantite5"></td>
        <td>

            <select name="unite5" id="">
              <option value="kg">kg</option>
              <option value="G">G</option>
              <option value="L">L</option>
              <option value="ml">Ml</option>
              <option value="cl">Cl</option>
              <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name6"></td>
        <td><input type="text" name="prixing6"></td>
        <td><input type="text" name="quantite6"></td>
        <td>

            <select name="unite6" id="">
              <option value="kg">kg</option>
              <option value="G">G</option>
              <option value="L">L</option>
              <option value="ml">Ml</option>
              <option value="cl">Cl</option>
              <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name7"></td>
        <td><input type="text" name="prixing7"></td>
        <td><input type="text" name="quantite7"></td>
        <td>

            <select name="unite7" id="">
              <option value="kg">kg</option>
              <option value="G">G</option>
              <option value="L">L</option>
              <option value="ml">Ml</option>
              <option value="cl">Cl</option>
              <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name8"></td>
        <td><input type="text" name="prixing8"></td>
        <td><input type="text" name="quantite8"></td>
        <td>
                
            <select name="unite8" id="">
              <option value="kg">kg</option>
              <option value="G">G</option>
              <option value="L">L</option>
              <option value="ml">Ml</option>
              <option value="cl">Cl</option>
              <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name9"></td>
        <td><input type="text" name="prixing9"></td>
         <td><input type="text" name="quantite9"></td>
         <td>

            <select name="unite9" id="">
              <option value="kg">kg</option>
              <option value="G">G</option>
              <option value="L">L</option>
              <option value="ml">Ml</option>
              <option value="cl">Cl</option>
              <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    <tr>
        <td><input type="text" name="name10"></td>
        <td><input type="text" name="prixing10"></td>
        <td><input type="text" name="quantite10"></td>
        <td>
            
            <select name="unite10" id="">
              <option value="kg">kg</option>
              <option value="G">G</option>
              <option value="L">L</option>
              <option value="ml">Ml</option>
              <option value="cl">Cl</option>
              <option value="Piece">Piece</option>
            </select>
        </td>
    </tr>
    </table>

    <button>Ajouter ingrédient</button>
</form>
</body>
</html>
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Miral Kh
  • 33
  • 1
  • 6
  • 3
    **Warning!!!** Your code is open for [SQL injection](https://en.wikipedia.org/wiki/SQL_injection), please use [prepared statements](https://www.php.net/manual/en/pdo.prepared-statements.php) preferably with [PDO](https://www.php.net/manual/en/book.pdo.php) or [mysqli](https://www.php.net/manual/en/mysqli.prepare.php). – biesior Aug 15 '20 at 11:41
  • Show us your HTML form yet. – biesior Aug 15 '20 at 11:46
  • Let me understand you have table `ingredient` with columns like `name`, `prix`, `prixn`, `uniteing` and `date` and you want to create several records within one form? – biesior Aug 15 '20 at 11:55
  • yesss truee sir – Miral Kh Aug 15 '20 at 11:57
  • like i want to create many record with many input and insert it in a table that have many columns like you said name,prix,prixn,uniteing – Miral Kh Aug 15 '20 at 11:58
  • it's a local application sir and im a beginner so i understand the problem that i have many sql injection bug i will not upload it in some server yet ! – Miral Kh Aug 15 '20 at 12:00
  • OK, you're doing it wrong I'll give you a sample soon in mean time please remove the answer and put the form sample in the question. – biesior Aug 15 '20 at 12:00
  • https://stackoverflow.com/a/4882317/2943403 You shouldn't pass a date string from php -- just use `CURRENT_DATE` stackoverflow.com/q/28094069/2943403 You should be declaring a prepared statement and binding parameters one time, then executing the statement in a loop with each set of values. – mickmackusa Aug 15 '20 at 12:47
  • 1
    Good code indentation would help us read the code and more importantly it will help **you debug your code** [Take a quick look at a coding standard](https://www.php-fig.org/psr/psr-12/) for your own benefit. You may be asked to amend this code in a few weeks/months and you will thank me in the end. – RiggsFolly Aug 15 '20 at 13:11
  • When an ` – mickmackusa Aug 15 '20 at 13:12
  • Your markup is invalid because you have duplicated element `id`s. – mickmackusa Aug 15 '20 at 13:23
  • https://stackoverflow.com/q/26456219/2943403 – mickmackusa Aug 15 '20 at 13:36
  • @MiralKh have you abandoned this page? There is no indication that your question is resolved. – mickmackusa Sep 11 '20 at 22:03

3 Answers3

2

You shouldn't repeat your form fields as a list name0, name1 .. name99 instead you need to send them as an array like: data[0][name] .. data[99][name]

Also better generate your HTML with PHP for not violating DRY rule, you'll apreciate that when will need to edit the form with reperating fields in the future:

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="css/style.css">
    <meta charset="utf-8">
</head>
<body>
<form action="php/insert-multi-ing.php" method="POST">

    <table>
        <tr>
            <th>Nom Ingrédient</th>
            <th>Prix</th>
            <th>Prix Ingrédient</th>
            <th>Quantite Ingrédient</th>
            <th>Unite</th>
        </tr>
        <?php
        for ($i = 0; $i < 10; $i++) {
            echo "
                <tr>
                    <td><input type='text' name='data[{$i}][name]'></td>
                    <td><input type='text' name='data[{$i}][prix]'></td>
                    <td><input type='text' name='data[{$i}][prixn]'></td>
                    <td><input type='text' name='data[{$i}][quantite]'></td>
                    <td>
                        <select name='data[{$i}][unite]' id='unite_{$i}'>
                            <option>kg</option>
                            <option>G</option>
                            <option>L</option>
                            <option>Ml</option>
                            <option>Cl</option>
                            <option>Piece</option>
                        </select>
                    </td>
                </tr>
            ";
        }
        ?>
    </table>
    <button>Ajouter ingrédient</button>
</form>
</body>
</html>

Here's the sample for accessing it as a multidimensional array in PHP and inserting to DB with prepared statement. Keep in mind that I use PDO instead of mysqli here which I advice you to:

<?php
$data = $_POST['data'] ?? null;
if (!is_null($data)) {

    $pdo = new PDO("mysql:host=127.0.0.1;dbname=test;charset=utf8", "yourusername", "yourpassword");
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $pdo->prepare("
        INSERT 
        INTO ingredient (name, prix, prixn, unite, quantite, date) 
        VALUES (:name, :prix, :prixn, :unite, :quantite, NOW())
        ");

    $stmt->bindParam('name', $name);
    $stmt->bindParam('prix', $prix);
    $stmt->bindParam('prixn', $prixn);
    $stmt->bindParam('quantite', $quantite);
    $stmt->bindParam('unite', $unite);

    foreach ($data as $item) {
        
        // Adds some data validation to make sure you won't save million empty rows,
        // also add custom validation for other fields (if any)
                 
        $name = checkValue($item['name']);
        $prix = checkValue($item['prix']);
        $prixn = checkValue($item['prixn']);
        $quantite = floatval($item['quantite']);
        $unite = checkValue($item['unite']);

        if (!is_null($name) && !is_null($prix) && !is_null($prixn) && $quantite > 0) {
            $stmt->execute();
        }
    }
}
/**
 * check if the string value is not null and not empty
 *
 * @param $value
 *
 * @return string|null
 */
function checkValue($value)
{
    return (is_null($value) || trim($value) == '') ? null : $value;
}

Note your code is messy and it's quite possible that I used wrong column names or field names in form, just fix it. In general that works.

biesior
  • 55,576
  • 10
  • 125
  • 182
  • MYSQL is perfectly capable of generating DATE and DATETIME stamps without passing them in as php variables. – mickmackusa Aug 15 '20 at 12:51
  • 1
    @mickmackusa probably, however this is not the topic in this case.Id set NOW() as default val in DB. – biesior Aug 15 '20 at 12:52
  • Why not bind `$item['name']` etc. To avoid the declarations inside the loop? E.g. `$stmt->bindParam('name', $item['name']);` – mickmackusa Aug 15 '20 at 12:52
  • We must always give our very best advice -- even if it is not asked for. We give because we want to help people grow -- not because we want to farm unicorn points while exerting the least effort necessary. In pdo, I'd probably just drop the data inside the `execute()` calls. – mickmackusa Aug 15 '20 at 12:54
  • The null coalescing operator followed by the `is_null()` check is double handling. Just call `isset()` in this case. – mickmackusa Aug 15 '20 at 12:57
  • I agree, as a matter of best practice the `date` column of the db table should have a default value of the CURRENT_DATE so that the date column can be completely removed from INSERT queries. – mickmackusa Aug 15 '20 at 13:05
  • @mickmackusa You are right about `date` column's default value, however we still don't know what DB structure OP has, changed my sample to use NOW() function. Actually date is broad it should be rather separate columns for `created_at` and `updated_at` first with CURRENT_DATE and not set in INSERT stmt, second with NOW in UPDATE stmt. – biesior Aug 15 '20 at 13:08
  • @mickmackusa about _**Why not bind $item['name'] etc**_ that's the way the `bindParam()` is supposed to be used (in opposition to `bindValue()`) it ***references*** the variable so we can reassign its value later if inserting data in the loop before calling next `$stmt->execute();` which is desired in this case. Probably you know that, but for other to reference see [this answer](https://stackoverflow.com/a/1179927/1066240) – biesior Aug 15 '20 at 13:26
  • Although pdo will allow the omission of `bindParam()` if the parameters are fed to `execute()`, my point (before you added the sanitization steps) was that you could spare the extra `$name = $item['name'];` declarations inside the loop by replacing `$stmt->bindParam('name', $name);` with `$stmt->bindParam('name', $item['name']);`. Anyhow, now the argument is more or less moot. Also, `checkValue` is not "checking" it is sanitizing. `(is_null($value) || trim($value) == '')` is more succinctly written as `!trim($value)` but either way the loose comparison will change `0` to `null` -- not good. – mickmackusa Aug 16 '20 at 00:04
  • @mickmackusa adding with variables has two reasons in this case. First (deliberately) it's referencing the basic PDO docs, and there's no need to explain why I try to read $item keys to the OP. The second (deliberately, most important) after all these years I always when coding trying to _think forward_ for me that's rather obvious, that there will be a need for some data validation and/or additional logic. In a perfect world, I'd use data models + repositories with customized setters, however this far away from OP's expectations. – biesior Aug 17 '20 at 15:57
0

Your code is subject to SQL injection. It's better to use parameterized queries. They take care of quoting, fixing data that might include SQL injection, etc. They also execute faster when executing the same statement repeatedly.

Note: Code not tested, may require some syntax checking and other corrections

<?php

//  Create PDO connection
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);

//  Create list of base column names
$colList = array(
    'name',
    'prix',
    'prixn',
    'uniteing'
);
//  Create array to hold column values from $_POST
$val = Array(null,null,null,null);

//  Prepare SQL statement with place holders, be sure to explicitly list the table column names. Substitute the actual column names for those below.
$stmt = $dbh->prepare("INSERT INTO ingredient (`namex`,`prixx`,`prixnx`,`uniteingx`) VALUES (:namex,:prixx,:prixnx,:uniteingx)");

//  Bind each array value to a place holder
$stmt->bindParam(':namex',$val[1]);
$stmt->bindParam(':prixx',$val[2]);
$stmt->bindParam(':prinx',$val[3]);
$stmt->bindParam(':uniteingx',$val[4]);

//  Step through the column name suffix values from the form
for($i=0;$i<=10;$i++) {
    //  Special case for the first (0) value (i.e. no suffix)
    $suffix = $i > 0 ? $i : '';
    //  Load the 5 column values from the post variables into the $val array
    foreach($colList as $colNum, $colName) {
        $val[$colNum] = $_POST[$colName . $suffix];
    }
    //  Execute the SQL statement above with the current values in $val
    $stmt->execute();
}


?>
Sloan Thrasher
  • 4,953
  • 3
  • 22
  • 40
0

To begin, craft your html form so that it is fit for purpose and doesn't violate html document standards.

  • You should be generating the rows of input fields inside of a loop.

  • You should declare the name attributes of each field using array syntax so that row data is submitted in grouped subarrays -- this will make subsequent processes much easier. By simply trailing the field name with [], you can avoid cluttering your file with unnecessary php syntax.

  • You must not have duplicated id attributes in a single document. You could append a counter to the end of the id strings, but there is a high probability that you don't need the id declarations at all -- I'll omit them.

  • There is zero benefit in duplicating an <option>'s text as its value value. Simply omit that attribute declaration as well.

  • Use a whitelist of measurement units so that you don't need to write out each <option> tag over and over. This will improve the maintainability of your script.

  • For improved UX, use field attributes such as: title, placeholder, pattern, minlength, maxlength, required, etc. as well as potentially type="number" to guide the users about how to form valid entries. These simple touches will not only help to prevent user frustration, they will spare your application from making fruitless trips to the database and/or only storing partial submissions.

    <table>
        <tr>
            <th>Nom Ingrédient</th>
            <th>Prix Ingrédient</th>
            <th>Quantite Ingrédient</th>
            <th>Unite</th>
        </tr>
        <?php
        $numberOfRows = 10;
        $units = ['kg', 'G', 'L', 'ml', 'Cl', 'Piece'];
        for ($i = 0; $i < $numberOfRows; ++$i) {
            ?>
            <tr>
                <td><input type="text" name="name[]"></td>
                <td><input type="text" name="price[]"></td>
                <td><input type="text" name="quantity[]"></td>
                <td>
                    <select name="unit[]">
                        <option><?php echo implode('</option><option>', $units); ?></option>
                    </select>
                </td>
            </tr>
            <?php
        }
        ?>
    </table>
    

As for your database table setup, here are some tips:

  • Avoid vague column naming like date. Rename the column as insert_date or created_on or something similar so that the value is more informative to future readers of your scripts/project.
  • Modify the schema of your ingredients table to set the DEFAULT value of insert_date as CURRENT_DATE. In doing so, you will never need to write this column into your INSERT queries -- the database will use the current date automatically when you do not pass a value for that column.
  • If this table doesn't have an AUTOINCREMENTing id column, you should add one and make it the PRIMARY KEY. This is a very basic technique to improve future interactions with the table and will eliminate possible confusion when you find that someone has submitted a duplicate name into the table.

As for processing your submitted data, there are only a few simple steps to follow:

  1. Iterate the $_POST array and isolate each row of data to be inserted into the database.

  2. Once isolated, you need to validate and optionally sanitize each row BEFORE executing the query so that you never store "bad data" in your table.

  3. You are using mysqli and that is just fine -- you don't need to switch to pdo to write secure/stable code. 4 You will only need to generate a prepared statement once and bind variables to placeholders once. Only the (conditional) execution of the statement needs to be inside the loop. (some other examples: 1, 2, 3)

  4. I will recommend, however, that you switch from mysqli's procedural syntax to its object-oriented syntax. It is more concise and I find it simpler to read.

    // create a mysqli connection object e.g. $mysqli = new mysqli(...$credentials);
    $sql = "INSERT INTO ingredients (`id`, `name`, `price`, `quantity`, `unit`)
            VALUES (NULL, ?, ?, ?, ?)"; 
    $stmt = $mysqli->prepare($sql);
    $stmt->bind_param('sdds', $name, $price, $quantity, $unit);  // Assumes price and quantity are float values
    
    $failures = [];
    $affectedRows = 0;
    $units = ['kg', 'G', 'L', 'ml', 'Cl', 'Piece'];
    foreach ($_POST['name'] as $index => $name) {
        // adjust the validation/sanitization processes as you wish
        $name = trim($name);
        $price = trim($_POST['price'][$index]);
        $quantity = trim($_POST['quantity'][$index]);
        $unit = trim($_POST['unit'][$index]);
        $rowNo = $index + 1;
        if (!strlen($name) || !strlen($price) || !strlen($quantity) || !in_array($unit, $units)) {
            $failures[] = "Missing/Invalid value on row $rowNo";
        } elseif (!$stmt->execute());
            $failures[] = "A syntax error has occurred";  // check your error logs
        } else {
            ++$affectedRows;
        }
    }
    echo "Affected Rows: $affectedRows";
    if ($failures) {
        echo "<ul><li>" , implode('</li><li>', $failures) , "</li></ul>";
    }
    

Some overall advice:

  1. avoid mixing your French and your English. If you are going to use French variable names, then use ALL French variables. That said, I have read advice from native English speakers and English-as-a-Second-Language developers who state that you should always use ALL English in your code -- this is a a debate, I will not weigh in on this right now.
  2. When to use htmlspecialchars() function? You will notice that at no point did I call this function in my answer. This is because at no point are we printing any of the user's input to screen. Validate? Yes. Sanitize? Sure. HTML Encode? Nope; not here, not now.
  3. If these rows of ingredients are meant to relate to specific recipe table rows, then you will need to establish a FOREIGN KEY relationship. The recipes table will need an id column and the ingredients table will need a column like recipe_id which stores that respective recipe id. Assuming your html form will already know which recipe is being referred to, you should include a <input type="hidden" name="recipe" value="<?php echo $recipeId; ?>"> field on the line under your <form> tag. Then when saving data, you must save the $_POST['recipe'] value with each ingredients row. Then you are making better use a of "relational database".
mickmackusa
  • 43,625
  • 12
  • 83
  • 136