I have a form in html with various fields, in particular a select and textarea. by pressing the button I create other n select and textarea (n given by keyboard).
I then have a php file that inserts the data into the database. everything works but not correctly inserted the data of the textarea (which in the file called $quantita) that does not take all the order (for sesmpio if I write 1, 2, 5 inserts 1,2,5) but only a value (if I write just takes 1,2,5 1,1,1).
html
<?php
$pro = 'sito';
$dd = mysqli_connect('localhost', 'root', '', $pro);
$re = mysqli_query ($dd,"SELECT Codice, Nome FROM prodotti");
echo"<div class='box'>";
echo"Prodotto";
echo"<select class='inse' name='po[]'>";
while($row=mysqli_fetch_array($re)){
echo"<option value=".$row['Codice'].">".$row['Nome']."</option>";
}
echo"</select>";
echo"<br>";
echo"Quantità <textarea name='qua[]' rows='1' cols='4'></textarea></div><br>";
?>
</div>
<br><button type="submit" id="ok">OK!</button><br>
</form>
php
<?php
$nordine = $_POST['nor'];
$datao = $_POST['dao'];
$datac = $_POST['dac'];
$quantita = $_POST['qua'];
$prodotto = $_POST['po'];
$data = 'sito';
$db = mysqli_connect('localhost', 'root', '', $data);
$result = mysqli_multi_query ($db, "INSERT INTO ordini
(Nordine,DataO,DataC)
VALUES('$nordine','$datao','$datac')");
if ($prodotto && $quantita){
foreach ($prodotto as $result1){
foreach ($quantita as $result2){
mysqli_query ($db, "INSERT INTO ordpro
(Prodotto, Ordini, Quantita)
VALUES('". mysqli_real_escape_string($db,$result1)."','$nordine','". mysqli_real_escape_string($db,$result2)."')");
}
}
}
echo"<p>Hai inserito un nuovo record <a href='ordini.php'> torna alla home </a></p>";
?>
From your HTML I think that po[0] should go with qua[0] and po[1] should go with qua[1] etc etc
So your 2 foreach loops are doing the wrong thing and storing all the quas with each po
You should also be using prepared and paramterised statement when using any data provided by the user in POST or GET.
An additional benefit of using prepared statements for multiple updates is that you can prepare it once and execute it many times, thus reducing the round trips to the database. Also the query needs to be compiled and optimized by MYSQL only once, making it almost like using a Stored Procedure.
NOTE: This also means you no longer need to use mysqli_real_escape_string() on the users data.
So the loops should be amended like this
$sql = "INSERT INTO ordpro (Prodotto, Ordini, Quantita) VALUES (?,?,?)";
$stmt = mysqli_prepare($db, $sql);
if ($prodotto && $quantita){
foreach ($prodotto as $idx => $prod){
$stmt->bind_param('sss', $prod, $nordine, $quantita[$idx]);
$stmt->execute();
}
}
Note2 I have used sss (string) as the data types for all 3 variables. You may need to check that this is correct and amend accordingly. The id fields may need to be changed to i where appropriate
Related
For days I've been trying the following: I have a HTML form. After receiving the data (MENGE / PRODUKT / LIEFERANT) I want to insert the data into the table "bestellung". For this purpose, I need two different data points from two different tables: the Waren_ID from the WARE table and the kunde_lieferant_ID from the kunde_lieferant table.
Every time I try this, I get a new error in whatever form (syntax, ...). I've read dozens of Stack Overflow posts, but none helped me out. It would be great if someone could give me a hint :-)
<?php
$server="localhost";
$username="xy";
$passwort="xy";
$database="xy";
$conn=mysqli_connect($server, $username, $passwort, $database)
or die ("Fehler im System");
if (!empty($_POST["Lieferant"]) AND !empty ($_POST["Produkt"]) AND !empty ($_POST["Menge"]))
{
$Menge = $_POST ["Menge"];
$Produkt = $_POST["Produkt"];
$Lieferant = $_POST ["Lieferant"];
$sql="SELECT Waren_ID FROM ware WHERE Name='$Produkt'";
$speichern = mysqli_query($conn, $sql);
$rs = mysqli_fetch_array($speichern);
$Waren_ID=$rs['Waren_ID'];
$abfrage="SELECT kunde_lieferant_ID FROM kunde_lieferant WHERE Name='$Lieferant'";
$result = mysqli_query($conn, $abfrage);
$ts = mysqli_fetch_array($result);
$kunde_lieferant_ID=$ts['kunde_lieferant_ID'];
$final="INSERT INTO bestellung (Menge, Waren_ID, kunde_lieferant_ID) values ($Menge, $Waren_ID, $kunde_lieferant_ID)";
$ende=mysqli_query($conn, $final)
or die ("Fehlgeschlagen: SQL-Error:" . mysqli_error($conn));
}
mysqli_close($conn);
?>
Add MYSQLI_ASSOC as a second argument to mysqli_fetch_array() to use the key name instead of the integer index number:
$rs = mysqli_fetch_array($speichern); becomes $rs = mysqli_fetch_array($speichern, MYSQLI_ASSOC);
and
$ts = mysqli_fetch_array($result); becomes $ts = mysqli_fetch_array($result, MYSQLI_ASSOC);
You may also use $rs = mysqli_fetch_assoc($speichern); and $rs = mysqli_fetch_assoc($speichern); to access the associative array by key name instead of index.
One potential problem in your insert statement is that you are not single-quoting the values that your are passing : to MySQL, this means that they are all numeric (but is « Menge » numeric for example ?).
To avoid this and also prevent your code from SQL injection, you probably should use parameterized queries.
By looking more globally at your code, I think that you should be able to achieve what you want in a single INSERT ...SELECT statement, like :
INSERT INTO bestellung
SELECT
:menge,
w.Waren_ID,
k.kunde_lieferant_ID
FROM
ware w
INNER JOIN kunde_lieferant k
ON k.Name = :lieferant
WHERE w.Name = :produkt
My question is pretty straight-forward, and I assume that people need to do this pretty often; yet, after hours of searching online, nothing especially enlightening has come up. I am aware of a thread on here about doing the same thing using PDO, but I want to stick to mysqli to be consistent across my whole site.
So, I need to move one or several rows from one database to another (and NOT from one table to another within a single database).
The code I have so far is sure to get some laughs, as this task proved to be considerably beyond my ability. Anyway, here goes:
To begin with, I have two mysqli_connect... not sure if that is encouraged, although it has not caused me problems so far.
$connect_MAIN = mysqli_connect($servername_MAIN, $username_MAIN, $password_MAIN, $dbname_MAIN);
$connect_TEMP = mysqli_connect($servername_TEMP, $username_TEMP, $password_TEMP, $dbname_TEMP);
Here is the meat in the sandwich in terms of code:
///Prepare this in advance because the 'IN' values are taken from a $_GET
$sql_select = "SELECT * FROM Concert WHERE id IN (1, 2, 3, 4)";
///Connect to source DB
$result = $connect_TEMP->query($sql_select);
if ($result->num_rows != 0) {
///Connect to destination DB
$stmt = $connect_MAIN->prepare('INSERT INTO Concert (venue_id, date, ensemble_id, info, title, repertoire, time) VALUES (?, ?, ?, ?, ?, ?, ?)');
$venue_id = $date = $ensemble_id = $info = $title = $repertoire = $time = null;
$stmt->bind_param("isissss", $venue_id, $date, $ensemble_id, $info, $title, $repertoire, $time);
while($row = $result->fetch_assoc()) {
$venue_id = $row["venue_id"];
$date = $row["date"];
$ensemble_id = $row["ensemble_id"];
$info = $row["info"];
$title = $row["title"];
$repertoire = $row["repertoire"];
$time = $row["time"];
if ($stmt->execute() === TRUE) {
if ($show_once == 1) {
echo "Info successfully submitted.";
$show_once = 0;
}
} else {
echo "Hmm, something went wrong..." . $connect_MAIN->error;
}
}
}
$stmt->close();
mysqli_close($connect_TEMP);
}
So, I know that this is a bit of a jumble... as I said, I am not sure if it is possible to connect to DB2 in the middle of a while loop returning values from DB1. Feel free to mock, but only if you have something useful to suggest!
Use a parametrized query instead of concatenating strings.
///Prepare this in advance because the 'IN' values are taken from a $_GET
$sql_select = "SELECT * FROM Concert WHERE id IN (1, 2, 3, 4)";
///Connect to source DB
$result = $connect_TEMP->query($sql_select);
if ($result->num_rows != 0) {
///Connect to destination DB
$stmt = $connect_MAIN->prepare('INSERT INTO Concert (venue, date, info, time) VALUES (?, ?, ?, ?)');
$venue = $date = $info = $time = null;
$stmt->bind_param("ssss", $venue, $date, $info, $time);
while($row = $result->fetch_assoc()) {
$venue = $row["venue"];
$date = $row["date"];
$info = $row["info"];
$time = $row["time"];
if ($stmt->execute()) {
///This is just to stop message from appearing multiple times.
if ($show_once == 1) {
echo "Info successfully submitted.";
$show_once = 0;
}
} else {
echo "Hmm, something went wrong..." . $stmt->error;
}
}
$stmt->close();
mysqli_close($connect_TEMP);
}
Yes, you may establish a second DB connection at any point in your script. There's nothing preventing it nor there's a reason to discourage it. It's far more common than you'd think (for different reasons). However, considering the overhead that actually connecting to the database carries, I would advice you to not establish a connection on each iteration (this is the best practice, performance-wise)
What I would do:
First, connect to the source database, get the data you need
Not much to say here, you already did and it looks OK. Check, as you did, that there's at least one result before moving on. If the resultset is empty, don't go any further (exit)
If there was at least one row in the resultset, establish a connection to the destination database
Do this before starting to loop to avoid the performance penalty of establishing multiple connections. If you're looking at hundreds/thousands or more rows, you'll really notice the difference. Once the connection is established, move on
Loop through the source data and prepare the insert statements
You have a choice here. Either a) loop through the whole resultset and prepare one single insert with multiple rows which you'll insert all at once at the end of the loop or b) create a single insert (single row) on each iteration, run the insert and then move on to the next iteration.
There's reasons for and against both strategies. Choose the one that suits you better.
In algorythmical terms, your code is pretty much ready (just connect to the destination DB once before you start looping). You may benefit from using a parameterized query with bindings instead of writing the full insert string, but other than that you're pretty much there.
If you are running your own MySql server, you may do this in a simpler way using the Federated engine.
The federated table behaves like a normal table, but it stores the data in a remote database. With this engine you can do someting like this:
INSERT INTO remoteTable (values) SELECT * FROM localTable
2 Questions about saving data from multiple checkbox (I have few of them in my form) in a database with PDO (PHP). I just show the relevant parts of the code to make it more simple for everyone.
A) The code I wrote works (still saving all data correctly) but it gives me still a failure message, which you can see below. Why, or what can I do better?
B) It saves the checked checkboxes as an array in the database. Later on I want to change data by getting the data from the database back into my original form - will it make problems, if its saved like an array? If yes, what would you recommend to do then better.
Warning: implode ( ) : Invalid arguments passed on line ... for
$p2 = implode(',',$product_2);
$p3 = implode(',',$product_3);
$p1 = implode(',',$product_1); which I defined first seems to be fine
<?php
if(isset($_POST['send']))
{
require("php/tconnect.php");
$id = $_POST['id'];
$name = $_POST['name'];
$date = $_POST['date'];
$p1 = implode(',',$product_1);
$p2 = implode(',',$product_2);
$p3 = implode(',',$product_3);
$sql = "INSERT INTO database (id, name, date) VALUES (:id, :name, :date, '$p1', '$p2', '$p3')";
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':id', $id);
$stmt->bindValue(':name', $name);
$stmt->bindValue(':date', $date);
$stmt->execute();
echo "Datas saved";
}
?>
HTML
<input type="checkbox" name="product_1[]" value="apple" id="product_1_apple">
Apple
</label>
<label class="checkbox-inline">
<input type="checkbox" name="product_1[]" value="Banana" id="product_1_banana">
Banana
</label>
and the next tables looks similar
<input type="checkbox" name="product_2[]" value="water" id="product_2_water">
Water
</label>
<label class="checkbox-inline" >
<input type="checkbox" name="product_2[]" value="juice" id="product_2_juice">
Juice
</label>
Since $product_1, $product_2 and $product_3 seems to be related with the input arrays from the HTML I suppose that you have in another part of the code something like this:
$product_1 = $_POST['product_1'];
$product_2 = $_POST['product_2'];
$product_3 = $_POST['product_3'];
Now, the problem is that those variables are related to an array of checkboxes, but when no checkbox is selected in the page for a group, instead of getting an empty array for that group the array is not added to $_POST (you can see it using var_dump($_POST)).
I suspect that in your tests you were only marking checkboxes for product_1, so you get an array for that product but no for the other ones. To prevent the error you can fill each of the products variables using something like this:
if(isset($_POST['product_1'])) // if the array is defined in $_POST
$product_1 = $_POST['product_1']; // fill with the array from the form
else $product_1 = array(); // fill with empty array, you get the empty string with implode()
// repeat for product_2 and product_3
Also, you are mixing prepared statements, which are good, with inserting the values directly in the query string, which is bad because it can lead to SQL Injection, you should use bindValue() for all the values of the table:
$sql = "INSERT INTO database (id, name, date) VALUES (:id, :name, :date, :p1, :p2, :p3)";
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':id', $id);
$stmt->bindValue(':name', $name);
$stmt->bindValue(':date', $date);
$stmt->bindValue(':p1', $p1);
$stmt->bindValue(':p2', $p2);
$stmt->bindValue(':p3', $p3);
I have an input form with two values as a key, constructed this way:
<input name="verificarPago['.$x['pagoID'].'-'.$x['userID'].']" type="text">
So, the HTML would look like, for example, like this:
<input name="verificarPago[4-10]" type="text">
Besides that I have the value that the user can type, for example "Juan".
The inputs are created programmatically, and I want to save them each three values (in the example: 4, 10, Juan) into a database.
So, when the user submits the form, I thought on using foreach in order to access the elements in that array, but my problem is: How may I explode the keys to access the two values separately?
I've tried this (I'm not taking into account security now, I'm trying to prove the concept):
$verificar = $_POST['verificarPago'];
foreach ($verificar as $pago => $curso) {
//I'm pretty much stuck here.
$verificar= array_flip(explode("-", $verificar));
//I want to insert the three items into the database
$verificarPago = "INSERT pagosVerificados SET userID = '$usuario', pagoID = '$pago', cursoID = '$curso'";
$cargarPago = mysqli_query($conectar, $verificarPago);
}
I've tried adding to the form another input type, so the values wouldn't be together, but that way I should do a foreach inside a foreach and that renders duplicated results (and with errors as well).
Without addressing any architectural issues, adding error-checking, or addressing security problems, here's how to do what you're asking for
$verificar = $_POST['verificarPago'];
foreach ($verificar as $ids => $text) {
list($pagoID, $cursoID) = explode("-", $ids);
$sql = "INSERT INTO pagosVerificados (userID, pagoID, cursoID, someVarcharField)
VALUES ($usuario, $pagoID, $cursoID, '$text');";
$cargarPago = mysqli_query($conectar, $sql);
}
This is a tad inefficient though - executing an insert for every iteration. Since mysql supports bulk inserts, you can modify the generation of the query to leverage that.
$verificar = $_POST['verificarPago'];
$rows = array();
foreach ($verificar as $ids => $text) {
list($pagoID, $cursoID) = explode("-", $ids);
$rows[] = "($usuario, $pagoID, $cursoID, '$text')";
}
$sql = "INSERT INTO pagosVerificados (userID, pagoID, cursoID, someVarcharField) VALUES "
. implode(',', $rows)
. ";";
$cargarPago = mysqli_query($conectar, $sql);
Now it's just one round-trip to the database
This is a bizarre way of passing values over POST. But, to expand on Peter's answer and address the glaring security issues, you can also use prepared statements. They're designed to be prepared once and then executed multiple times so are perfect for the job.
$verificar = $_POST['verificarPago'];
$sql = "INSERT INTO pagosVerificados (userID, pagoID, cursoID, someVarcharField) VALUES (?, ?, ?, ?)"
$stmt = $conectar->prepare($sql);
foreach ($verificar as $ids => $text) {
list($pagoID, $cursoID) = explode("-", $ids);
$stmt->bindParam("iiis", $usuario, $pagoID, $cursoID, $text);
$stmt->execute();
}
It's been years since I've worked with mysqli, but this should do the trick. You'll want to include some error checking in there as well.
This question already has answers here:
How to include a PHP variable inside a MySQL statement
(5 answers)
Closed last year.
I am trying to insert data from modal after user clicks submit button. But it is not working, I have 2 files index to display modal and PHP file to run connect MySQL and insert data into it. I don't think it recognizes submit action. I also have question how do I insert primary key id into database or does it adds automatically.
HTML submit code:
<button type="submit" action="add.php"class="btn">Finish!</button>
PHP code:
<?php
include 'db.php';
$cName = $_POST['form-name'];
$ser = $_POST['form-s-name'];
$link = $_POST['form-t'];
$info = $_POST['form-des'];
$sql = "INSERT INTO crewlist(id, name,sname,linkname,description)
VALUES ('','".$cName."','".$ser."','".$link."','".$info."')";
mysqli_query($conn,$sql);
if(mysqli_affected_rows($conn) > 0){
echo "<p>Added</p>";
The textbook way to do this is to use prepared statements:
$stmt = mysqli_prepare($conn,
"INSERT INTO crewlist(name,sname,linkname,description) VALUES (?,?,?,?)"
);
mysqli_stmt_bind_param($stmt, 'ssss',
$_POST['form-name'],
$_POST['form-s-name'],
$_POST['form-t'],
$_POST['form-des']
);
$result = mysqli_stmt_execute($stmt);
If you use prepared statements correctly you're guaranteed that your values are inserted with the proper escaping. Here I've used s for string, but there are other types listed in the documentation.
You'll want to enable exceptions for errors in case you make a mistake.
If you're doing a lot of database work I'd strongly encourage you to use an ORM like Doctrine or Propel as they make interfacing with your records a lot more pleasant.
you are not using variables in sql query you should use it like this
$sql = "INSERT INTO crewlist(id, name,sname,linkname,description)
VALUES ('','{$cName}','{$ser}','{$link}','{$info}')";
Insert query not matching your column use this it will work:
$sql = "INSERT INTO crewlist(id, name,sname,linkname,description)
VALUES ('',cName,ser,link,info)";
this will insert cName,ser,link,info in table if you want the data use:
'".$cname."'