php creating an array based off keys of another array - php

Background: I have an array created by:
$order = $_POST['order'];
The contents only have a single value per row:
[0] => 1
[1] => 4
[2] => 5
[3] => 2
[4] => 2
I am updating a database with this:
for ($i=0; $i<count($order); $i++)
{
$sql = "UPDATE catalog SET quantity=quantity - $order[$i] WHERE item_number= $i +1";
$result = mysqli_query($connection,$sql) or
die("<b>Query Failed.</b><br>" . mysqli_error($connection));
}
But I would like to use SELECT to search for records in which I have updated. Of course the problem is I do not have a direct item number to reference since I used $i +1 to refer to it.
As you can see the (array)key+1 to each value is equal to the item_number. So I was hoping to create an array in which the following is true:
for ($i=0; $i<count($order); $i++)
{
if ($order[$i] > 0)
{
$itemNum[$i] = 1;
} else {
$itemNum[$i] = 0;
}
I am sure I am over thinking this but I just need to be able to set up a WHERE statement displaying only item_num records which were just updated.

Make an array containing all the item_numbers you are updating. Then, select those item_numbers.
$updated = [];
for ($i=0; $i<count($order); $i++)
{
if ($order[$i] > 0) {
$updated[] = $i + 1;
$sql = "UPDATE catalog SET quantity=quantity - $order[$i] WHERE item_number= $i +1";
$result = mysqli_query($connection,$sql) or
die("<b>Query Failed.</b><br>" . mysqli_error($connection));
}
}
$sql = "SELECT * FROM catalog WHERE item_number IN (" . implode(",", $updated) . ")";
What are you going to do if the order is for more quantity than are remaining in catalog?

Related

Each row has the same random number being inserted

I'm looking to insert random numbers into each column in a database.
The issue that is occuring is that each column for some reason has the same random generated value being passed inside.
$sql = "SELECT * FROM players";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
$targScore = 3;
while($row = $result->fetch_assoc()) {
$target = 3; // The target number the sequence is adding up to
$n = 4; // Max numbers within sequence
while ($n) {
if (1 < $n--) {
$addend = rand(0, $target - ($n - 1));
$target -= $addend;
$num[] = $addend;
} else {
$num[] = $target;
}
}
/* Rows to update */
/* Output looks like:
[0] = 1
[1] = 2
[0] = 0
[0] = 1
*/
$changeScore = "UPDATE players SET doja='$num[0]' WHERE score='$targScore'";
$conn->query($changeScore);
$changeScore = "UPDATE players SET 7acres='$num[1]' WHERE score='$targScore'";
$conn->query($changeScore);
$changeScore = "UPDATE players SET tweed='$num[2]' WHERE score='$targScore'";
$conn->query($changeScore);
$changeScore = "UPDATE players SET bickel='$num[3]' WHERE score='$targScore'";
$conn->query($changeScore);
}
}
The data looks like: https://imgur.com/a/nhhZDVo
What I need is that each loop, it will run the randomizer again but change the numbers its inserting so that each row will have different numbers.
You need to first get a list of all the rows that meet the score condition. Then you have to update them one by one, so you can set different random values in each.
$select_stmt = $conn->prepare("SELECT id FROM players WHERE score = ?");
$select_stmt->bind_param("i", $targScore);
$select_stmt->execute();
$res = $select_stmt->get_result();
$update_stmt = $conn->prepare("UPDATE players SET doja = ?, 7acres = ?, tweed = ?, bickel = ? WHERE id = ?");
$update_stmt->bind_param("iiiii", $doja, $acres, $tweed, $bickel, $id);
$target = 3;
while ($row = $res->fetch_assoc()) {
$n = 4;
$num = [];
while ($n) {
if (1 < $n--) {
$addend = rand(0, $target - ($n - 1));
$target -= $addend;
$num[] = $addend;
} else {
$num[] = $target;
}
}
[$doja, $acres, $tweed, $bickel] = $num;
$id = $row['id'];
$update_stmt->execute();
}
There's also no need to use four UPDATE statements to update 4 columns in the same rows.
MySQL has a rand() function https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html#function_rand
(Note the warning that it's not perfectly random / security secure, but nor is PHPs rand()).
If you do not need to know what the values are, you can simply do UPDATE myCol=FLOOR(RAND() * 200) WHERE myConditionalField=MyCondition
This will allocate a random number from 0 to 199; examples in the MySQL manual (linked above) as to how to set a range, e.g. FLOOR(7 + (RAND() * 5)) gives an integer from 7 to 11.

How to calculate the sum of number array elements from multiple database rows using php?

I need to count the number of elements that exist in the column of a MySQL database row for multiple rows and them add them all together. This is the code I used to count the number of array elements (which are numbers separated by commas):
$result = substr_count($count_fetch['micro_analysis'], ",") + 1;
But now I need to do this for each row, which could vary depending on the query. I need to add the $result of each row together to get a final sum of all the rows. I used the following code but I get the incorrect value, can someone please point me in the right direction?
$sql = "SELECT * FROM samples_database WHERE order_id = $order_id";
$count_query = mysqli_query($conn, $sql);
$count_fetch = mysqli_fetch_assoc($count_query);
foreach ($count_fetch as $row) {
$result = substr_count($count_fetch['micro_analysis'], ",") + 1;
$end_result += $result;
}
echo $end_result;
You are just fetching 1 row and then trying to count over that row, instead you need to loop over the rows and add the fields in that...
$sql = "SELECT * FROM samples_database WHERE order_id = $order_id";
$end_result = 0;
$count_query = mysqli_query($conn, $sql);
while( $row = mysqli_fetch_assoc($count_query)) {
$end_result += substr_count($row['micro_analysis'], ",") + 1;
}
echo $end_result;
Replace your code with the following:
$sql = "SELECT * FROM samples_database WHERE order_id = $order_id";
$count_query = mysqli_query($conn, $sql);
$count_fetch = mysqli_fetch_assoc($count_query);
$end_result=0;//initialize variable to 0
foreach ($count_fetch as $k => $row) {
if($k == 'micro_analysis'){
$result = substr_count($row, ",") + 1; //change over here
$end_result += $result;
}
}
echo $end_result;

Make SQL selection from nested arrays

I am trying to make a selection based on a nested array I get from a prior selection.
Here is where I make my first selection:
$coursequery = "
SELECT
courseID
FROM enrollments
WHERE
studentID = '$userid'
";
try
{
$stmt = $db->prepare($coursequery);
$result = $stmt->execute();
}
catch(PDOException $ex)
{
die("Failed to run query: " . $ex->getMessage());
}
$rows = $stmt->fetchAll();
$_SESSION['studentcourses'] = $rows;
This gets all the courseID's in the following format:
Array ( [0] => Array ( [courseID] => 6 ) [1] => Array ( [courseID] => 7 ) )
and I want to be able to access these ID's for selecting information from a different table. I've started by trying to use a for loop to grab all the "course information" depending on the ID.
for($i = 0; $i < $count; $i++) {
$coursequery = "
SELECT
*
FROM courses
WHERE courseID = '$studentcourses[$i]'
";
try
{
$stmt = $db->prepare($coursequery);
$result = $stmt->execute();
}
catch(PDOException $ex)
{
die("Failed to run query: " . $ex->getMessage());
}
$row = $stmt->fetchAll();
$_SESSION['studentcourseinfo'] = $row;
}
Any help would be greatly appreciated in accomplishing this!
You can accomplish this with one SQL query thus eliminating all these loops
SELECT
*
FROM courses
INNER JOIN enrollments ON
enrollments.courseID = courses.courseID
AND enrollments.studentID = '$userid'
WHERE 1
you can use same array in query, can use implode function
$coursequery = "SELECT * FROM courses
WHERE courseID IN (" . implode(",", $studentcourses) . ");";
As long as you change the output format
Array (6, 7)
where 6 and 7 would be the id of the courses
Also in you code have mistake in rewrite var $_SESSION['studentcourseinfo'] = $row; these overwriting the same variable at a time

php for loop inside a foreach loop, not sure how to do it

I'm trying to do a for loop inside a foreach loop.
I have a table in my database as follows:
ID | Fname | Lname
------------------------
1 Bart Simpson
1 Mickey Mouse
2 Peter Griffin
2 Clark Kenet
2 David Johnson
i call the data from the database (and it works, tested on phpmyadmin), I want the data to be shown on the page by the ID value for exemple:
Bart Simpson, Mickey Mouse & Peter Griffin
Clark Kenet & David Johnson
as you see there in an "&" before the last name at any row but that isnt my problem.
this is the code i wrote:
//HERE I RETRIVE ALL THE DATA FROM THE DATABASE.
$query = $dbh->query(" SELECT *
FROM table
WHERE ID= '{$ID}'
");
//THIS CODE SHOWS THE NUMBER OF ROWS WITH THE CURRENT ID
$sql = "SELECT COUNT( * ) FROM table WHERE ID= '{$ID}'";
$result = $dbh->prepare($sql);
$result->execute();
$number_of_rows = $result->fetchColumn();
//THIS IS THE FOREACH IN WHICH I CALL ALL THE ROWS BY THEIR VALUE
foreach ($query as $key =>$value) {
$value['wFname'][$key] = !empty($value['wFname'][$key]) ? $value['wFname'][$key] : '';
$numRow = $number_of_rows-2; // THE ITEM BEFORE THE LAST ONE IN THE ARRAY
$lastItem = $number_of_rows-1; //LAST INDEX IN THE ARRAY
for($counter = 0; $counter = $numRow; $counter++){
return $value['wLname'][$counter] . ', '. $value['wFname'][$counter];
}
return "&" . $value['wLname'][$lastItem] . ', '.$value['wFname'][$lastItem] ;
return ' ';
};
with this code i get only the first pair of names with each id.
any help would be great.
Try changing:
for($counter = 0; $counter = $numRow; $counter++){
to:
for($counter = 0; $counter =< $numRow; $counter++){
You are checking if $counter equals $numRow, and you should check if it equals and is less than...
Hope this helps.
EDIT Based on user requests
Try storing the results in a variable and return that variable at the end of both loops, but im not sure what you are trying to achieve here, try running the following code:
//HERE I RETRIVE ALL THE DATA FROM THE DATABASE.
$query = $dbh->query(" SELECT *
FROM table
WHERE ID= '{$ID}'
");
//THIS CODE SHOWS THE NUMBER OF ROWS WITH THE CURRENT ID
$sql = "SELECT COUNT( * ) FROM table WHERE ID= '{$ID}'";
$result = $dbh->prepare($sql);
$result->execute();
$number_of_rows = $result->fetchColumn();
//THIS IS THE FOREACH IN WHICH I CALL ALL THE ROWS BY THEIR VALUE
$return = "";
foreach ($query as $key => $value) {
$value['wFname'][$key] = !empty($value['wFname'][$key]) ? $value['wFname'][$key] : '';
$numRow = $number_of_rows - 2; // THE ITEM BEFORE THE LAST ONE IN THE ARRAY
$lastItem = $number_of_rows - 1; //LAST INDEX IN THE ARRAY
for ($counter = 0; $counter <= $numRow; $counter++) {
$return .= $value['wLname'][$counter] . ', ' . $value['wFname'][$counter];
}
$return .= "&" . $value['wLname'][$lastItem] . ', ' . $value['wFname'][$lastItem];
$return .= ' ';
}
return $return;

MySQL contains variable

I have an array in PHP that is looping through a set of names (and a corresponding quantity). I would like to print the ones found in a MYSQL database table (to which I've succesfully connected). I'm currently using the code:
foreach ($arr as $name => $quan) {
$query = "SELECT * FROM table WHERE name='$name'";
$result = mysql_query($query) or die(mysql_error());
if (mysql_num_rows($result) > 0) {
$row = mysql_fetch_array($result);
echo $quan." ".$row['name']. "\n";
}
}
For some reason, this only prints the last quantity and name in the array. Help?
For example, if the array has key-value pairs of {A-4, B-2, C-3}, and table contains {A, B, D} as names ... it'll only print "2 B".
Change the code to the following:
foreach ($arr as $name => $quan) {
$query = "SELECT * FROM table WHERE name='$name'";
$result = mysql_query($query) or die(mysql_error());
if (mysql_num_rows($result) > 0) {
while($row = mysql_fetch_array($result)) {
echo $quan." ".$row['name']. "\n";
}
}
}
You have to loop through the result. By the way, stop using mysql_query()! use MySQLi or PDO instead ( and be careful of SQL Injection ; you can use mysqli_real_escape_string() to handle input parameters ). For MySQLi implementation , here it is :
foreach ($arr as $name => $quan) {
$query = "SELECT * FROM table WHERE name='$name'";
$result = mysqli_query($query) or die(mysqli_error());
if (mysqli_num_rows($result) > 0) {
while($row = mysqli_fetch_array($result)) {
echo $quan." ".$row['name']. PHP_EOL;
}
}
}
And rather "\n", I prefer using PHP_EOL ( as shown above )
And as the comment suggests, the SQL statement can be executed once, as follow:
$flipped_array = array_flip($arr); // flip the array to make "name" as values"
for($i = 0; $i < count($flipped_array); $i++) {
$flipped_array[$i] = '\'' . $flipped_array[$i] . '\''; // add surrounding single quotes
}
$name_list = implode(',', $arr);
$query = "SELECT * FROM table WHERE name IN ($name_list)";
// ... omit the followings
e.g. in $arr contains "peter", "mary", "ken", the Query will be:
SELECT * FROM table WHERE name IN ('peter','mary','ken')
sidenote: but I don't understand your query. You only obtain the name back from the query? You can check number of rows, or you can even group by name, such as:
SELECT name, COUNT(*) AS cnt FROM table GROUP BY name ORDER BY name
to get what you want.
UPDATE (again): based on the comment of OP, here is the solution :
$flipped_array = array_flip($arr); // flip the array to make "name" as values"
for($i = 0; $i < count($flipped_array); $i++) {
$flipped_array[$i] = '\'' . $flipped_array[$i] . '\''; // add surrounding single quotes
}
$name_list = implode(',', $arr);
$query = "SELECT name, COUNT(*) AS cnt FROM table WHERE name IN ($name_list) GROUP BY name HAVING COUNT(*) > 0 ORDER BY name";
$result = mysqli_query($query) or die(mysqli_error());
if (mysqli_num_rows($result) > 0) {
while($row = mysqli_fetch_array($result)) {
echo $quan." ".$row['name']. ": " . $row['cnt'] . PHP_EOL;
}
}
The above query will show the name appearing in the table only. Names not in table will not be shown. Now full codes ( be cautious of SQL Injection , again )

Categories