Never ending for() and while() loops - php

I'm really sorry if this has been asked before, I've looked as far as I could on here and none of the similar questions answer mine...
I'm trying to create a raffle of sorts... I have a database table of members and their entries and I'm trying to insert their names into another database table repeatedly for as many times as their individual entry amounts say.
Now I've looked up for() loops and as far as I can understand it, this attempt of my code should have worked:
$Amount = mysql_query("SELECT * FROM reapingbowl WHERE userid = $reapablef->id") or die(mysql_error());
$reapablef = mysql_query("SELECT * FROM members");
$reapablef = mysql_fetch_object($reapablef);
$amount = $reapablef->entries
for($e = 1; $e < $amount; $e++)
{
mysql_query("INSERT INTO reapingbowl (userid) VALUES ($reapablef->id)") or
die(mysql_error());
}
Wherein $amount is previously defined to pull the entry amounts from the database and $reapablef is previously defined to pull the specific user from the database table. The whole thing is wrapped in a while loop that works on one user at a time.
My problem is only that this for() loop never ends. It should, as far as I understand it, end after the amount of entries supersedes the $e value, but it just keeps going and I don't understand why... I have a similar problem with another for() loop and I don't understand why.
I tried a while loop as well with the coding being this:
$Amount = mysql_query("SELECT * FROM reapingbowl WHERE userid = $reapablef->id") or die(mysql_error());
while ($amount = mysql_num_rows($Amount), $amount < $ENTRIES)
{
mysql_query("INSERT INTO reapingbowl (userid) VALUES ('$reapablef->id')") or
die(mysql_error());
}
This does the same thing, just keeps going with entering the names neverendingly... I'm really sorry if I'm being stupid or something but please can someone help me figure out why?
Hope that's all the code necessary. All I really want to know is why the for() loop doesn't end ever... (I've tried it somewhere else with the limit of 10 and it still just went on forever)

My bet is, your $amount variable contains an object.
As PHP manual states, when using comparison operators, an object is always considered greater than a number.
In an alternate reality, PHP could throw a warning at you for doing silly comparisons, but for some reason in this universe of ours it doesn't.
It is well possible there is a simple explanation and/or a good reason for that, but right now I can't think of any.

Related

Random jump within while() loop in PHP for MySQL query

I am doing an example project for University and got a problem that I can't solve.
In general, the project is to create an automated pizza order system in PHP and MySQL on Apache. The system works through the following steps:
- Customer places order -> Baker receives order, proceeds -> Driver receives order at certain state, proceeds
- Customer can view order at all time through session
Now I hung up at the last step: The driver can see a page that has a table with the information that the baker worked with and passed on (all changes are on database side). The driver can only see a whole package (whenever all pizzas are marked as a certain status, also saved in DB).
For this, I have the following SQL statement
SELECT PizzaID, BestellungID, Adresse, PizzaName, Preis, Status FROM angebot, bestelltepizza, bestellung where bestellung.bestellungid = bestelltepizza.fbestellungid and angebot.PizzaName = bestelltepizza.fPizzaName and (select min(status) from bestelltepizza where bestellung.bestellungid = fbestellungid) >2 ORDER BY Status, BestellungID
Now, when I use var_dump() to get the mysqli_num_rows() output, I get no errors and the following output int 26. Compared to the database rows, it's the correct number. I fetch the sql:
while($row = mysqli_fetch_array($this->result)) {
var_dump(mysqli_num_rows($this->result));
var_dump($row);
...
}
Within the while() loop contains another query
$this->query = "SELECT fPizzaName FROM bestelltepizza WHERE fBestellungID = '$BestellID'";
var_dump($this->query);
$tmpResult = $this->_database->query($this->query);
$count = mysqli_num_rows($tmpResult);
Now here is the problem, the while() loop leaves out a random $BestellID which can contain x rows of data. But when I count the output of var_dump() everything is correct. However, var_dump($this->query); is not showing the query statement for the specific jump, too.
Any ideas what this could be? Full link to pastebin below.
To not extend this question to the fullest, I uploaded the whole code to pastebin here: http://pastebin.com/u888CPLw
Offtopic: Appreciate any help, thanks. If I failed clearing out my exact problem or if any questions pop up to my question, please comment and I will clarify. Thanks.
while($row = mysqli_fetch_array($this->result)) {
$count = mysqli_num_rows($tmpResult);
for($i = 0; $i < $count; $i++) {
$tmpVar = mysqli_fetch_array($this->result);
Ive snipped the code to show the problem
$count is based on $tmpResult you are then doing a fetch array on $this->result you should be doing it on $tmpResult
As Marc B says, Its a simple query to either inner join / left join on to the query. It would be better to use the join.

using mysqli_multi_query to set variables of data

I have just started to convert to mysqli due to the added security benefits. The main reason for converting to mysqli was the mysqli_multi_query function though. I had several long, complicated query's with a lot of JOINS in and when I found out about this function I thought I could make it simpler by breaking everything down into separate queries.
However, I have been unable to get the query to work as I want it to and the PHP manual isn't helping me.
Here's what I have so far;
$qry = "SELECT T.T_ID, T.name, T.pic, T.timestamp AS T_ts,
(SELECT COUNT(*) FROM track_plays WHERE T_ID = T.T_ID) AS plays,
(SELECT COUNT(*) FROM track_downloads WHERE T.T_ID = T_ID) AS downloads
FROM tracks T WHERE ID = '$ID';
";
$qry .= "SELECT S_ID, status, timestamp AS S_ts FROM status WHERE ID = '$ID';";
$qry .= "SELECT G_ID, gig_name, date_time, lineup, price, ticket, venue, G_pic, timestamp AS G_ts FROM gigs WHERE ID = '$ID'";
// Execute multi query
if (mysqli_multi_query($con,$qry)){
do {
// Store first result set
if ($result=mysqli_store_result($con)){
while ($row=mysqli_fetch_array($result)){
print_r($row);
}
}
}
while (mysqli_next_result($con));
}
This works fine and the array is printed as expected. However, i want to set a lot of variables for use later on. I won't list all of the variables but I have a few like this;
$S_ID = htmlspecialchars($row['S_ID']);
$T_ID = htmlspecialchars($row['T_ID']);
$G_ID = htmlspecialchars($row['G_ID']);
The variables are retrieved but due to the loop nature of the function PHP errors are given as well saying the $S_ID or $G_ID are undefined. $T_ID does not get an undefined error as it is the first query as is not looped over.
If you need any more information or I have not explained well enough just ask!
A while back ago i have had the same issues, and also for the same reason i have migrated from mysql to mysqli.
Sadly, it wasnt the best sollution for many cases, as i have realized on the way.
While implementing stuff with mysqli and multi query i still have had some issues that i had with mysql.
The solution i recommend, is to use views on your complicated querys.
it makes your coding and querys far less complicated.
I know it is not the answer you have been looking for, but give it a thought.
So far, every time I use a mysqli_multi_query, my do-while condition is:
while(mysqli_more_results($connection) && mysqli_next_result($connection));
You may like to replace your while statement and see if that helps.
If not, are you differentiating between each subsequent query when you are assigning these $S_ID, $G_ID variables? Are you inadvertently overwriting a variable with an empty $row[] value?
I also didn't see mysqli_free_result($result) in your code.
I'll even offer some error checking as a garnish.
preg_match_all("/(?:SELECT\s(.*?),\s.*?(?:;|$))/",$qry,$first_columnname);
if (mysqli_multi_query($con,$qry)){
do {
if ($result=mysqli_store_result($con)){
$query_identifier=array_shift($first_columnname[1]);
while ($row=mysqli_fetch_array($result)){
if($query_identifier)=="T.T_ID"){
//do something...
}elseif($query_identifier)=="S_ID"){
//do something...
}elseif($query_identifier)=="G_ID"){
//do something...
}
}
mysqli_free_result($result);
}
}
while(mysqli_more_results($con) && mysqli_next_result($con));
}
if($error_mess=mysqli_error($con)){echo "Error = $error_mess";}
Let me know if any of these small changes do the trick.

