INSERT array multidimensional into database - php

i'm newbie in PHP, and sorry for my English.
I had read all the questions about this topic in this forum, but i still cant find the solution for my PHP.
I have 2 session here, first to save data person, and second to save cart. Here my session structure
<?php
$id_pers person = $_SESSION['person'] ; //its contain just id
//for second $_SESSION['cart'] structure when i print_r is like this
Array (
[0] => Array (
[item_id] => 4
[item_name] => Notebook
[item_qty] => 1
[price] => 750
)
[1] => Array (
[item_id] => 5
[item_name] => Keyboard
[item_qty] => 1
[price] => 70
)
[2] => Array (
[item_id] => 6
[item_name] => Mouse
[item_qty] => 1
[price] => 50
)
)
?>
The problem is when i save array into database its just one array is saved, the other array cant save into database. Here my insert function what i wrote from watching video tutorial:
<?php
function save($array, $connect){
if(is_array($array)){
$id_person = $_SESSION['person'];
foreach($array as $row => $value) {
$item_id = mysqli_real_escape_string($connect, $value['item_id'];
$item_qty = mysqli_real_escape_string($connect, $value['item_qty'];
$sql = "INSERT INTO tbl_order(id_person,item_id,qty) VALUES ('".$id_person."','".$item_id."','".$item_qty."')";
mysqli_query ($connect, $sql);
}
}
}
save($_SESSION['cart'], $ connect);
?>
Please tell me where is my mistake on my script for inserting data array into table. Thanks :)

Syntax error
$item_id = mysqli_real_escape_string($connect, $value['item_id'];
$item_qty = mysqli_real_escape_string($connect, $value['item_qty];
Missing the ' and a ) 2x
$item_id = mysqli_real_escape_string($connect, $value['item_id']);
$item_qty = mysqli_real_escape_string($connect, $value['item_qty']);
And change this (this is ok, just not the best way to do it):
function save($array, $connect){
if(is_array($array)){
to
function save(array $array, $connect){
Now if you pass in something other then an array PHP with issue an error. It's called type hinting and it lets us get rid of that check as we are guaranteed that only arrays can be passed as that argument. With manual checking your code would just fail silently and you wouldn't know why.
I would probably toss a if(!session_id()) session_start(); in there to be safe. If there is no session ID, then create a session. You cannot store data to the session unless it's started.
So like this:
<?php
function save(array $array, $connect){
if(!session_id()) session_start();
//don't trust this who knows where it came from, QQ'n not me.
$id_person = mysqli_real_escape_string($connect, $_SESSION['person']);
foreach($array as $row => $value) {
$item_id = mysqli_real_escape_string($connect, $value['item_id']);
$item_qty = mysqli_real_escape_string($connect, $value['item_qty']);
$sql = "INSERT INTO tbl_order(id_person,item_id,qty) VALUES ('".$id_person."','".$item_id."','".$item_qty."')";
mysqli_query ($connect, $sql);
}
}
save($_SESSION['cart'], $ connect);
?>
-NOTE- It's also preferred to prepare queries instead of escaping them.
Cheers.

Assuming those numbers are integers and not strings your code should look more like:
<?php
session_start(); // before headers are sent
function saveCart($connect){
if(!(isset($_SESSION['person'], $_SESSION['cart']) && is_int($_SESSION['person']) && is_array($_SESSION['cart']))){ // remember $_SESSION is a super global
return false;
}
$id = $_SESSION['person']; $cartArray = $_SESSION['cart'];
foreach($cartArray as $a){
$stmt = $connect->prepare('INSERT INTO tbl_order (id_person, item_id, qty) VALUES (?, ?, ?)');
$stmt->bind_param('iii', $id, $a['item_id'], $a['item_qty']); $stmt->execute();
}
return true;
}
if(saveCart($connect) === true){
echo 'Cart Saved';
}
else{
echo 'Cart was not Saved';
}
?>
Prepared statements are the way to go.

Related

Looping through Array Values with $SQL output

I have a list of serialized data that I unserialize and store into an array.
$employee_data = unserialize($entry, '63');
Which results in an expected output:
Array ( [0] =>
Array ( [First] => Joe
[Last] => Test
[Birth Date] => 01/01/2011
)
[1] =>
Array ( [First] => Mike
[Last] => Miller
[Birth Date] => 01/01/1980
)
)
Ive been trying, unsuccessfully, to insert these records into a table in MySQL using foreach() or something like:
$employee_array = array();
$k = 1;
for($n=0; $n<count($employee_data); $n++ ){
$employee_array['employee_first_name'.$k] = $employee_data[$n]['First'];
$employee_array['employee_last_name'.$k] = $employee_data[$n]['Last'];
$employee_array['employee_birthdate'.$k] = $employee_data[$n]['Birth Date'];
$SQL = "INSERT INTO employee_test (
employee_first_name,
employee_last_name,
employee_birthdate
)
VALUES (
'$employee_first_name.$k',
'$employee_last_name.$k',
'$employee_birthdate.$k'
)"
$k++;
};
Each employee in the array needs to be entered into a new row in the table, however the number of employees will vary from 1 to 10+
We've tried
foreach($employee_array as $key => $value)
with the same results.
The actual results we're hoping for is the SQL Statement to be:
insert into employee_test(
employee_first_name,
employee_last_name,
employee_birthdate)
VALUES(
'Joe',
'Test',
'01/01/2011');
insert into employee_test(
employee_first_name,
employee_last_name,
employee_birthdate)
VALUES(
'Mike',
'Miller',
'01/01/1980');
Keep in mind that your sql statement is not escaped. For example, a name with an apostrophe like "0'neil" will break your sql. I would also familiarise yourself with php's foreach: https://www.php.net/manual/en/control-structures.foreach.php.
I'm not sure exactly what you're trying to accomplish by adding the index to the name and sql value, but I would do something like this:
foreach($employee_data as $key => $value){
// $employee_array is not necessary
$employee_array[$key]['employee_first_name'] = $value['First'];
$employee_array[$key]['employee_last_name'] = $value['Last'];
$employee_array[$key]['employee_birthdate'] = $value['Birth Date'];
// Needs escaping
$SQL = "INSERT INTO employee_test (
employee_first_name,
employee_last_name,
employee_birthdate
)
VALUES (
'{$value['First']}',
'{$value['Last']}',
'{$value['Birth Date']}'
)";
echo $SQL;
};
The first implementation wont work as your calling a variable rather than the key in your array.
'$employee_first_name.$k',
Should be
$employee_array['employee_first_name'.$k]
You are also creating the SQL statement every iteration of the for loop, so in this implementation only the last employee will save.
Also I don't see the reasoning in doing it that way anyway you may as well just use the employee_data array and the $k variable can also be made redundant.
$SQL = "";
for($n=0; $n<count($employee_data); $n++ ){
$SQL .= "INSERT INTO employee_test (
employee_first_name,
employee_last_name,
employee_birthdate
) VALUES (";
$SQL .= "'".$employee_data[$n]['First']."',";
$SQL .= "'".$employee_data[$n]['Last']."',";
$SQL .= "'".$employee_data[$n]['Birth Date']."'";
$SQL .= ");";
};
Ive not tested but it should give you an idea.
You will also have issues with the date formatted that way, Your database would likely require the date in yyyy/mm/dd format
Finally I would not recommend inserting values like this, look at the PDO library for placeholders.
I think I understand what you're trying to do here. You are using the = operator, effectively setting $SQL to a new value each time your loop iterates. If you adapt your code, you will be able to append to $SQL variable each time.
//I used this array for testing. Comment this out
$employee_data = array(
0 => array(
"first" => "test",
"last" => "tester",
"birth date" => "01/01/1970"
),
1 => array(
"first" => "bob",
"last" => "david",
"birth date" => "02/02/1972"
),
);
//Start SQL as a blank string
$SQL = "";
//Do your iteration
foreach( $employee_data as $key=>$value ){
$first = $value['first'];
$last = $value['last'];
$birthDate = $value['birth date'];
//append this query to the $SQL variable. Note I use `.=` instead of `=`
$SQL .= "INSERT INTO employee_test(
`employee_first_name`,
`employee_last_name`,
`employee_birthdate`)
VALUES(
'$first',
'$last',
'$birthDate'
);";
}
//output the query
echo $SQL;
There are much easier ways of doing this though. Look into prepared statements :)

How to add <hr> tags between unique rows from query resultset?

I'm trying to add an <hr> tag between lines when a new name is encountered.
$conn = new mysqli("localhost", "root", "", "test");
$rs = $conn->query("SELECT * FROM usuarios");
$info = [];
$i = 0;
while($rows = $rs->fetch_array()) {
$info[$i]["pass"] = $rows["pass"];
$info[$i]["name"] = $rows["name_real"];
$i++;
}
// I want to print a line just after the last duplicated value
for($i = 0; $i < count($info) - 1; $i++) {
if($info[$i]["name"] !== $info[$i +1]["name"] && // some duplicate condition) {
$info[$i]["line"] = "<hr>";
};
}
This is the structure of my info array build from the resultset.
Array
(
[0] => Array
(
[pass] => 12
[name] => Martin
)
[1] => Array
(
[pass] => 20
[name] => Martin
)
[2] => Array
(
[pass] => 2
[name] => Martin
)
[3] => Array
(
[pass] => 2
[name] => Alberto
)
)
My desired result would be something like:
<p>Martin<p>
<p>Martin<p>
<p>Martin<p>
<hr>
<p>Alberto<p>
If you don't care what the duplicate names are or how many duplicates exist, and you just want to see whether or not there are any, it looks like it could be simpler code than some of the possible duplicate answers.
Get the names
$names = array_column($array, 'name');
Then check if the full list of names is equal to the unique list.
$has_duplicates = $names != array_unique($names);
Disclaimer: This answer looks odd now. It was provided for Revision 1 of the question. I seem to have misunderstood the question somewhat, and then Revision 2 transformed it to the extent that this answer no longer applies at all. Still, I think it's a useful way to do the thing that it seemed was trying to be done at first.
This solution would be handy:
$result = array();
$names = array_count_values(array_column($source, 'name'));
foreach($names as $key=>$val) {
$result[$key] = ($val == 1 ? false : true);
}
This can be achieved with just one loop. First, use your mysqli query to order the resultset by name_real. (If you are only going to use name_real, you can change the SELECT clause to reflect this. I have shown this in the commented query.) Then write a condition that checks for a new/unique name_real -- if so, echo <hr>.
Code: (Demo)
//$rs = $conn->query("SELECT `name_real` FROM usuarios ORDER BY `name_real`;");
$rs=[
['pass'=>2,'name_real'=>'Alberto'],
['pass'=>12,'name_real'=>'Martin'],
['pass'=>20,'name_real'=>'Martin'],
['pass'=>2,'name_real'=>'Martin']
];
$prev=NULL;
//while($rows = $rs->fetch_array()) {
foreach($rs as $rows){
if($prev && $rows['name_real']!=$prev){ // if not first iteration, and new name_real
echo "<hr>";
}
echo "<p>{$rows['name_real']}</p>";
$prev=$rows['name_real']; // preserve this value for next iteration's check
}
Output:
<p>Alberto</p>
<hr>
<p>Martin</p>
<p>Martin</p>
<p>Martin</p>

Insert result from DOMXpath into MySQL

Im using this DOMXpath query to retrieve some columns from another page.
$html = file_get_contents("http://localhost:8888/stockPrices.php");
libxml_use_internal_errors(true);
$doc = new \DOMDocument();
if($doc->loadHTML($html))
{
$result = new \DOMDocument();
$result->formatOutput = true;
$table = $result->appendChild($result->createElement("table"));
$thead = $table->appendChild($result->createElement("thead"));
$tbody = $table->appendChild($result->createElement("tbody"));
$table->setAttribute('class', 'table table-hover');
$xpath = new \DOMXPath($doc);
$newRow = $thead->appendChild($result->createElement("tr"));
foreach($xpath->query("//table[#id='kurstabell']/thead/tr/th[position()=2 or position()=3 or position()=8 or position()=9 or position()=10]") as $header)
{
$newRow->appendChild($result->createElement("th", trim($header->nodeValue)));
}
foreach($xpath->query("//table[#id='kurstabell']/tbody/tr") as $row)
{
$newRow = $tbody->appendChild($result->createElement("tr"));
foreach($xpath->query("./td[position()=2 or position()=3 or position()=8 or position()=9 or position()=10]", $row) as $cell)
{
$newRow->appendChild($result->createElement("td", trim(htmlentities($cell->nodeValue))));
}
}
echo $result->saveXML($result->documentElement);
}
This generates four columns, aktier, senaste, högst, lägst and omsatt. But i dont know how to insert this to a MySQL table. Im thinking to first generate a array of the result, like:
Array
(
[1] => stdClass Object
(
[aktie] => AAK AB
[senaste] => 634,50
[högst] => 638,50
[lägst] => 622,50
[omsatt] => 32 094 048
)
[2] => stdClass Object
(
[aktie] => ABB Ltd
[senaste] => 162,80
[högst] => 163,30
[lägst] => 161,90
[omsatt] => 167 481 268
)
(you get the hang of it..)
)
According to this image:
And then loop the array into the table. Something like this?
$sql = "INSERT INTO stock_list (`aktie`, `senaste`, `högst`, `lägst`, `omsatt`, `timestamp`) VALUES
(:aktie, :senaste, :högst, :lägst, :omsatt)";
$query = $database->prepare($sql);
foreach($data as $stock){
$query->execute(array(':aktie' => $stock->stock,
':senaste' => $stock->prevclose,
':högst' => $stock->high,
':lägst' => $stock->low,
':omsatt' => $stock->volume
));
}
My question:
How do i populate the array with data?
How do i loop the result in a mysql query?
Don't know if this is a work around. But it is currently doing what I'm asking for.
// build query...
$sql = "INSERT INTO stocks";
// columns to insert into...
$sql .="(`name`, `closing`, `high`, `low`, `turn`, `timestamp`)";
// implode values of $array...
// notice array_chunk, this functions splits a big array into multi.
$str = NULL;
foreach (array_chunk($a, 5) as $row) {
$str .= '("'. implode('","',$row).'",NOW()),';
}
// Remove last ',' (comma) from string
// We added commas in the previous step
$str = rtrim($str,',');
$sql .= 'VALUES '. $str ;
// execute query...
$app = new Connection();
$query = $app->getConnection()->prepare($sql);
$query->execute();
if ($query->rowCount() <= 0) {
echo "Something went wrong.";
return false;
}
return true;
My guess is that what you really want is something along the lines of:
$query = 'INSERT INTO stock_list
(`aktie`, `senaste`, `högst`, `lägst`, `omsatt`, `timestamp`)
VALUES
(:aktie, :senaste, :högst, :lägst, :omsatt, NOW())';
$stmt = $app->getConnection()->prepare($query);
foreach ($data as $stock) {
$stmt->execute(
[
':aktie' => $stock->aktie,
':senaste' => $stock->senaste,
':högst' => $stock->{'högst'},
':lägst' => $stock->{'lägst'},
':omsatt' => $stock->omsatt,
]
);
$stmt->closeCursor();//might be required depending on DB driver, not for MySQL, though
}
Note that I call NOW() in the query string, and I don't bind that SQL function call to the parameters I execute the prepared statement with. All in all though, a timestamp field is best set by the DB itself (with a DEFAULT CURRENT_TIMESTAMP in the field definition). Then you can just leave the timestamp field out of your INSERT query, and it'll be set correctly for you.
I've also changed the way you're using the objects stock. From the var_dump I can see the properties aren't called stock, high, low and all that. The problem is, some of these property names (lägst for example) are a bit dodgy. You'll probably have to access those using a string, which can be done, like I did, by writing $objVar->{'property name as string'}.
If I were you, though, I'd look into ways of changing what $data actually looks like, and change the property names if at all possible.

How will PHP Web Service read JSON

My JSON is
{"users":[{"UserName":"user1","FullName":"Name One"},
{"UserName":"user2","FullName":"Name Two"}]}
My PHP is
<?php
include '../inc/connect.php';
include '../inc/class/mysql.class.php';
$data = file_get_contents('php://input');
$array = json_decode($data, true);
$rows = array();
foreach ($array['users'] as $parentvalue)
foreach ($parentvalue as $key => $value)
$rows[] = "('" . $value . "', '" . $value . "')";
$values = implode(",", $rows);
try
{
$count = mysql_query("INSERT INTO users (UserName, FullName) VALUES $values") or die(mysql_error());
}
catch(PDOException $e) { //later
}
?>
The structure of the array is
Array
(
[users] => Array
(
[0] => Array
(
[FullName] => Name One
[UserName] => user1
)
[1] => Array
(
[FullName] => Name Two
[UserName] => user2
)
)
)
Instead of inserting the data:
**user1 - Name One
**user2 - Name Two
to MySQL...
It inserts
**user1 - user1
**Name One - Name One
**user2 - user2
**Name Two - Name Two
Please help!
/********EDIT (prev answer below)*********/
Here is my new code. I have modified your JSON structure based on your comments.
//added addresses as an example (no the postcodes aren't real :P)
$json='{
"users":[
{"UserName":"user1","FullName":"Name One"},
{"UserName":"user2","FullName":"Name 2"}
],
"addresses":[
{"HouseNumber":"1","PostCode":"LS1 1PS"},
{"HouseNumber": "23", "PostCode": "LS1 2PS"}
]
}';
$data=json_decode($json);
//loop over each 'table'
foreach ($data as $table_name=>$data_array){
$table_name=mysql_real_escape_string($table_name);
//loop over each 'row' in table
foreach($data_array as $current_obj){
$current_sql="INSERT INTO ".$table_name." SET ";
$row=array();
//loop through 'row' data and get 'column' name and value.
foreach($current_obj as $name=>$value){
$row[]='`'.mysql_real_escape_string($name).'` = "'.mysql_real_escape_string($value).'"';
}
$current_sql.=implode(',',$row);
mysql_query($current_sql);
unset($current_sql,$name,$value);
}
}
Now, while this code will do what you asked I probably wouldn't use it myself. I would have different endpoints in your web service for the different tables (and use GET,POST,PUT etc http requests to determine action - see REST web services) - Although its more work, clearly defined actions make debugging easier and your application more secure (as you'll know exactly what its doing and what to).
As for authentication, thats a whole issue on its own that I can't really go into here. Please don't think I mean this in an offensive way, but as you're new to development I would advise spending more time learning before trying to make anything production ready - to protect you and your customers more than anything.
Anyway, I hope this helps.
Regards
Ryan
/******* OLD ANSWER - LEFT HERE FOR CLARITY****************/
I believe you don't need the second loop. This is what I have (modify to suit your needs):
$json='{"users":[{"UserName":"user1","FullName":"Name One"},{"UserName":"user2","FullName":"Name 2"}]}';
$data = json_decode($json);
$rows = array();
foreach ($data->users as $user_obj){
$rows[]='("'.$user_obj->UserName.'","'.$user_obj->FullName.'")';
}
$values = implode(",", $rows);
echo "INSERT INTO users (UserName, FullName) VALUES ".$values;
Also, I would advise that you make use of prepared statements or at the very least mysql_real_escape_string.
Hope this helps,
Ryan :)
(P.s I stopped json_decode converting objects to arrays as it feel it is helpful to know when a data structure is supposed to be iterable and when it is not - feel free to change it back if you like.)
I slightly improved your code, for readability's sake. The very first thing you'd realize is that you're dealing with two problems here : one is parsing JSON response, and the second one is inserting records into a table:
$json = '{"users":[{"UserName":"user1","FullName":"Name One"},
{"UserName":"user2","FullName":"Name Two"}]}';
$values = buildArray($json);
insertValues($values);
function buildArray($json) {
$result = array();
$array = array_values(json_decode($json, true));
foreach ($array as $index => $nestedArray) {
foreach($nestedArray as $index => $value) {
$result[] = $value;
}
}
return $result;
}
function insertValues(array $values) {
foreach($values as $index => $array) {
$query = sprintf("INSERT INTO `users` (`UserName`, `FullName`) VALUES ('%s', '%s')",
mysql_real_escape_string($array['UserName']),
mysql_real_escape_string($array['FullName']),
);
if (!mysql_unbuffered_query($query)) {
return false;
}
}
return true;
}

