...

View Full Version : Resolved Help Needed - Unexplainable Issue



Foxx
02-12-2010, 10:06 PM
Hey, this is my first post, I'm not great with PHP and I'm having a problem I cannot work out why is happening

Basically I'm using an SMF forum with an arcade and award system mod and I've wrote a script which ties them together so when a player gets a certain score it gives them an award and shows an iframe with a message informing them.

I put one simple rule in which shows up when the user logs in, which worked perfectly.
Then I added 2 more which were for games getting a score of above 1000 and 3000.
On my test account I got the score for the second game but the code did not run even though I ran the query through SQL and it showed results.
Then after getting the first score I was awarded both , but the code is set to show when ANY of the scores are met. I've checked many times and changed variables and things but nothing has worked.

Here is my code: (All DB connections and defining of $usr and $currentUser are done above).



//Award: Friend! - Log In. ;; 1 Point
//This award relies on the function above which exits the script before it executes if a guest is online.

//Check they already have the award.
$gottenFriend = mysql_num_rows(mysql_query("SELECT * FROM award_leaders WHERE id_member='$usr' AND award='Friend!'")) or die(mysql_error());

//If no, give them it.
if($gottenFriend == 0){
SWGiveAward("1","Friend!","Log in! (1P)");
//Insert the award to SMF.
mysql_query("INSERT INTO smf_awards (ID_AWARDED_MEMBER,title,givenDate,ID_MEMBER,memberName,filename) VALUES ('$currentUser','Friend!','$time','1','Foxx','$bronze_file')");
//Insert award into recordbase to avoid dupes
mysql_query("INSERT INTO award_leaders (id_member,award,points,date) VALUES ('$currentUser','Friend!','1','$now')");
//Update Leaderboard db with new points.
mysql_query("UPDATE leaderboard SET points=points+'1' WHERE member_id='$currentUser'");
}

//To be safe add new awards here.


//Award: Backwards Compatible - Score over 3000 in a single game of Space Invaiders ;; 25 Points

//Check they meet the requirements - 3000 points or more.
$invade_check = mysql_query("SELECT * FROM smf_arcade_scores WHERE id_game=32 AND id_member='$usr' AND score >=3000") or die(mysql_error());
$invade_check = mysql_num_rows($invade_check) or die(mysql_error());
//Check they haven't already gotten it
$gottenBack = mysql_num_rows(mysql_query("SELECT * FROM award_leaders WHERE id_member='$usr' AND award='Backwards Compatible'")) or die(mysql_error());

//If both conditions are good, show em the iframe and put the award into the database, along with scores.
if($invade_check > 0 AND $gottenBack == 0){
SWGiveAward("1","Backwards Compatible","Score over 3000 in a game of Space Invaders (25P)");
//Insert the award to SMF.
mysql_query("INSERT INTO smf_awards (ID_AWARDED_MEMBER,title,givenDate,ID_MEMBER,memberName,filename) VALUES ('$currentUser','Backwards Compatible','$time','1','Foxx','$bronze_file')");
//Insert award into recordbase to avoid dupes
mysql_query("INSERT INTO award_leaders (id_member,award,points,date) VALUES ('$currentUser','Backwards Compatible','25','$now')");
//Update Leaderboard db with new points.
mysql_query("UPDATE leaderboard SET points=points+'25' WHERE member_id='$currentUser'");
}



//Check they meet the requirements - 1000 points or more.
$l2f_check = mysql_query("SELECT * FROM smf_arcade_scores WHERE id_game=5 AND id_member='$usr' AND score >=1000");
$l2f_check = mysql_num_rows($l2f_check) or die(mysql_error());
//Check they haven't already gotten it
$gottenFly = mysql_num_rows(mysql_query("SELECT * FROM award_leaders WHERE id_member='$usr' AND award='Learn to Fly'"));

//If both conditions are good, show em the iframe and put the award into the database, along with scores.
if($l2f_check > 0 AND $gottenFly == 0){
SWGiveAward("1","Learn to Fly","Send a Penguin over 1000M on Bloodypingu (25P)");
//Insert the award to SMF.
mysql_query("INSERT INTO smf_awards (ID_AWARDED_MEMBER,title,givenDate,ID_MEMBER,memberName,filename) VALUES ('$currentUser','Learn to Fly','$time','1','Foxx','$bronze_file')");
//Insert award into recordbase to avoid dupes
mysql_query("INSERT INTO award_leaders (id_member,award,points,date) VALUES ('$currentUser','Learn to Fly','25','$now')");
//Update Leaderboard db with new points.
mysql_query("UPDATE leaderboard SET points=points+'25' WHERE member_id='$currentUser'");
}


From this the person has to have the first award to get the second, and the second to get the third but I do not want this to happen and I have no idea why or how to fix it :(

Sorry if the explanation is bad, I'm not sure how to explain the issue properly.

Fumigator
02-12-2010, 10:51 PM
I'm pretty sure your problem is the function stacking combined with the use of "or die" syntax.

Most people use this "or die" nonsense without knowing what it is actually saying, and you end up with problems such as yours. Please, indulge me...

In any PHP "if" statement, when there are two statements, such as "if (x or y)", PHP will evaluate the first statement, and decide if it should even bother checking the second statement before it actually checks it. So in the case of "if (x or y)", if "x" is true, the "y" statement is never run. If "x" is false, the "y" statement is run.

So, in the case of "if (mysql_query() or die())", the second statement, "die()", will only get run if the first statement, mysql_query(), returns false.

This is a really bizzare way to write logic. Here's a much better way to call mysql_query():



$result = mysql_query($query);
if (!$result) {
die();
}


Even better would be to return false instead of calling die(), but that's another lecture.

ALL THAT SAID, here's where your code is going wrong. You are stacking mysql_num_rows() and mysql_query(), and sticking an "or die()" at the end of it all. Well, your "or" has two statements, the mysql_num_rows(mysql_query()), and the "die()". Thing is, in PHP the value "0" is equal (==) to "FALSE", and therefore if the number of rows your query returns is ZERO, the function mysql_num_rows() will actually return false, and the "die()" gets run!

I strongly recommend you slow the roll of your code and avoid the function stacking, quit all that "or die()" business, and make your code flow like a nice malt liquor. Oh, and indent! Here's my style (note I've eliminated mysql_num_rows() by selecting a COUNT straight from the database):



$query = "SELECT COUNT(*) FROM award_leaders WHERE id_member='$usr' AND award='Friend!'";
$result = mysql_query($query);
if (!$result) {
die("Query error. Query is $query<br />Error is ".mysql_error());
}
$gottenFriend = mysql_result($result, 0, 0);
if ($gottenFriend == 0) {
//etc
};

Foxx
02-13-2010, 12:34 PM
I've changed what you said with all my code and everything works perfectly!


Thank you very much!



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum