How to do a DB update of two separate yet associated arrays? - php

I am using Laravel, however in this case, I think that is irrelevant.
I have 1 array, $materials pulled from a form using $materials = $request->except() which delivers 2 sub arrays, product_code and quantity. So $materials looks like this:
{
"product_code":
[
"123",
"234",
"128"
],
"quantity":
[
"50",
"50",
"50"
]
}
Ok - I need to do an update of the DB table. The table has 2 columns, 'product_code' and 'quantity'
I was thinking I need a foreach loop to update each row:
product_code => Quantity
Problem: How do I update my DB, when the array is not organised in a
$key =>value pair ?
Secondly, is using a foreach() the best way to do it ? I have about 30 products.
Currently I have a foreach loop, which I can not see working for a DB update:
foreach($materials as $key=>$value) {
echo $key."<br>";
foreach ($value as $k=>$v) {
echo($v)."<br>";
}
}
And I get this out of it:
product_code
123
234
128
quantity
50
50
50
Many thanks !

$ids = $request->get('product_code');
$qty = $request->get('quantity');
foreach($ids as $key => $id) {
DB::table('product')->where('product_code', $id)->update(['quantity' => $qty[$key] ]);
}

You could always just do a for loop like the following (if your data is not in json then just ignore the json decode:
<?php
$json = '{"product_code": ["123","234","128"],"quantity": ["50", "50", "50"]}';
$data = json_decode($json, true);
for($i = 0; $i < sizeof($data['product_code']); $i++)
{
echo "UPDATE stuff with the ID " . $data['product_code'][$i] . " and the quantity " . $data['quantity'][$i] . "<br />";
}
?>
This will print

Related

How generate column using for loop

How to make this function produce column occLvl_ loop 3 time and using explode to fetch each value from sql CONCAT. So the result will become like this.
[{
"accommodationID": "LA56",
"occLvl_0": "40.00",
"occLvl_1": "70.00",
"occLvl_2": "90.00"
}]
function getOccLevel(){
global $ehorsObj;
$occArray = array();
$sql = "SELECT accommodationID, GROUP_CONCAT(occLevelDesc) AS occLevels
FROM tblSamAccOccLevels
WHERE ACTIVE = 'y'
GROUP BY accommodationID
ORDER BY accommodationID ASC, occLevelDesc ASC ";
$GetResult = $ehorsObj->FetchData($sql, $ehorsObj->DEFAULT_PDO_CONNECTIONS);
while ($row = $GetResult->fetch()){
$occArray[] = array(
'accommodationID' => $row['accommodationID'],
);
//seem the method below is not working
for ($j = 0; $j < 3; $j++) {
$occArray["occLvl_".$j] = explode(",", $row['occLevels'])
}
}
header("Content-type: application/json");
$result = json_encode($occArray);
echo $result;
}
Result of the query
accommodationID occLevels
LA56 40.00, 70.00, 90.00
Making numerically named object properties/variables (occLvl_0 etc.) is generally a bad idea as it makes it difficult to work with them in any regular manner (e.g. using a loop). It is better practice to put the values into an array:
while ($row = $GetResult->fetch()){
$occArray[] = array(
'accommodationID' => $row['accommodationID'],
'occLvl' => explode(",", $row['occLevels'])
);
}
This will give you an output JSON that looks something like:
[
{
"accommodationID": "LA56",
"occLvl": [
40,
70,
90
]
},
{
"accommodationID": "PQ45",
"occLvl": [
30,
60,
100
]
},
...
]
And in your JS you can then iterate over the occLvl array to get the values.
If you need the data in the form you describe, then you need to iterate over the exploded occLevels value to generate the individual values, pushing them with the accommodationID into a new array and then pushing that array to $occArray:
while ($row = $GetResult->fetch()){
$this_occ = array(
'accommodationID' => $row['accommodationID'],
);
foreach (explode(",", $row['occLevels']) as $key => $occLvl) {
$this_occ["occLvl_$key"] = $occLvl;
}
$occArray[] = $this_occ;
}
Explode returns an array. You should explode before the loop and iterate through the result of that explode in the loop

Getting a an array from for loop and use another for loop with that array in PHP

I have a for loop, and will form two arrays in the loo
foreach ($data as $key => $value) {
........
........
$user_insert[] = [
'keyy' => $value,
'key' => $value,
....
...
...
];
$someArray1[] = [
/*'user_id' => $insert_id,*/
'key1' => $value1,
'keyy' => $value,
.......
........
];
}
the count of $user_insert[] array is 4, the count of $someArray1 is 15.
after this for loop, I need to insert $user_insert array data to the database and use that inserted_id to insert next array $someArray1
foreach($user_insert as $insert_user){
$unique_user_insert = array_unique($insert_user);
//dd($unique_user_insert);
$insert_id = DB::table('users')->insertGetId($unique_user_insert);
foreach ($someArray1 as $someArray) {
$someArray['user_id'] = $insert_id;
DB::table('table_name')->insert($someArray);
}
}
So the problem here is the data in the second loop is inserting 60 times(4 * 15). I need to insert only 15 rows.
The data($someArray1) is coming from the first for loop, but I need to add a user_id to that array which I get after the insert operation in second for loop.
So how can i insert only 15 rows.
I'm going to assume that you are able to access your $someArray1 using the $insert_id value to find the appropriate user data.
foreach($user_insert as $insert_user){
$unique_user_insert = array_unique($insert_user);
$insert_id = DB::table('users')->insertGetId($unique_user_insert);
// Get the user information you need as $someArray1 should be user_id=>data
$userData = $someArray[$insert_id];
$userData['user_id'] = $insert_id;
// No need for an inner loop, just access the necessary properties of the loop you created earlier.
DB::table('table_name')->insert($userData);
}
Your tags indicate that you are using Laravel 5 too. If you are using the eloquent ORM, some of the insertion and ID retrieval can be cleaned up by creating Models for your DB tables.
Actually, each time you process a line from $user_insert, you loop over $someArray1 instead of fetching just the line you need.
The thing is to understand the line you need. As much as I can understand your piece of code, I would say the easiest (most readable) way of doing it is by using a for loop, not a foreach one :
for( $i = 0, $iMax = count( $user_insert ); $i < $iMax; ++$i ){
$insert_user = $user_insert[$i];
// Put your `$user_insert` insert code here
$someArray1[$i]['user_id'] = $insert_id;
DB::table('table_name')->insert( $someArray[$i] ); // Note the [$i] here
}
You also may do that with foreach by requesting indices :
foreach( $user_insert as $i => $insert_user ){
$unique_user_insert = array_unique($insert_user);
//dd($unique_user_insert);
$insert_id = DB::table('users')->insertGetId($unique_user_insert);
// Now use $i requested above :
$someArray1[$i]['user_id'] = $insert_id;
DB::table( 'table_name' )->insert( $someArray1[$i] );
}

PHP loop through array and if key1 add operator to variable

I have not coded in many years and have decided to make my own golf statistics program.
I have an issue with going through an array and getting the data I want out. I'm guessing it is very simple but I'm very rusty and tried to read myself to this. Thankful for any help.
For the below code I want $dismade to be 8 it now returns 4?
<?php
$score = array(
"4" => "4",
"3" => "4",
"4" => "4"
);
$dismade = 0;
foreach ($score as $stroke => $dis) {
if($stroke == 4) {
$dismade = $dis + $dismade;
}
}
echo $dismade;
?>
UPDATE!!
That worked well. Thanks. Now i have another issue where i would need to do this 18 times. I tried doing like below without luck. What i want to do is to check the foreach array 1-18. They will all be the same with 9 keys inside. Am i thinking correctly on this? The below only gets the first position. $row[fp1] for example will always be key 2 but can have alot of values inside which i want to go through and add to $gir and then move on to fp2 and so on to 18 and add into $gir array. I hope my question makes sense.
$hole1 = array();
$hole2 = array();
$result = mysql_query($sql) or die ("Couldn't select table at!!");
while ($row = mysql_fetch_array($result)) {
$hole1[$row[rid]] = array($row[s1],$row[p1],$row[gir1],$row[ngir1],$row[fp1],$row[fw1],$row[ud1],$row[ss1],$row[pen1]);
$hole2[$row[rid]] = array($row[s2],$row[p2],$row[gir2],$row[ngir2],$row[fp2],$row[fw2],$row[ud2],$row[ss2],$row[pen2]);
}
mysql_free_result($result);
$gir = array();
foreach (array_combine($hole1,$hole2) as $value) {
if($value[2] == 1) {
array_push($gir,$value[4] );
}
}
print_r ($gir);
There is a problem with your $score keys. As you can see you have a duplicate key "4".
Try something like:
$score = array([4,4], [3,4], [4,4]);
$dismade = 0;
foreach ($score as $value) {
if($value[0] == 4) {
$dismade += $value[1];
}
}
echo $dismade;
Have a nice day.
Because you have an duplicate key "4" in your array, since every key is unique in
array so the third line "4" => "4" will overlap the first line within array.

Removing an item from an array during a foreach loop

I have the following foreach being performed in PHP.
What I would like to do is instead of the $invalid_ids[] = $product_id; building and then looping around that, I would instead like to remove the entry from array that is being looped around as I'm looping around it..
For example:
If the current $product_id fails any of the test, delete the item from the $current_list array and proceed to the next iteration of the foreach loop.
I tried to do an unset($product_id) while the foreach loop header looked like this: foreach ($current_list as &$product_id) {, but the item item is still in the array.
Does anyone have any ideas on how I can go about doing this?
foreach ($current_list as $product_id) {
// Test 1 - Is the product still active?
// How to test? - Search for a product in the (only active) products table
$valid = $db->Execute("SELECT * FROM " . TABLE_PRODUCTS . " WHERE products_id = " . $product_id . " AND products_status = 1");
// Our line to check if this is okay.
if ($valid->RecordCount <= 0) { // We didn't find an active item.
$invalid_ids[] = $product_id;
}
// Test 2 - Is the product sold out?
if ($valid->fields['products_quantity'] <= 0 and STOCK_ALLOW_CHECKOUT == "false") { // We found a sold out item and it is not okay to checkout.
$invalid_ids[] = $product_id;
}
// Test 3 - Does the product have an image?
if (empty($valid->fields['products_image'])) { // Self explanatory.
$invalid_ids[] = $product_id;
}
}
$product_id isn't the actual data in the array, it's a copy of it. You would need to unset the item from $current_list.
I'm don't know how $current_list is stored, but something like unset($current_list['current_item'] would do the trick. You can use key to select the current_item key in the array.
A similar way of iterating the Array, where you can get the array key, from the PHP key docs...
while ($fruit_name = current($array)) {
if ($fruit_name == 'apple') {
echo key($array).'<br />';
}
next($array);
}
Untested, but something like this...
while ($product_id = current($current_list)) {
// Do your checks on $product_id, and if it needs deleting...
$keyToDelete = key($array);
unset($current_list[$keyToDelete]);
next($current_list);
}
I think this simple code may help you
let's say we have an array of integers and we want to remove all the items that are equal to "2" inside of the foreach loop
$array = [1,2,1,2,1,2,1];
foreach ($array as $key => $value)
{
if($value==2)
unset($array[$key]);
}
var_dump($array);
this shows the following result
array (size=4)
0 => int 1
2 => int 1
4 => int 1
6 => int 1

Insert if not exists in DB and delete if not in an array

I have an array like this :
$services = array(
array("id" => "1", "desc" => "desc 1"),
array("id" => "2", "desc" => "desc 2" ),
......
);
I want to insert those services in TABLE_SERVICE .
each service is inserted if it doesnt exists in TABLE_SERVICE , and deleted it if it exists in TABLE_SERVICE but not in $services array.
I could just delete all records in TABLE_SERVICE and then insert all $services elements ,
but that can be an issue with performance because i often have large set of data in both TABLE_SERVICE and $services .
So is there an efficient way to do this ?
Thanks.
If it was me I'd iterate over $services collecting ids:
$ids = array();
foreach($services as $service)
{
$ids[] = $service['id'];
}
Then using PHP's join and the select NOT IN
"DELETE FROM TABLE_SERVICE WHERE id NOT IN (" . join($ids,',') . ")"
After that, iterate over the array again to insert/update using ON DUPLICATE KEY
"INSERT INTO TABLE_SERVICE (id,desc) VALUES (?,?) ON DUPLICATE KEY UPDATE desc = ?"
Since oracle doesn't have ON DUPLICATE KEY this stackoverflow question might help you with that last part.
My answer would be that there isn't really an efficient way to do this.
I have thought about a merge, but to be efficient, you would still be better off first inserting it in a temporary table. Then you might as well just truncate table_service and then fill it again from your $service array.
Even if Kristoffer's anwser could work, it might still be slower than a truncate insert.
This is my php method to quickly insert a lot of records:
The advantage of this is, that your insert statement will be parsed only once instead for each insert, which will improve the speed greatly. Sometimes by a factor 100 or so.
$connection = oci_connect(<YOUR CONNECTION>);
$sql = insert into table_service (id, var) values (:id, :var); // desc is a reserved word, cannot be a column name
$parsed = oci_parse($connection, $sql);
$binds = array(':id', ':var');
$sizes = array(6, 20);
$data = $services;
$errors = execute_multiple($binds, $sizes, $data);
if ($errors > 0)
// log or show
else
// feedback: full succes!
function execute_multiple($binds, $sizes, $data, $commit = true)
{
$errorCount = 0;
// first determine all binds once
foreach ($binds as $i => $bind)
{
// ${trim($bind, ':')} example: :some_id -> $some_id
oci_bind_by_name($parsed, $bind, ${trim($bind, ':')}, $sizes[$i]);
}
// Then loop over all rows and give the variables the new value for that row
// This is because the variables remain binded!
for ($row=0; $row<count($data); $row++)
{
foreach ($binds as $i => $bind)
{
$value = array_key_exists($i, $data[$row]) ? substr($data[$row][$i], 0, $sizes[$i]) : null;
${trim($bind, ':')} = trim($value);
}
if (! #oci_execute($this->parsed, OCI_DEFAULT)) // don't auto commit
$errorCount++;
}
if ($commit)
oci_commit($connection);
return $errorCount;
}

Categories