Use of unset and count with arrays - php

I have a array that contains other arrays with each user's details in. For example:
$_SESSION["ActQueue"] = [["J.Paul", "John", "Paul", "0000-00-00 00:00:00"],["J.Bloggs", "Joe", "Bloggs", "0000-00-00 00:00:00"]]
I have written a bit of code that is mean to turn the "account rank" of the first user in the array to "Cadet" in the database. The code then removes the user from the array and then should either echo data = 1 or the next user in the list depending if they exist. I have done this with the following bit of code, however I have found that when unset deletes the first item it the keys don't shift down 1, so 0 will simply not exist and 1 will still be "J.Bloggs". As a result when the next user is echoed no values are sent. Any suggestions?
<?php
session_start();
require "classes.php";
$TF = new TF_Core ();
$ActQueueAccept = "UPDATE users
SET rank = 'Cadet'
WHERE username = ?";
if ($statement = TF_Core::$MySQLi->DB->prepare($ActQueueAccept)) {
$statement->bind_param('s',$_SESSION["ActQueue"][0][0]);
$statement->execute();
}
unset($_SESSION["ActQueue"][0]);
if(count($_SESSION["ActQueue"] != 0)){
echo json_encode(['Username'=>$_SESSION["ActQueue"][0][0], 'Surname'=>$_SESSION["ActQueue"][0][1],'Forename'=>$_SESSION["ActQueue"][0][2],'Joined'=>$_SESSION["ActQueue"][0][3]]);
}
else{
$data = 1;
echo $data;
}
?>

unset($_SESSION["ActQueue"][0]);
$_SESSION["ActQueue"] = array_values($_SESSION["ActQueue"]);
It seems that unset() does not always reset array keys. The function array_values redefines my array with the correct keys / indexes it.

Related

Prevent duplicate ids from being added to session (array)