foreach multidimensional Array and insert database

got a problem.
I got form like this
<input name="product[sub_name][]">
<input name="product[price][]">
<input name="product[random][]">
<input name="product[just_field][]">
I can add many blocks of this form pressing "add more".
Recieving posta data i do the stuff.
$field = $_POST['product'];
foreach ($field as $key => $values) {
foreach($values as $value) {
$key.' - '.$value;
}
}
I need code to insert multiple rows in database depending on posted rows. Problem is that, i dont know how to get only, for example, "price". Goal is insert all data in database. Hope you guys understand my logic.
Here is print_r output. I can got more possibilities than two
Array (
[sub_name] => Array ( [0] => New car [1] => New bike )
[standart_price] => Array ( [0] => 100 [1] => 300 )
[cupon_price] => Array ( [0] => 50 [1] => 200 )
[max_purchases] => Array ( [0] => 1000 [1] => 100 )
)
You can get a more ordered result if you re-organize the array to contain the index first:
<input name="product[$index][sub_name]">
<input name="product[$index][price]">
<input name="product[$index][random]">
<input name="product[$index][just_field]">
Each time you add a new product change the index with javascript, in that way, when you recieve the data in php you can do something like:
$products = $_POST['product'];
foreach ($products as $product)
{
$sub_name = $product['sub_name'];
$random = $product['random'];
$just_field = $product['just_field'];
$sql = "Your SQL query"
$mysqli->query($sql);
}
Maybe need a little more work changing the html indexes with javascript but your code become more clear.
p.s. That's the general idea, i don't test it.
Try to use
print_r($_POST["product"]);
to output the whole array.
Are you sure the values transmitted by the formular are passed into $_POST ?
Could you please post the output.
Check this out..
<?
//Connect to DB.
$link = mysqli_connect("HOST","USERNAME","PASSWORD","DATABASE") or die("Error " . mysqli_error($link));
//Consider your table structure in MYSQL. Don't depend on this structure.
//CREATE TABLE TBL1(SLNO PRIMARY KEY AUTO_INCREMENT, DETAIL_VALUE VARCHAR(200));
foreach( $_POST['product'] as $key => $value )
{
//Get specific Tag.
if( $key == 'price')
{
//Creating Query to insert.
$query = "insert into TBL1('DETAIL_VALUE') VALUES('".addslashes($value)."')";
$mysqli_query($link, $query) or die;
}
}
?>
For more details on querys or php: Refer PHP.net.
$mysqli = new mysqli("localhost", "root", "password", "db name");
$field = $_POST['product'];
foreach ($field['price'] as $idx => $price)
{
$sub_name = $field['sub_name'][$idx];
$random = $field['random'][$idx];
$just_field = $field['just_field'][$idx];
$sql = "INSERT INTO table (sub_name, random, just_field, price) VALUES ('{$sub_name}','{$random}','{$just_field}','{$price}')";
$mysqli->query($sql);
}

Categories