Getting answers from a database - php

I am making an online test script where you can input the answers in the input elements. Once the test is submitted I want the database's answers to be compared with the inputted answers to say whether it is wrong or not, however the script I am using is not working! :S
Here is the problem!
In the database, I have 4 out of 50 ready answers set (not all yet) when I answer both 4 correct or wrong it returns them being incorrect. It lists all the answers, whether they're correct or incorrect in the page but it's not working correctly, no matter what inputs I do, it all the answers up to 49 say incorrect, then for some reason 50 says correct?...
Here is my script:
<?php
$con=mysqli_connect("localhost","dstsbsse","pass","user");
if (mysqli_connect_errno($con))
{
echo "ERROR - Failed to connect to MySQL Server. Please contact an Administrator at English In York: " . mysqli_connect_error();
}
//Set variables to hold output data and total score.
$output="";
$score=0;
//for-next loop. This means "Set n to value one. Every time through the loop (between {}) increase n by one. Do this while n is less than or equal to 50"
for($n=1;$n<=50;$n++)
{
$sql="SELECT a$n FROM answer WHERE 1";
// $sql="SELECT * FROM answer WHERE name='a$n'"; //sql is specific to your table of course - you will need to change this.
$result = $con->query($sql); // perform the query
$row = $result->fetch_assoc(); //load the result into the array $row
$key="a".$n; //concatenate to generate the $_POST keys
if($row['answer']==$_POST[$key]) //compare the data from the table with the answer
{
//answer is correct
$score++;
$output.="Answer $n is correct</BR>"; //add responses to the output string
}
else
{
$output.="Answer $n is incorrect</BR>";
}
}
$output.="Total score: $score/50"; //add the score
echo $output; //echo to screen.
Here is an example of one of the questions answer boxes:
<input type="text" name="a1" id="a1" required>
How can I fix this?

Fetching a query like:
SELECT a1 FROM answer
would return $row['a1'], instead of $row['answer']
So you should be using the column name, not the table one

Related

PHP: Running if and else if inside a while loop?