I got a session which adds ids to an array, the problem is every id gets added even if the id is already present. How can I prevent duplicate id's from being added to the array?
I figured I need to check for the id using in_array but I don't know exactly how to use it correctly.
I send the id of the product to my quote page using this link:
<p><a class="offertelink" href="offerte.php?product='.$productcr[0]['id'].'">Request a quote</a></p>
Then on that page I use the following code:
if(!isset($_SESSION['product'])){
$_SESSION['product'] = array();
}
// CHECK FIRST THAT $_GET['product'] IS SET BEFORE ADDING IT TO SESSION
if( isset($_GET['product'])){
$_SESSION['product'][] = $_GET['product'];
}
$prods = implode(",", $_SESSION['product']);
And finally load all the products with the ids that are inside the array:
if(count($_SESSION['product']) != 0){
// offerte overzicht
$offerte = "SELECT * FROM `snm_content` WHERE `id` in (".$conn->real_escape_string($prods).") AND state = 1";
$offertecon = $conn->query($offerte);
$offertecr = array();
while ($offertecr[] = $offertecon->fetch_array());
}
But now everytime I reload the page, the id is added again, it's not really bad since the products are only loaded once, but still I would like to fix this, because I think a query checking for tons of duplicate ids is not the best way.
Using in_array is simple - you just check if element is in array:
var_dump(in_array($element, $array));
In your case it is:
var_dump(in_array($_GET['product'], $_SESSION['product']));
And the check is:
// i advise you to check product value as `int`.
// Because values as `empty string` or `0` or `false` are considered set
if( 0 < intval($_GET['product']) && !in_array($_GET['product'], $_SESSION['product']) ) {
$_SESSION['product'][] = $_GET['product'];
}
But the more clever solution is to use product id as an array key with some fixed value (1 or true for example):
$_SESSION['product'] = [
'101' => 1,
'102' => 1,
'106' => 1,
];
In this case you don't even need to check if your key exists - if it exists it will be overwritten, if not - will be added:
if( 0 < intval($_GET['product']) ) {
$_SESSION['product'][ $_GET['product'] ] = 1;
}
// but here you need to take array keys instead of values
$prods = implode(",", array_keys($_SESSION['product']));
Option 1
Use in_array() to prevent duplicates:
// CHECK FIRST THAT $_GET['product'] IS SET BEFORE ADDING IT TO SESSION
if( isset($_GET['product'])){
if(!in_array($_GET['product'], $_SESSION['product']){
// product not exists in array
$_SESSION['product'][] = $_GET['product'];
}
}
Option 2 empty array before adding products
//if(!isset($_SESSION['product'])){
$_SESSION['product'] = array();
//}

Fetch result from database to multiple variables

I have a site were the user fills a form and all data is stored in a database, when the user enter his/hers page all the added data is visible. Today I´m doing this but in a lot of code rows and there is for sure a much smoother way to do this.
Here´s a look of how I have done it today:
$query = mysqli_query($dbhandle, "SELECT * FROM ..."); // ... added now
$row = mysqli_fetch_assoc($query);
$m0 = $row['m1'];
$m1 = $row['m2'];
$m2 = $row['m3'];
$m3 = $row['m4'];
...
$m47 = $row['m48'];
$firstPlace = $row['firstPlace '];
$secondPlace = $row['secondPlace '];
$thirdPlace = $row['thirdPlace '];
$fourthPlace= $row['fourthPlace'];
As you can see there are a lot of rows of code. What I would like to do is to loop through my query and then add the right value in the database to the right value in the form.
Appreciate help.
There definitely are many alternative (and in every possible sense of the word) better ways to go about your business.
For a kickoff: ask yourself what an array actually is. An array is a collection of data. You store them together because one value of that array in itself doesn't mean much. The data in an array belongs together. Why then, assign it to individual variables in the first place?
Of course, your $row array has keys like $row['m1'], which you assign to a variable called $m0. so the names of the fields in the database don't quite match the names your code uses. That's something that you can, quite easily, fix by changing your query: use aliasses for those fields:
SELECT m1 as m0, ... FROM
Now your array will have a key called m0, instead of m1. This reduces the rest of your code down to:
$row = mysqli_fetch_assoc($query);
echo 'M0: ', $row['m0'];//<-- use m0 value here.
Alternatively, you could use a second array that maps these field-names to the name you want to use in your code:
$map = array(
'm0' => 'm1'
);
echo 'M0: ', $row[$map['m0']];//use value of m0, which is the actual key if the $row array
Still, if you are hell-bound on unmaintainable, messy, error-prone and just awful code, you could use variable variables:
foreach ($row as $key => $value)
{
$$key = $val;
}
Note the double $ in $$key. This is like saying "the variable that is called whatever the value of $key is". If $key is firstname, the code above evaluates to $firstname = $value. But whatever you do: forget this is possible. It's like an enema: yes, it's possible, but you don't want one if you can avoid it. And in this case, you clearly can avoid it.
Loop through the $row var grabbing the key and value. If key starts with "m" followed by a 1 or 2 digit number, get the number, subtract one, concatenate it with "m", and assign the value. Otherwise just interpolate key into variable name and assign value.
foreach ( $row as $key => $value ) {
if ( preg_match('/^m(\d{1,2})/', $key, $matches) ) {
${'m' . ($matches[1] - 1)} = $value;
}
else { $$key = $value; }
}
In the above example, $row['m1'] value gets assigned to var $m0, and $row['firstPlace'] to var $firstPlace, etc.

how to identify unsaved value from database using php mysql

I have to identify unsaved value from mysql table using php and mysql, for example i using table named as numtab and i have already stored some numbers 1, 3, 4, 7, 23, 12, 45 in numb column.
now i have generated one new number randomly(for example 23) and i have to check this number with already stored numbers,
if 23 is exist in the table mean i have to generate another one new number and have to check once again with stored values, this process have to continue till finding unsaved number.
if generated value is not exist in table mean can stop the process and can store this number in table.
here below the format i am currently using
$numb=23;
$qryb="select * from numtab where numb='$numb'";
$results=mysql_query($qryb)or die("ERROR!!");
if(mysql_num_rows($results) == 1)
{
$numb=rand(1,100);
mysql_query("insert query");
}
the problem is above the code is validation once only, its not verifying second time. i think if using for or while loop mean can solve this problem, but i dont know how to do looping, so help me to solve this problem.
You can use in clause like this :
$qryb="select * from numtab where numb in('$numb')";
$results=mysql_query($qryb)or die("ERROR!!");
$count = mysql_num_rows($results);
if ($count > 0) {
echo "number exist in db";
} else {
echo "number does not exist in db";
}
You could make a while() loop to check if the numbers exist in your database. You could also retrieve all numbers from the database, store them in an array and check if the generated number exists within that array.
The first option would be something like this:
do {
$numb=rand(1,100);
$qryb="select * from numtab where numb='$numb'";
$results = mysql_query($qryb) or die("ERROR!!");
} while(mysql_num_rows($results) >= 1)
mysql_query("insert query");
The second option would be something like this:
$query = mysql_query("SELECT DISTINCT(numb) as numb FROM numtab");
// set array
$array = array();
// look through query
while($row = mysql_fetch_assoc($query)){
// add each row returned into an array
$array[] = $row['numb'];
}
do
{
$numb = rand(1,100);
}
while(!in_array ( $numb , $array) ;
mysql_query("insert query");

PHP SQL Update array

I originally was satisfied with the following in order to update row 1 and row 2 to the same value (status=1)
if ($_POST){
$sql ="UPDATE table SET status = 1,
WHERE id IN (1,2 );";
db()->query($sql);
if(db()->query($sql)){
echo "<b>Good</b>";
}
else{
echo "<b>No Good</b>";
}
}
But now I want to update with different values, ie- row 1 to status 1, row 2 to status 2, and row 3 to status 3.
Off the bat, I know I need to
1. Use an array and loop through it three times.
2. pass in the array value into the $sql
I figure it would be something like this but I am still learning PHP..
$array_id = array(1, 2, 3);
$array_status = array(1, 2, 3);
if ($_POST){
$sql ="UPDATE table SET status = $array_status
WHERE id = $array_id;";
db()->query($sql);
if(db()->query($sql)){
echo "<b>Update Successful</b>";
}
else{
echo "<b>Update Unsuccessful</b>";
}
}
How would I go about making this happen?
You can loop through the arrays using a for loop and exec a query for each one (Radu Vlad answer), or you can build a long query and execute it once, something like this:
if ($_POST){
$sql = ""; // Blank string
$len = count($array_id); // Number of iterations
for ($i = 0; $i < $l; $i++) { // Enter the loop
$sql .= "UPDATE
table
SET
status = {$array_status[$i]}
WHERE id = {$array_id[$i]};"; // Append the query
}
db()->query($sql);
if(db()->query($sql)){
echo "<b>Update Successful</b>";
}
else{
echo "<b>Update Unsuccessful</b>";
}
}
When the val of $i is 0, then $array_id[$i] will print the first element, when $i is 1, $array_id[$i] will print the second element, and so on.
Using .= you append text to a string. By the end of the loop, $sql will be a string with 3 queries ('UPDATE ... SET ...; UPDATE ... SET ...; UPDATE ... SET ...;').
Not sure if it's the best way, though. But you get the idea.
If yow want the status to be equal to the id, do this (single query):
UPDATE table SET status=id WHERE id IN (1,2,3);
Of course you can use some math, like:
UPDATE table SET status=(id+1)*2 WHERE id IN (1,2,3);
You didn't really explain why you need that, so
try1(childish): set status = id
"UPDATE table SET status = id"
It's a bad practice, and only you could understand what those numbers are. Plus if id is auto-increment, status will be auto-increment too, you will have a duplicate column. If status has only 3 values posible, you should not do this.
try2(basic): do 3 updates, or actually, do as many as you need with a for
if ($_POST){
$status = 1;
for ($i = 1; $i <= 3; $i++){
$sql ="UPDATE table
SET status = $status
WHERE id = $i;";
db()->query($sql);
$status++;
}
A better way bacause you have more control over the status. Of course the second try is irrelevant if you have only that 3 values. This one assumes you will change the $status variable inside the for loop, in concordance with the $i (id)
try3(mature): set one or 2 arrays with the concordance between id and status, so that either $arr[$id] will have the value of status and the key will be the id, or $arr1[$i] will have the value of id, and $arr2[$i] will have the value of status
the example will have only one array(also called map, because you map a value based on another value)
if ($_POST){
$status_array = array(1 => 1,2 => 2,3 => 3);
for ($i = 1; $i <= 3; $i++){
$sql ="UPDATE table
SET status = $status_array[$i]
WHERE id = $i;";
db()->query($sql);
}
Also, this works because the array is consistent. If you do not have an consistent array you should either work with 2 arrays, or try a foreach with key->value instead of for
I would suggest you to use the following code:
$theArray = array("1" => "1","2" => "2","3" => "3"); // The scheme is ID => Status
$errorMsg = false; // Our default assumption is that no error occured
foreach($theArray as $key => $value) {
$sql = "UPDATE table SET status =".$value." WHERE id = ".$key;
if(!db() -> query($sql)) { // Execute the query and check whether it failed
$errorMsg = "Query for ID ".$key." failed.";
break; // When the query failed we exit the loop and echo the error message
}
}
if($errorMsg) { // If an error occured (errorMsg is no longer false) we echo it here
echo $errorMsg;
}
Basically you do just create one array $theArray, which contains key => value pairs of the IDs and the statuses you want to give them. Afterwards, you loop through this array, execute the db() -> query() for each key => value pair and check whether it failed or not. If a query failed, you break the loop and output the error message.
Advantages:
Instead of using two arrays ($array_id, $array_status) I do use only one associative array $theArray. The advantage here is that you only have one instead of two arrays and that you can extend the number of rows you'd like to change without changing your code. Just extend the array.
The array $theArray does not need to be in a chronological order and you can give each ID independently of the other IDs a status.
You are executing the db() -> query($sql) in your code two times. This is not very efficient and redundant. Instead you can execute the command only once and immediately check whether it failed or not based on its return value inside the if().
The errorMsg I am creating in the code let you know which query failed so it gives you a more detailed information for debugging.
If you want to update multiple rows (in single query) using the INSERT syntax, you can do this:
REPLACE table(id,status) VALUES(1,1),(2,2),(3,3)
Notice that id must be Primary Key or Unique, otherwise the REPLACE will insert a new row.
Notice also that REPLACE isn't SQL standard, and works only in MySQL.

How to access an Arrays value by the value of another array

$query = "select Code , count(ListID) as nums from accesstable where Cust=" . $_SESSION ['Cust'] . " and App=" . $_SESSION ['App'] . " group by Code";
$result = mysql_query ( $query );
while ($row = mysql_fetch_array ( $result )){
$Codes[] = $row['Code'];
$Values[] = $row['nums'];
}
This is the structure of my code that I am trying to learn how to properly access... Here is my dilemma... I am trying to figure out how to explicitly find the associated count of nums dependent on the value of a Code.
Let me explain in better detail where my issue is....
Lets say the list of codes is
Code nums
1 624
7 825
571 450
9 393
2 739
9 590
The above code does successfully allow me to separate those values strictly into keys and values but I cannot figure out how to grab the nums value if the code is = to a certain value... I have currently been trying to declare a variable above the entire snippet of code and then declare it within the while statement but cannot figure out how to get the value to bind properly.... I will repaste the above code with one of my many failures in the while statement to give a better idea.
$Answer1 = 0;
$query = "select Code , count(ListID) as nums from accesstable where Cust=" . $_SESSION ['Cust'] . " and App=" . $_SESSION ['App'] . " group by Code";
$result = mysql_query ( $query );
while ($row = mysql_fetch_array ( $result )){
$Codes[] = $row['Code'];
$Values[] = $row['nums'];
($Codes == 1){
$Answer1 = // Right Here I want to Get the value 624 related to Code 1... Dont want to embarass myself with examples of what I have tried...
}
So how do I make a condition to output the value associated with a Code? I want to explicitly define these values as the list of codes can change with each customer... Luckily there are only a certain amount of codes so its not like I need to define too many of them... I just want to make sure I can get the nums value associated with a code and display it.
Hope I did a good job explaining this. :)
I'd do:
while ($row = mysql_fetch_array ( $result )){
$Codes[] = $row['Code'];
$Values[$row['Code']] = $row['nums'];
}
and, to access the value associated to a code:
$code = 1;
$value = $values[$code];
Since they would share the same array key, something like this would work-
if ($Codes[$key] == 1){
$Answer1 = $Values[$key];
}

Categories