automatic order id system check existence in mysql database - php

What I am trying to achieve is I have a systematic order generating system for my website I am just not able to check if the order id already exist if yes then it should increase the number by 1. heres my code end result
for e.g
Order ID: ABCD-00001 (already exist in db then)
New Order ID: ABCD-00002 (and so on...)
$i=0;
$n=1;
while ($i<10000) {
$j = sprintf("%'.05d\n", $n);
$orderid= "ABCD"."-".$j;
$query = mysql_query("SELECT * FROM `orders` WHERE jobid='".$orderid."'") or die (mysql_error());
$num_rows = mysql_num_rows($query);
if ($num_rows > 0) {
$i++; $n++;
} else { $jobid = $orderid;
break; }

Related

My for loop only allows one post to be displayed, over and over again

/* To sort the id and limit the post by 40 */
$sql = "SELECT * FROM requests";
$result = $conn->query($sql);
$sqlall= "SELECT * FROM requests ";
$resultall = $conn->query($sqlall);
$i = 0;
if ($result->num_rows > 0) {
// Output data of each row
$idarray= array();
while($row = $result->fetch_assoc()) {
echo "<br>";
// Create an array to store the
// id of the blogs
array_push($idarray,$row['id']);
}
}
else {
echo "0 results";
}
?>
<?php
for($x = 1; $x < 40; $x++) {
// This is the loop to display all the stored blog posts
if(isset($x)) {
$query = mysqli_query(
$conn,"SELECT * FROM `requests`");
$res = mysqli_fetch_array($query);
$email1 = $res['email1'];
$msg1= $res['msg1'];
$subject1 = $res['subject1'];
$name1 = $res['name1'];
$id = $res['id'];
the output is 40 cards reading data from the first row in my database. can anyone help?
I'm using xampp.
This code is to show the loop, but if anyone wants the full code is here
You are storing all the IDs in the array $idarray, but then you don't really use them properly. You loop over them, but you just run SELECT * FROM requests` 40 more times, and always extract the same first row. You never use the ID to change the query.
But it really makes no sense to run lots of separate queries anyway. If you just want the first 40 rows then use MySQL's LIMIT keyword. It usually works best when combined with ORDER BY as well. Something like this:
$sql = "SELECT * FROM requests ORDER BY id LIMIT 40";
$result = $conn->query($sql);
while ($res = $result->fetch_assoc()) {
$email1 = $res['email1'];
$msg1 = $res['msg1'];
$subject1 = $res['subject1'];
$name1 = $res['name1'];
$id = $res['id'];
//example output, just for demo:
echo $email1." ".$msg1." ".$subject1." ".$name1." ".$id;
}
Documentation: https://dev.mysql.com/doc/refman/8.0/en/limit-optimization.html

PHP check if ID already is in use

I am currently busy with creating my own 6 player game based on PHP/MySQL. I want to check if the ID from players_online is already in use, if yes then it need to keep searching until it found one (till max 6) else it need to return 0;
$con is the connection to the database and you can find the settings on the .mysql_config.php
This is what I got:
function find_local_id()
{
include'./mysql_config.php';
$i=1;
$select_id=mysqli_fetch_assoc(mysqli_query($con, "SELECT `ID` FROM `players_online` WHERE ID = ".$i.""));
if ($select_id["ID"] == $i) {
$i++;
$select_id=mysqli_fetch_assoc(mysqli_query($con, "SELECT `ID` FROM `players_online` WHERE ID = ".$i.""));
if ($select_id["ID"] == $i) {
$i++;
$select_id=mysqli_fetch_assoc(mysqli_query($con, "SELECT `ID` FROM `players_online` WHERE ID = ".$i.""));
if ($select_id["ID"] == $i) {
$i++;
$select_id=mysqli_fetch_assoc(mysqli_query($con, "SELECT `ID` FROM `players_online` WHERE ID = ".$i.""));
if ($select_id["ID"] == $i) {
$i++;
$select_id=mysqli_fetch_assoc(mysqli_query($con, "SELECT `ID` FROM `players_online` WHERE ID = ".$i.""));
if ($select_id["ID"] == $i) {
$i++;
$select_id=mysqli_fetch_assoc(mysqli_query($con, "SELECT `ID` FROM `players_online` WHERE ID = ".$i.""));
if ($select_id["ID"] == $i) {
return 0;
} else {
return 6;
}
} else {
return 5;
}
} else {
return 4;
}
} else {
return 3;
}
} else {
return 2;
}
} else {
return 1;
}
Is there a way to have this smaller/compact? Because I think this is pretty big for just a small function. :)
I think this would work:
function find_local_id()
{
include'./mysql_config.php';
$result = mysqli_query($con, "SELECT `ID` FROM `players_online`");
while($row = mysqli_fetch_assoc($result)) {
$ids[] = $row['ID'];
}
if($available = array_diff(range(0, 6), $ids)) {
return min($available);
}
return 0;
}
If you have mysqli_fetch_all use that.
Get all of the IDs in the table
See which ones (1-6) are not in the results
If any are available return the lowest one
If not return 0
First of all, you could use a loop to do this (but you don't need one).
You're hitting the DB many times unnecessarily.
Create a function or query (like the one below) that accepts one integer id and returns the count of rows.
<?php
$db = new PDO('mysql:host=localhost;dbname=yourdb', 'user', 'pass');
$id = ''; //input, whether it be a param from a function, session superglobal, GET or POST.
$exists = $db->prepare('SELECT id FROM players_online WHERE id = ?');
$exists->execute(array($id));
echo $exists->rowCount(); // if greater than 1 or equal, it exists.
You'd be far better off doing something like
$sql = "SELECT * FROM players_online WHERE id BETWEEN {$i} AND {$i}+6";
$stmt = mysqli_query($con, $sql) or die(mysqli_error($con));
$in_use = mysqli_num_rows($stmt);
If all 6 IDs are in the database, then you'll get 6 rows in $in_use. If 5 show up, then you'll get 5 rows, etc...
You seem to have a really flawed design in that you are never going to scale for more than one game at at time with this approach, are going to need to delete rows from your table to make it work when generating a new game, and are going to have problems with race conditions in cases where concurrency is high. But assuming you have a means for managing inserting player record id's in order (1,2,3, etc.). Your query can simply be:
SELECT MAX(id) FROM players_online
This will tell you the current highest id in the table. You would simply insert the next player with the id value incremented by 1 above the current max value.

How to populate an array from data in a table

I'm writing a very simple seating plan arranger for my sister. All it is, is a database with a list of people attending and each has a table number assigned ($tano)
My PHP is as follows:
$con = mysql_connect('localhost', $dbuser, $dbpass) or die(mysql_error());
$db = mysql_select_db($dbname, $con) or die(mysql_error());
// Get current table no
$tableno = $_GET["t"];
// Current table -> array
$t = array();
$i = 0;
$result = mysql_query('SELECT * FROM plan WHERE tano = $tableno ORDER BY fname');
while($row = mysql_fetch_array($result)) {
$t[$i] = $row;
$i++;
}
// Get other tables (Seats Remaining)
for ($i = 1; $i <= 40; $i++) {
$result = mysql_query("SELECT * FROM plan WHERE 'tano' = $i");
$seatsremaining = 10-mysql_num_rows($result);
if ($seatsremaining == 0) {$d[$i] = "Table ".$i." (No Seats Remaining)";}
else if ($seatsremaining == 1) {$d[$i] = "Table ".$i." (1 Seat Remaining)";}
else if ($seatsremaining >= 2) {$d[$i] = "Table ".$i." (".$seatsremaining." Seats Remaining)";}
}
?>
You can see the rest of the HTML code on www.greenbottleblue.com
The array is not populated and there's an annoying SQL error:
Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /home/greenbot/public_html/index.php on line 18
The table structure is:
In your first query, you are missing quotes around your value:
$result = mysql_query('SELECT * FROM plan WHERE tano = $tableno ORDER BY fname');
This should be:
$result = mysql_query("SELECT * FROM plan WHERE tano = '$tableno' ORDER BY fname");
In your second query, you are using quotes instead of backticks around the column name:
$result = mysql_query("SELECT * FROM plan WHERE 'tano' = $i");
This should be:
$result = mysql_query("SELECT * FROM plan WHERE `tano` = $i");
You should note that your code assumes that the query completed successfully instead of checking. For debugging purposes, you can add:
... or die(mysql_error());
to the end of each of your mysql_query(...) statements to get details about the attempted queries. You should develop a logging strategy for such errors in production code.
Additionally, be aware that using unfiltered user input $tableno = $_GET["t"]; opens the door for SQL injection attacks. Consider updating your code to use parameterized PDO queries, or at least filter your incoming data.

Prevent two calls to the same script from selecting the same mysql row

The below script is called every 5 seconds. The issue is that if the server is responding slow, one entry in "blog" can get selected twice in a row because the server hasn't had time to set "done" to "1" yet. Is there an industry standard (or whatever you call it) way to prevent this from happening?
$result = mysql_query("SELECT * FROM blogs WHERE done=0 LIMIT 1");
$rows = mysql_num_rows($result); //If there are no entries in with done set to 0, that means we've done them all; reset all entries to 0.
if($rows == 0)
{
mysql_query("UPDATE blogs SET done=0 WHERE done=1");
}
else
{
while($row = mysql_fetch_array($result))
{
mysql_query("UPDATE blogs SET done=1 WHERE id=$row[id]");
// Do stuff
}
}
I think I could change it to
while($row = mysql_fetch_array($result))
{
if($row['done'] == 1){ die; }
mysql_query("UPDATE blogs SET done=1 WHERE id=$row[id]");
//Do stuff
}
But will that really fix the problem? I would imagine there would be a better way that really prevents it from happening without a shadow of a doubt.
I think the best way to prevent selecting the same row is using SELECT GET_LOCK("lock_name"); and SELECT RELEASE_LOCK("lock_name");. When you get a lock from mysql server, other processing trying to get a lock will wait for the lock to be released. Below is a sample implementation:
<?php
function getLock($lockName, $dbc) {
$query = "SELECT GET_LOCK('".$lockName."', 0)";
$result = mysql_query($query, $dbc);
$lockResult = mysql_fetch_row($result);
$lockResult = $lockResult[0];
return $lockResult == 1 ? true : false;
}
function releaseLock($lockName, $dbc) {
$query = "SELECT RELEASE_LOCK('".$lockName."')";
$result = mysql_query($query, $dbc);
}
// CONNECT TO DATABASE
$dbc = mysql_connect('localhost', 'root', '');
mysql_select_db('test', $dbc);
$loopQueue = true;
$rowsProcessed = 0;
// MAIN QUEUE LOOP
while ($loopQueue) {
// TRY UNTIL GETTING A LOCK
$queueLockName = 'queue_lock_1';
while (getLock($queueLockName, $dbc) === true) {
// WE GOT THE LOCK, GET A QUEUE ROW WITH PENDING STATUS
$query = 'SELECT * FROM test WHERE status = 0 ORDER BY ID ASC LIMIT 1';
$result = mysql_query($query, $dbc);
if (mysql_num_rows($result) < 1) {
// SINCE WE DON"T HAVE ANY QUEUE ROWS, RELEASE THE LOCK
releaseLock($queueLockName, $dbc);
// WE DONT NEED TO LOOP THE MAIN QUEUE ANYMORE SINCE WE DONT HAVE ANY QUEUE ROWS PENDING
$loopQueue = false;
// BREAK THIS LOOP
break;
}
// WE GOT THE QUEUE ROW, CONVERT IT TO ARRAY
$queueRowArray = mysql_fetch_assoc($result);
// UPDATE QUEUE ROW STATUS TO SENDING
$query = 'UPDATE test SET status = 1 WHERE id = '.$queueRowArray['id'];
mysql_query($query);
// RELEASE THE LOCK SO OTHER JOBS CAN GET QUEUE ROWS
releaseLock($queueLockName, $dbc);
// DO STUFF ...
// UPDATE QUEUE ROW STATUS TO PROCESSED
$query = 'UPDATE test SET status = 2 WHERE id = '.$queueRowArray['id'];
mysql_query($query);
$rowsProcessed++;
}
}
echo "\n\n".'process finished ('.$rowsProcessed.')'."\n\n";
I would have given a go to transactions. Here is an example in another StackOverflow question
Just a question: What happens if the server is even slower? For instance, the select statament takes so long (e.g. 5 seconds) that once it finishes (returning 0 rows), the new select is executed (returning 1 or more rows)
MySQL documentation
$result = mysql_query("SELECT * FROM blogs WHERE done=0 LIMIT 1");
$rows = mysql_num_rows($result); //If there are no entries in with done set to 0, that means we've done them all; reset all entries to 0.
if($rows == 0)
{
mysql_query("UPDATE blogs SET done=0 WHERE done=1");
}
else
{
while($row = mysql_fetch_array($result))
{
mysql_query("UPDATE blogs SET done=1 WHERE id=$row[id] AND done=0");
if(mysql_affected_rows() != 1)
die();
// Do stuff
}
}

in array sql query

I have the following inside a foreach loop (displaying my various videos), I'm trying to display some alternate text for the top three voted videos. What on earth am I doing wrong (a lot clearly)...
$sql = "SELECT video_id FROM videos WHERE displayable='y' ORDER BY votes desc LIMIT 0,3";
$result = mysql_query($sql);
$row = #mysql_fetch_array($result);
if(in_array($video->getProperty('video_id')) == $row['video_id']) {
do this...
} else {
do this..
}
Firstly replace your code with some error preventing techniques like so!
$sql = "SELECT video_id FROM videos WHERE displayable='y' ORDER BY votes desc LIMIT 0,3";
if(false != ($result = mysql_query($sql))
{
$row = mysql_fetch_assoc($result); //Dont need the # restraint as the result is not false above.
//Also to get associate keys you need to use mysql_fetch_assoc
if($video->getProperty('video_id') == $row['video_id'])) //Remove the in array as your directly comparing the to entities with ==
{
//Match
}else
{
//Video does not match
}
}
Your main problem was the mysql_fetch_array(), Please research the differences with mysql_fetch_array() and mysql_fetch_assoc();
--
Edit: The way i would go
//Change the query and the loop way.
$sql = "SELECT video_id FROM videos WHERE displayable='y' AND video_id != '".(int)$video->getProperty('video_id')."' ORDER BY votes desc LIMIT 0,3";
if(false != ($result = mysql_query($sql))
//Use the # restraint if you have E_NOTICE on within E_Reporting
{
while($row = mysql_fetch_assoc($result))
{
//Print the $row here how you wish for it to be displayed
}
}else
{
//We have an error?
echo '<strong>Unable to list top rated videos, please check back later.</strong>'
}
}
mysql_fetch_array only returns a single row, you need to loop through your results to build an array containing the top three ids.
$sql = "SELECT video_id FROM videos WHERE displayable='y' ORDER BY votes desc LIMIT 0,3";
$result = mysql_query($sql);
while($row = #mysql_fetch_array($result)) {
$topthree[] = $row["video_id"];
}
Then you can use in_array but with the correct syntax:
if(in_array($video->getProperty('video_id'), $topthree)) {
do this...
} else {
do this..
}

Categories