I'm trying to run if and else if inside a while loop in my PHP code.
The code looks like this:
<?php
$sql = "SELECT * FROM table ORDER BY id";
$query = mysqli_query($db_conx, $sql);
$productCount = mysqli_num_rows($query);
if ($productCount > 0) {
while($row = mysqli_fetch_array($query, MYSQLI_ASSOC)){
$deviceType = $row["deviceType"];
if($deviceType == 'iPhone' || $deviceType == 'iPad'){
echo 'IOS';
}else if($deviceType == 'Android'){
echo 'Android';
}
}
} else {
}
?>
The code above works (sort of) but not as I was expecting it.
To give you an example, lets say I have 2 rows in MYSQL database.
like this:
id deviceType
1 Android
2 iPhone
when i run my PHP code above, I get this echo-ed on my page:
IOS
IOS
Android
Android
BUT I only have 2 rows in the database so the result should be:
IOS
Android
Could someone please advise on this issue?
This question is clearly misrepresenting your actual code/data.
When your database table has 2 rows, but you are receiving 4 rows then the onus is not on the fetching function, but on your query or database table data.
If your actual query is as posted in your question, then your table data contains more than two rows.
If your actual query is different from what you posted (say, joining the table with a copy of itself), then your data is fine and your query is failing you.
Regardless of if you are using mysqli_fetch_array($result), mysqli_fetch_array($result,MYSQLI_ASSOC), or mysqli_fetch_assoc($result), your while() loop will only do one iteration for each row of data.
The difference in resultset fetching functions:
mysqli_fetch_array($result):
array(0=>'1', 'id'=>'1', 1=>'Android', 'deviceType'=>'Android') // 1 row w/ 4 elements
array(0=>'2', 'id'=>'2', 1=>'iPhone', 'deviceType'=>'iPhone') // 1 row w/ 4 elements
mysqli_fetch_array($result,MYSQLI_ASSOC), or mysqli_fetch_assoc($result):
array('id'=>'1', 'deviceType'=>'Android') // 1 row w/ 2 elements
array('id'=>'2', 'deviceType'=>'iPhone') // 1 row w/ 2 elements
I will rewrite your code and implement some good practices:
if($result=mysqli_query($db_conx,"SELECT `deviceType` FROM `table` ORDER BY `id`;")){
if(mysqli_num_rows($result)){
while($row=mysqli_fetch_assoc($result)){
echo ($row["deviceType"]=="Android"?"Android":"IOS"); // inline condition is a personal preference
}
}else{
echo "No rows in `table`.";
}
}
Only bother declaring a variable if you will use its value more than once (*or if it dramatically improves readability to separate it from its single use.)
So that your variable names are intuitive, name your query variable $sql or $query; and name your query's result variable $result.
Only SELECT columns that you intend to use; * is unnecessary for your case.
Backtick ` wrapping is not required on column and table names, but doing so will avoid any potential clashes with MySQL keywords.
Perform a conditional check and declare the $result variable as false or [resultset] in a single step.
Always check that $result is true before calling any functions that access the resultset. (e.g. mysqli_num_rows() and mysqli_fetch_assoc()).
if(mysqli_num_rows($result)){ will check for a non-falsey value -- I mean 0 equates to false and anything greater than 0 will be true.
Your code appears to be perfectly fine. However, instead of the expected output, you get more items than needed. If I am not mistaken, this means that you have duplicate deviceType in your database table. $productCount probably has a value of 4. You can get two values if you use this query instead:
SELECT DISTINCT `deviceType` FROM `table` ORDER BY `id`
but while this should fix the output you get, your data will still hold duplicates, so you might want to look into the data of your table and into the way it was created, find out and fix the problem.
the answer is very simple you are fetching the results twice with the while loop change this line
while($row = mysqli_fetch_array($query, MYSQLI_ASSOC)){
to
while($row = mysqli_fetch_assoc($query)){
then it will work right, you can see buy the order iPhone iPhone android android that is doing it twice instead of once per loop

php mysql issue with check if record exist before insert

I'm having a little problem with the codes given below. When I'm using the name="staff_number[]" then it insert the record with everything ok even if it is already in the database table and when i use name="staff_number" it does check the record and also give me alert box but when insert the record if it is not in the database it stores only the first number of the staff number like the staff no is 12345 it stores only 1. can anyone help in this record i think there is only a minor issue what I'm not able to sort out.
PHP Code:
<select placeholder='Select' style="width:912px;" name="staff_number[]" multiple />
<?php
$query="SELECT * FROM staff";
$resulti=mysql_query($query);
while ($row=mysql_fetch_array($result)) { ?>
<option value="<?php echo $row['staff_no']?>"><?php echo $row['staff_name']?></option>
<?php } ?>
</select>
Mysql Code:
$prtCheck = $_POST['staff_number'];
$resultsa = mysql_query("SELECT * FROM staff where staff_no ='$prtCheck' ");
$num_rows = mysql_num_rows($resultsa);
if ($num_rows > 0) {
echo "<script>alert('Staff No $prtCheck Has Already Been Declared As CDP');</script>";
$msg=urlencode("Selected Staff ".$_POST['st_nona']." Already Been Declared As CDP");
echo'<script>location.href = "cdp_staff.php?msg='.$msg.'";</script>';
}
Insert Query
$st_nonas = $_POST['st_nona'];
$t_result = $_POST['st_date'];
$p_result = $_POST['remarks'];
$arrayResult = explode(',', $t_result[0]);
$prrayResult = explode(',', $p_result[0]); $arrayStnona = $st_nonas;
$countStnona = count($arrayStnona);
for ($i = 0; $i < $countStnona; $i++) {
$_stnona = $arrayStnona[$i];
$_result = $arrayResult[$i];
$_presult = $prrayResult[$i];
mysql_query("INSERT INTO staff(st_no,date,remarks)
VALUES ('".$_stnona."', '".$_result."', '".$_presult."')");
$msg=urlencode("CDP Staff Has Been Added Successfully");
echo'<script>location.href = "cdp_staff.php?msg='.$msg.'";</script>';
}
Your $_POST['staff_number'] is actually an array.
So you have to access it like $_POST['staff_number'][0] here, 0 is a index number.
If the name of select is staff_number[] then $prtCheck will be a array so your check query must be in a loop to make sure your check condition.
if the name is staff_number then the below code is fine.
The answer of amit is right but I will complete it.
Your HTML form give to your PHP an array due to the use of staff_number[] with [] that it seems legit with the "multiple" attribute.
So you have to loop on the given values, you do it with a for and a lot of useless variables without really checking it. From a long time, we have the FOREACH loop structure.
I could help you more if i know what is the 'st_nona', st_date' and 'remarks' values.
According to your question you are getting difficulty in storing the data. This question is related to $_POST array.
Like your question we have selected following ids from the select : 1,2,3,4
It is only storing 1.
This is due to you have not used the loop when inserting the data.
Like below:
<?php
foreach($_POST['staffnumber'] as $staffnumber){
$query=mysql_query("select * from staff where staff_number =".$staffnumber);
if(mysql_num_rows($query)>0){
//action you want to perform
}else{
//action you want to perform like entering records etc. as your wish
}
}
?>
And I would like to suggest you that use the unique keys in database for field and use PHP PDO for database, as it is secure and best for OOPs.
Let me know if you have any queries.

Check if no result found in mysql db [duplicate]

This question already has answers here:
Checking if mysqli_query returned any values?
(2 answers)
Closed 4 months ago.
I wrote a php search for a table in mysqli and it works fine but i want to show the correct message to user if no result were found.
here is my current code:
$search_string=$_GET["design"];
$connect= mysqli_connect("mysql.myhost.com","abc","123456","mydb_db");
$query="select * from product where product_design like '%$search_string%'";
$rows= #mysqli_query($connect,$query) or die("Error: ".mysqli_error($connect));
if ($rows!=null)//I put this if to check if there is any result or not but its not working
{
while(($record=mysqli_fetch_row($rows))!=null)
{
.
.//i have working code for showing the result here
.
}
mysqli_close($connect);
}
else{
echo"no result found";
}
could you please help me what is wrong , even when i search for something which is not exist in the db still the program not displaying "no result found"
Thank you
What you need is mysqli_num_rows specifically the mysqli_result::num_rows bit. This adds a num_rows property to mysqli result sets. This means you can do
$rowCount = $rows->num_rows
There's also a non-OO equivalent ...
$rowCount = mysqli_num_rows($rows);
(The difference is purely one of coding style)
Use one of these to determine how many records are returned and output the appropriate messages.
The following line doesn't make sense, that might be the issue.
while(($record=mysqli_fetch_row($rows))!=null)
However, $row wouldn't return 'null' if it was empty, but be not set. Do it like this:
if ($rows) { echo 'works';} else { echo 'no rows'; }

Why is my database not being updated when someone visits my website?

For some reason when a user comes to my site to play multiplayer the call to the php file is sent, but the database never adds a new player or updates their information.
php file is called with the following line of code from a javascript file:
xmlhttp.open('GET',"xml_http_request.php?mod0="+truckHeading+"&mod1="+newhtr[1]+"&mod2="+absRoll+"&lla0="+lla[0]+"&lla1="+lla[1]+"&lla2="+lla[2]+"&pid="+rCC+"&rangeCheck="+rangeCheck+"&ranger="+ranger+"&namely="+namely+"&message="+message+"&unLoader=false", true);
Here's the php code:
<?php
require("db1.php"); //for using live public database
//require("db.php"); //for using local database
$inserter=0;
//assign pid if have not already
$pid=$_GET['pid'];
if($pid=='false'){
$inserter=1;
$query="SELECT id FROM positioner";
$result=mysql_query($query);
$num_rows=mysql_num_rows($result);
$i=1;
while($row=#mysql_fetch_assoc($result)){
if($i!=$row['id']){ $pid=$i;break; } //take first available id
$i++;
}
if($pid=='false'){ $pid=$num_rows+1; } //if no hole in id list, take next one higher
mysql_free_result($result);
}
$unLoader=$_GET['unLoader'];
if($unLoader=='true'){
$ddb=dbq("DELETE FROM positioner WHERE id = '".$pid."' LIMIT 1;");
}else{
$dbMi=$_GET['dbMi'];
$mod0=$_GET['mod0'];
$mod1=$_GET['mod1'];
$mod2=$_GET['mod2'];
$lla0=$_GET['lla0'];
$lla1=$_GET['lla1'];
$lla2=$_GET['lla2'];
$rangeCheck=$_GET['rangeCheck'];
$namely=addslashes($_GET['namely']);
if($namely==''){ $namely='x'; }
$message=addslashes($_GET['message']);
$rangeCheck='true';
//only check range every x number of ticks (50, ~3 seconds)?
// , $rangeCheck is true first time
if($rangeCheck=='true'){
$ranger=array();
//get lat lon of all for determining who is in range
$query="SELECT id, lla0, lla1 FROM positioner WHERE id != '".$pid."' ";
$result=mysql_query($query);
//if distance < 10000, put id in ranger array
while($row=#mysql_fetch_assoc($result)){
//leave rangeCheck off for now
//$di=dister($row['lla0'],$row['lla1'],$lla0,$lla1);
//if($di<10000){
$ranger[]=$row['id'];
//}
}
mysql_free_result($result);
if(count($ranger)==0){
$rangerS='';
}else{
$rangerS=implode(",", $ranger);
}
//between rangeChecks get ranger array from js
}else{
$rangerS=$_GET['ranger']; // $rangerS: string(for inserting)
$ranger=explode(",",$rangerS); // $ranger: array(for looping)
}
//insert new row first time
if($inserter==1){
$idb=dbq("INSERT positioner (id,mod0,mod1,mod2,lla0,lla1,lla2,ranger,namely,message,model)
VALUES ('".$pid."', '".$mod0."', '".$mod1."', '".$mod2."', '".$lla0."', '".$lla1."', '".$lla2."', '".$rangerS."', '".$namely."', '".$message."', '".$dbMi."');");
}else{
//update the database with current model data and result of range check
$udb=dbq("UPDATE positioner SET mod0 = '".$mod0."', mod1 = '".$mod1."', mod2 = '".$mod2."', lla0 = '".$lla0."', lla1 = '".$lla1."', lla2 = '".$lla2."', ranger = '".$rangerS."', namely = '".$namely."', message = '".$message."', model = '".$dbMi."' WHERE id = '".$pid."' LIMIT 1;");
}
header("Content-type: text/xml");
echo '<markers>';
echo '<marker ranger="'.$rangerS.'" pid="'.$pid.'" />';
//loop through a number of times equal to number of id's in ranger array
foreach($ranger as $rang){
$query="SELECT mod0, mod1, mod2, lla0, lla1, lla2, namely, message, model FROM positioner WHERE id = '".$rang."' ";
$result=mysql_query($query);
while ($row=#mysql_fetch_assoc($result)){
echo '<marker mod0="'.$row['mod0'].'" />';
echo '<marker mod1="'.$row['mod1'].'" />';
echo '<marker mod2="'.$row['mod2'].'" />';
echo '<marker lla0="'.$row['lla0'].'" />';
echo '<marker lla1="'.$row['lla1'].'" />';
echo '<marker lla2="'.$row['lla2'].'" />';
echo '<marker namely="'.rawurlencode(stripslashes($row['namely'])).'" />';
echo '<marker message="'.rawurlencode(stripslashes($row['message'])).'" />';
echo '<marker dbMi="'.$row['model'].'" />';
}
}
echo '</markers>';
} //end if unLoader
//function for calculating distance between latlon pairs, for range check
/* not necessary for only a few visitors
function dister($lat1,$lon1,$lat2,$lon2){
$R=6378100;
$lat1*=pi()/180;
$lon1*=pi()/180;
$lat2*=pi()/180;
$lon2*=pi()/180;
$dLat=$lat2-$lat1;
$dLon=$lon2-$lon1;
$a=sin($dLat/2)*sin($dLat/2)
+cos($lat1)*cos($lat2)*
sin($dLon/2)*sin($dLon/2);
$c=2*atan2(sqrt($a),sqrt(1-$a));
$di=$R*$c;
$di=round($di,6);
return $di;
}
*/
?>
Some notes.
The "assign pid if have not already" block is tragic. You're grabbing the entire contents of the table, and then row-by-row checking to see if you found the right one. The code blindly assumes that the row count is going to match the id column when picking what the next pid should be. The proper thing to do (for MySQL) would be using an auto-increment column so that you don't need to worry about that mess.
Your DELETE FROM query contains an SQL Injection vulnerability. If pid is not the string 'false', it will never be validated. Someone can destroy the entire positioner table. How do you protect against it? Well...
You're using addslashes. This isn't a code smell, it's a code stench. addslashes has never, ever at any time in the entire history of computing been the correct thing to use*. I think you're looking for a real database escaping mechanism. Because you're using the atrocious "mysql" interface, you want mysql_real_escape_string.
lla1 and lla2? Those are the best and most descriptive names for columns you could come up with? I'm going to assume those are latitude/longitude pairs.
Once again, you have SQL injection in that SELECT.
And in that INSERT, you are possibly blindly trusting $rangerS. SQL Injection ahoy!
And in the UPDATE.
I'd also like to rant briefly about string 'true' and string 'false', but those are coming from bad Javascript. Consider having them submitted as 1 and 0 instead. Also, please, please consider using a modern Javascript library like jQuery instead of rolling your own Ajax bits. It will save you time and stress.
I think the core problem here is actually the initial pid check. I'm going to bet that you're always getting a new or incorrect pid back from the table, because the id is unlikely to perfectly match the row count. Then you're doing a blind no-error-check INSERT with the "new" pid, but if your indexes are designed properly, this will fail with a duplicate key error. Therefore, no updates. But this is just speculation. Other than the vulnerabilities here, I'm not sure I completely understand what's happening, and I'm not spotting anything obviously incorrect.
There's another possible problem here. I'm going to assume that pid means player ID from the context. Your code is blindly trusting that the request is coming from the player that owns that pid, but anyone can just make a request here with any valid pid and make moves for people as a result. I'm not sure you intended that.
* Okay, maybe someone found addslashes useful once or twice...

PHP Mysql Update issue

I'm having an issue that I can't quite figure out. I have a bit of code that allows a user to pick, let's say, which type of fruit is their favourite. If they've previously selected 'apples' as their favourite and want to change it to 'oranges' - the script performs well.
But if they select 'apples' when they've already selected 'apples' the MYSQL Update call breaks down and returns an error. It's like it won't write over itself with the same data, that the new value has to be unique. I'm at a loss.... Here's the update bit:
// UPDATE THEIR FRUIT SELECTION...
$q = "UPDATE account SET fav_fruit='" . $row['fruit'] . "' WHERE act_id=$act_id LIMIT 1";
$r = #mysqli_query ($dbc, $q);
if (mysqli_affected_rows($dbc) == 1) { // If it ran OK.
echo 'success!';
} else {
echo 'oops!';
}
Again, this works so long as the new selection and what's in the database aren't the same. If they are: I get the oops! error.
Why would you need to update a field to contain a value it already contains?
Regardless, this can be fixed by altering the table structure. You need to remove the unique flag from the fav_fruit column.

Categories