Problem with php/ajax, a <select>, and a database

Ok. So my logic is that i have a <select><?php that inserts the options [client names] ?></select> and then a text box that displays the client id depending on the client they choose from the select. here is my code:

the code in the form:


<table id="form-wrapper">
<tr>
	<td>Client Name: <select name="clientname" onchange="showClient(this.value)">
<?php
///session_start();
$con = mysql_connect($_SESSION['dbhost'],$_SESSION['dbuser'],$_SESSION['dbpass']);
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }

mysql_select_db("c2_dj", $con);

$result = mysql_query("SELECT * FROM clients");

while($row = mysql_fetch_array($result))
  {
  echo "<option>" . $row['client_name'] . "</option>";
  }
mysql_close($con);
?> 	
	</select></td>
<!-- =============================================================================== -->
<script type="text/javascript">
function showClient(str)
{
if (str=="")
  {
  document.getElementById("client_id").innerHTML="";
  return;
  }
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    document.getElementById("client_id").innerHTML=xmlhttp.responseText;
    }
  }
xmlhttp.open("GET","cli-id.php?q="+str,true);
xmlhttp.send();
}
</script>
<!-- =============================================================================== -->
	<td id="client_id">Client ID: <input type="text" readonly="true" value="xxxx-xxxx-xxxx" /></td>
	</tr>
</table>

here is the code on cli-id.php


<?php
session_start();
$con = mysql_connect($_SESSION['dbhost'],$_SESSION['dbuser'],$_SESSION['dbpass']);
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }

mysql_select_db("c2_dj", $con);

$sql="SELECT * FROM clients WHERE id = '".$q."'";

$result = mysql_query($sql);

/// ;

while($row = mysql_fetch_array($result))
  {
  echo "Client ID: <input type=\\"text\\" readonly=\\"true\\" value=\\"" . $row['client_id'] . "\\"cliid\\" />";
  }

mysql_close($con);
?> 

Here Is My Problem. When I use it through my form, or enter …/cli-id.php?q=1, i get this error:

Notice: Undefined variable: q in /var/www/cge/ak/booking/new/cli-id.php on line 11 Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /var/www/cge/ak/booking/new/cli-id.php on line 17 

What Amm I Doing Wrong? Any Help would be greatly appreciated.

Thanks, JL Griffin

Here’s what’s happening:

Register Globals is off (as it should be) so the ?q=1 in the query string does NOT automatically become $q in the script. You need to access $_GET[‘q’]

That non-value is breaking your query, so mysql_query() will fail, and $result will be boolean false. That’s why your error message mentions that. Instead of $result being a resource, it’s bool false.

You need to use $_GET[‘q’]
You need to check that $_GET[‘q’] actually exists and very importantly you must ensure it’s an integer. You’re wide open to an SQL Injection attack right now.


if(isset($_GET['q'])) {
   $q = (int) $_GET['q'];

   $sql = "SELECT client_id FROM clients WHERE id = $q";
}

You need to check that $result actually worked (don’t just run mysql_fetch_array() assuming the query succeeded)

And you can tidy the echo statement a bit by using single quotes for your attributes that won’t need escaping


echo "Client ID: <input type='text' readonly='true' value='{$row['client_id']}' />";

@cranial-bore

Ok so i tried to do what you said, but im getting a new error now. Perhaps i havent inserted your code correctly. I apologise as im pretty new to using php/sql for stuff like this in the past the most ive used it for was login systems so im pretty new to this.
Either way, here is my new code:


<?php
session_start();
$con = mysql_connect($_SESSION['dbhost'],$_SESSION['dbuser'],$_SESSION['dbpass']);
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }
mysql_select_db("c2_dj", $con);

if(isset($_GET['q'])) {
   $q = (int) $_GET['q'];

   $sql = "SELECT client_id FROM clients WHERE id = $q";

$result = mysql_query($sql);
if(!isset($result)) 
{
echo "<B>ERROR! </B> $result did not succeed!";
}	
while($row = mysql_fetch_array($result))
  {
  echo "Client ID: <input type='text' readonly='true' value='{$row['client_id']}' />"; 
  }
mysql_close($con);
?> 

And here is the error im getting:

Parse error: syntax error, unexpected $end in /var/www/cge/ak/booking/new/cli-id.php on line 23 

you forgot an } at the end.


<?php
session_start();
$con = mysql_connect($_SESSION['dbhost'],$_SESSION['dbuser'],$_SESSION['dbpass']);
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }
mysql_select_db("c2_dj", $con);

if(isset($_GET['q'])) {
   $q = (int) $_GET['q'];

   $sql = "SELECT client_id FROM clients WHERE id = $q";

$result = mysql_query($sql);
if(!isset($result))
{
echo "<B>ERROR! </B> $result did not succeed!";
}
while($row = mysql_fetch_array($result))
  {
  echo "Client ID: <input type='text' readonly='true' value='{$row['client_id']}' />";
  }
mysql_close($con);
}
?>

You also should probably do this too:
$q = mysql_real_escape_string($q);

LOL. i should have known it would be something stupid like that… sometimes its the littlest things. lol thank you.