Querying inside of a for loop

I am wondering if there is a way to do what I am doing more efficiently. Right now, I have a class that retrives statuses from the database. It's pretty simple and shouldn't really effect performance all that much.
public function get ($var1, $var2, $var3)
{
$feed = array(); //Initialize an empty array
//Query the database
$Statement = $this->Database->prepare("SELECT id, name, excerpt, post, timestamp, tags, title FROM posts WHERE col1 = ? AND col2 = ? AND col3 = ? ORDER BY id DESC LIMIT 15");
$Statement->execute(array($var1, $var2, $var3));
while($row = $Statement->fetch(PDO::FETCH_ASSOC))
{
$posts[] = array( "id" => $row["id"], /*etc...*/ );
}
return $posts;
} //end get
And then my page set up something like this which I know is not efficient at all:
<?php for ($count = 1; $count <= $total; $count++): //Display the calendar
echo $count;
$feed = $Feed->get($count, $total, $var3);
foreach ($feed as $post):
echo $post["id"];
endforeach;
endfor; ?>
I hope that makes sense. There's a lot more html thrown in there and everything. Right now there are only 18 rows in my database, and it takes 10 seconds to load the page. Which is really bad. I have to set it up this way because of the design of the site. So the foreach loop has to be within the for loop because the whole thing is set up as a calendar.
My question is whether it would be more efficient to select all of the rows, save them outside of the for loop and then work with that array, or whether it's better to run each query inside the foreach loop the way I'm doing it now (i've read a lot, and know that most people say this is a huge no no). And what kind of issues would I run into if I used the former option and there were say a million rows in the database.
I hope that makes sense. I'll update the question if it doesn't. Right now though about 30 queries are being made to only access 1 or 2 rows. But the only other option I could come up with is selecting all of the rows in the table, and then working with that array, but if there are pretend 1 million rows in the db, I feel like that would affect performance a lot more.
Am I right, and what are some solutions? Thanks
I just want to point out that I did resolve the issue. If anyone is wondering why the foreach loop was querying so sow it was because I accidentally deleted a line where I connected to the Facebook api within the foreach loop every time to gather the poster's information. So if anyone ever stumbles upon this question, just to be sure I want to clarify that making many facebook->api calls is a bad thing. save the info in your database and query that instead.

Names for PHP query results and PHP loops.

This might be a simple question, but I can't find a definitive answer I can understand. I use PHP loops alot, I'm fairly new to PHP so they are usually simple like so:
<?php
$result = mssql_query("SELECT Price FROM Window_Extras WHERE ExtraID = '4' ");
while ($row = mssql_fetch_array($result)) {
?>
<a title="<?php echo $row['Colour']; ?>"></a>
<?php }?>
Is a really simple example, that doesn't make much sense, but I hope it shows how I use them. The question I wanted to ask was if $row and $result have to be named that for it to work, could they for example be named $priceresult and $pricerow?
This is because sometimes I would like to use multiple queries for a single loop, for example:
<?php
$result = mssql_query("SELECT Price FROM Extras WHERE ExtraID = '4' ");
$colourresult = mssql_query("SELECT ColourID FROM Colours WHERE Type = '8' ");
while ($row = mssql_fetch_array($result, $colourresult)) {
?>
This however didn't work, when I tried to echo out:
<?php echo $row['ColourID']; ?>
Can anyone tell me how I should be approaching this, and if I am at all on the correct track. Sorry if I havn't explained it very well.
To answer your first question:
Yes, you can use any variable name you like for the result and row variables. PHP doesn't care what you call them, and in fact it's perfectly possible to have several of them in use at any given time, in which case they obviously need to have different names.
You then followed up that question by asking why the following code doesn't work:
$result = mssql_query("SELECT Price FROM Extras WHERE ExtraID = '4' ");
$colourresult = mssql_query("SELECT ColourID FROM Colours WHERE Type = '8' ");
while ($row = mssql_fetch_array($result, $colourresult)) {
....
}
The reason for this is that the _fetch_array() function can only work with one set of results at a time. You would need to fetch a separate row array for each of them.
It's not clear what you're trying to do with these two queries, and why you would want to put them into the same loop together in the way you've shown.
I'm going to assume that the two queries are linked in some way that makes it logical for you to use them together like this? Perhaps the Extra item you're loading has a known Colour; ie you know that the Extra item numbered 4 is coloured with the Colour numbered 8?
Typically a program wouldn't be written with this knowledge; it would be part of the data. So in the Extras table, you would have a ColourID field, which would contain the value 8. The program would load the Extras record, see that the ColourID was set, and then load the matching Colours record according to what it saw.
Thus, your code could look something like this:
$result = mssql_query("SELECT Price FROM Extras WHERE ExtraID = '4' ");
while ($row = mssql_fetch_array($result)) {
$colourresult = mssql_query("SELECT ColourID FROM Colours WHERE Type = '".$row['colourID']."' ");
while ($row2 = mssql_fetch_array($result)) {
....
}
}
Inside the inner while loop, you could then access fields from either query, using $row or $row2 respectively (again, you can name these as you see fit).
However, that's not the end of the story, because SQL actually has the ability to merge these two queries into one without needing all that PHP code, using a thing call a SQL JOIN.
Now we can write a more complex query, but go back to having simpler PHP code:
$result = mssql_query("SELECT Extras.Price, Colours.ColourName FROM Extras WHERE ExtraID = '4' INNER JOIN Colours ON Colours.ColourID = Extras.ColourID");
while ($row = mssql_fetch_array($result)) {
....
}
If you're a beginner in PHP and SQL, these concepts are all probably new to you, so I advise trying them out, experimenting with them, and most importantly, reading a few (good quality) tutorials about them before proceeding much further.
Hope that helps. :)
(PS: as I said above, make sure you're reading good tutorials; beware of bad PHP examples and teaching sites -- there's a lot of them out there, teaching poor code and obsolete techniques; make sure you're reading something worthwhile. A good place to start might be http://phpmaster.com/)
This is because mssql_fetch_array can only take one result set. So removing $result and leaving $colourresult should work for you.
See: http://php.net/manual/en/function.mssql-fetch-array.php
Your variables ($...) can be called whatever you want, it's generally better to name them in a way that you can understand, hence most of the examples in the PHP Manual contain variables like $row, $result, $query, etc.
In terms of your database query, you can only pass one query to the mssql_query method. If you have data from different tables that you need to display, you should try and join the tables if possible using SQL rather than looping through multiple result sets.

php code, better way of grabbing sql data

I need to grab data from two tables, but I know theres a better, more tidier way to do this. Is it some kind of JOIN i need?
I'll show you my code and you'll see what I mean:
if ($rs[firearm] != "") {
$sql_result2 = mysql_query("SELECT * FROM db_firearms WHERE name='$rs[firearm]'", $db);
$rs2 = mysql_fetch_array($sql_result2);
$sql_result3 = mysql_query("SELECT * FROM items_firearms WHERE player='$id'", $db);
$rs3 = mysql_fetch_array($sql_result3);
if ($rs3[$rs2[shortname]] < 1) {
mysql_query("UPDATE mobsters SET firearm = '' WHERE id ='$id'");
}
}
This question is clear, but your code example has alot of formatting issues and I cannot give you direct answer, based on your example code.
The reason, why your example is unclear, is because.. with what are you going to join the tables? From one table you are selecting by name='$rs[firearm]' and from another by player='$id'. You have to provide the hidden data, like $rs and also $id.
You should definitely read these about mysql join and mysql left join. But I will try to give you an example based on your code, with fixed syntax. (Keep in mind, that I'm no mysql join expert, I did not test this code and also I do not know the joining conditions.) And also, the system structure is unclear.
As I understood, this what your tables do, correct?
mobsters - Users table
items_firearms - Links from users table to items table
db_firearms - Items table
So basically, my example does this: It will have preloaded $rs value, from the users table. It will check, if there is a entry inside the links table and hook the result with them items table. However, if the links table or even the items table can return multiple entries, then this doesn't work and you need to loop your results in much more smarter way.
// I can only assume, that $id is the ID of the player
$id = 2;
// Since I dont know the $rs value, then Im going to make some up
$rs = array(
'id' => 33,
'firearm' => 'famas'
);
if ($rs['firearm']) {
$result = mysql_fetch_array(mysql_query("SELECT ifa.*, dbfa.* FROM `items_firearms` AS `ifa` LEFT JOIN `db_firearms` AS `dbfa` ON `ifa.shortname` = `dbfa.shortname` WHERE `ifa.player` = '$id'"));
if ($result['id']) {
mysql_query("UPDATE `mobsters` SET `firearm` = '' WHERE `id` = '$id'", $db);
}
}
It is pretty clear, that you are new to PHP and mysql.. So I think you should probably edit your question and talk about your higher goal. Briefly mention, what your application are you building..? What are you trying to do with the mysql queries..? Maybe provide the table structure of your mysql tables..? I'm sure, that you will get your questions votes back to normal and also we can help you much better.
NOTES
You have to quote these types of variables: $rs[firearm] -> $rs['firearm']
If you want to check if your $rs['firearm'] equals something, then there is a better way then $rs[firearm] != "". The most simple is if ($rs['firearm']) {echo 'foo';}, but will produce a notice message, when all errors reporting mode. You can use isset() and empty(), but keep in mind, that isset() checks whether the variable has been set.. Meaning, even if its false, then it has been set. empty() reacts to undefined and empty variable the same, without any messages.
Also, "" means NULL, so if you even need to use "", then use NULL instead...much neater way..
I strongly recommend to use mysql class. You can understand the basics behind that idea from this answer. This is gonna make things much more easier for you. Also, mysql class is a must-have when dealing with dynamic applications.
if ($rs3[$rs2[shortname]] < 1) { .. makes no sense.. Do you want to check if the value is empty? Then (simple): if (!$rs3[$rs2[shortname]]) { .. and a very strict standard: if (empty($rs3[$rs2[shortname]])) { ..
Also you have to quote your sql queries, see my examples above.
Is the last mysql query missing $db?

Categories