You are close; don’t check isset($result) though, because it will exist even if the query failed. Just use if() to test if it’s true-ish or false


<?php 
session_start(); 
$con = mysql_connect($_SESSION['dbhost'],$_SESSION['dbuser'],$_SESSION['dbpass']); 
if (!$con) 
{ 
	die('Could not connect: ' . mysql_error()); 
}
mysql_select_db("c2_dj", $con); 

//No q in query string
if( !isset($_GET['q']) ) {
	die('No client specified');
}


$q = (int) $_GET['q']; 
$sql = "SELECT client_id FROM clients WHERE id = $q"; 

//Failed Query
if( !$result = mysql_query($sql) )
{
	die("<b>ERROR!</b> Unable to query the database"); //don't put $result in this message, PHP will try to display it
}

//No matching client found (this is NOT a failed query)
if( mysql_num_rows($result) == 0 ) {
	die('No client matched your search');
}

while($row = mysql_fetch_array($result)) 
{ 
	echo "Client ID: <input type='text' readonly='true' value='{$row['client_id']}' />"; 
} 
?>

Now i am still getting same error:


Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /var/www/cge/ak/booking/new/cli-id.php on line 20 

With no other errors shown first?

echo $sql and see how it looks. Try executing it from PhpMyAdmin or similar, does it work?

Disregard the last comment. after using cranial-bore’s code, i get the

ERROR! unable to query database

Yeah sorry about that i didnt refresh to see if there were new comments before i posted that. now i just cant query database

Is the client_id field of your clients table an integer type (like TINYINT, SMALLINT, INT)?
If it’s a string (VARCHAR, TINYTEXT etc.) that query will fail.

Also, you can echo mysql_error($con) to help you debug. I left it out of my example because it’s better not to display those errors to your site users.

Yeah I’m pretty sure it’s int. I’ll double check through when I get home.

OK! i totally figured it out. it was really simple. lol. the php in the form was making the <option>s the valies in the field ‘client_name’ so when the script sent out the value of ‘q’ in tas sending ‘client_name’ and cli-id.php was trying to match up ‘client_name’ values in the ‘client_id’ fiel, which would account for the errors. ‘client_name’ is char(40) and client_id is int (i realized that because of what cranial-bore said about making sure the field was int.)

So here is what i changed:


$q = (int) $_GET['q']; 
$sql = "SELECT client_id FROM clients WHERE id = $q"; 

changed to:

$q = (int) $_GET['q']; 
$sql = "SELECT client_id FROM clients WHERE client_name = $q"; 

now the only problem is that when i select an option it gives me this as the output:

<td id="client_id">
Client ID: <input readonly="true" value="5" type="text">Client ID: <input readonly="true" value="4" type="text">Client ID: <input readonly="true" value="3" type="text">Client ID: <input readonly="true" value="2" type="text">Client ID: <input readonly="true" value="1" type="text">
</td>

that is a field for all the test clients in my database…

i have a feeling that this one will be much easier to solve though. here is my updated source for cli-id.php:


<?php 
session_start(); 
$con = mysql_connect($_SESSION['dbhost'],$_SESSION['dbuser'],$_SESSION['dbpass']); 
if (!$con) 
{ 
    die('Could not connect: ' . mysql_error()); 
}
mysql_select_db("c2_dj", $con); 

//No q in query string
if( !isset($_GET['q']) ) {
    die('No client specified');
}


$q = (int) $_GET['q']; 
$sql = "SELECT client_id FROM clients WHERE client_name = $q"; 

//Failed Query
if( !$result = mysql_query($sql) )
{
///	echo mysql_error($con);
///	echo "<BR>"
///   echo $q; ///Make sure the value transfered...
///   echo "<BR>"
	   die("<b>ERROR!</b> Unable to query the database (Sresult failed)"); //don't put $result in this message, PHP will try to display it
    
}

//No matching client found (this is NOT a failed query)
if( mysql_num_rows($result) == 0 ) {
    die('No client matched your search');
}

while($row = mysql_fetch_array($result)) 
{ 
    echo "Client ID: <input type='text' readonly='true' value='{$row['client_id']}' />"; 
} 
?>


Hope to hear from you soon :smiley:

JL Griffin

Remember earlier when I said:

You need to check that $_GET[‘q’] actually exists and very importantly you must ensure it’s an integer. You’re wide open to an SQL Injection attack right now.

and added $q = (int) $_GET[‘q’] to your code?
Well that forces $q to be an integer. You’re now dealing with a name (string), so turning it into 0 won’t help anymore.

This is also why I mention echoing $sql to see what it looks like to try and debug your script.

$q is now a string (could be better named too).
So:


//Remove the (int) line
$q = mysql_real_escape_string($_GET['q']);

//Notice '$q' is now in quotes, because it's a string. Before it was not
$sql = "SELECT client_id FROM clients WHERE client_name = '$q' LIMIT 1";

//Debug. Looks right? Works in PhpMyAdmin?
echo $sql;

Thank You! It’s Finally working!

Thank you all for all of your help (mainly cranial-bore. lol)

Have a great memorial day weekend everyone!

-JL Griffin