using form variables for mysql query - php

I'm trying to fetch a result from a mysql table using two form variables namely $sessionID and $semesterID. I used the following code and it seems to have an error in the sql syntax
<?php
...
mysql_select_db($database_connChePortal, $connChePortal);
$query_rsRegcourses =sprintf("SELECT * FROM VW_reg vwr WHERE vwr.sessionID=%s AND vwr.semesterID=%s",$sessionID,$semesterID);
$rsRegcourses = mysql_query($query_rsRegcourses, $connChePortal) or die(mysql_error());
$row_rsRegcourses = mysql_fetch_assoc($rsRegcourses);
$totalRows_rsRegcourses = mysql_num_rows($rsRegcourses);
print_r($query_rsRegcourses); die;
...
?>
I tried running the query and I have the following error report
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AND vwr.semesterID=' at line 1
thanks

I think you should surround your variable with single quotes '' please change as follow
"SELECT * FROM VW_reg vwr WHERE vwr.sessionID='%s' AND vwr.semesterID='%s'"

Put the %s in single quotes like this
"SELECT * FROM VW_reg vwr WHERE vwr.sessionID='%s' AND vwr.semesterID='%s'",$sessionID,$semesterID);

To insert a variable into query, you have to properly format it.
Two other answers contains improper formatting - so, you shouldn't follow them.
To make formatting more handy, you have to encapsulate sprintf() into function like this:
function paraQuery()
{
$args = func_get_args();
$query = array_shift($args);
$query = str_replace("%s","'%s'",$query);
foreach ($args as $key => $val)
{
$args[$key] = mysql_real_escape_string($val);
}
$query = vsprintf($query, $args);
$result = mysql_query($query);
if (!$result)
{
throw new Exception(mysql_error()." [$query]");
}
return $result;
}
which would apply proper formatting and also will handle errors
Also note that your way of counting records is extremely inefficient and may cause server to hang. You have to query the only data you need. So, if you need only count - request the count only
so, the code would be
mysql_select_db($database_connChePortal, $connChePortal);
$sql = "SELECT count(*) FROM VW_reg vwr WHERE vwr.sessionID=%s AND vwr.semesterID=%s";
$res = paraQuery($sql,$sessionID,$semesterID);
$row = mysql_fetch_row($res);
print_r($row[0]); die;
it will make your query properly formatted and thus invulnerable to SQL injection
also, it seems that $semesterID is not set which may cause some problem too

Related

Print MySQL Output Based on Query String Value

I'm trying to take a query string param such as ?table=products and have mysql return all the rows for the "products" table in mysql. I tried running the code below in my browser, but I just get a blank white page. I know the mysql server/username/pass information is correct, I've tested the query in mysql and it works fine.
I guess I have two question:
What am I doing wrong?
How come I can't see any error messages when php has an issue?
e.g. code:
<?php
// Get query string parameter value
$keys = array_keys($_GET);
$key = $keys[0];
$value = $_GET[$key];
// Setup connection to mysql database
$serverName = "localhost";
$username = "root";
$password = "password";
$dbname = "webserver";
$conn = new mysqli($serverName, $username, $password, $dbname);
// SQL query
$sql = "SELECT * FROM $value";
$result = $conn->query($sql);
// Print results
echo $result;
?>
Follow the instuctions on below link to enable php.ini errors
How do I get PHP errors to display?
VULNERABLE IMPLEMENTATION WARNING
The above comments clearly mention the side effects of this implementation.
Since knowing the actual bug is a developer's right! Continue reading the answer keeping the safety of software and its users in mind.
You are trying to print $result which is not valid since its an object.
You can do the following instead:
$response = array();
$sql = "SELECT * FROM $value";
$result = $conn->query($sql);
// Print results
if ($result) {
while($row = $result->fetch_array(MYSQL_ASSOC)) {
$response[] = $row;
}
}
echo json_encode($response);
What am I doing wrong?
Sadly, pretty much everything.
// Get query string parameter value
$keys = array_keys($_GET);
$key = $keys[0];
$value = $_GET[$key];
You are dereferencing a named value based on its position. And its totally unnecessary. Consider:
$value=$_GET['table'];
...
$conn = new mysqli($serverName, $username, $password, $dbname);
Where is your error checking to see if $conn was initialized?
$result = $conn->query($sql);
again, no error checking.
echo $result;
$result here is a mysqli_result object. You need to call some methods on it to get the data out.
while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
var_export($row);
}
How come I can't see any error messages when php has an issue?
Have you tested that the default handlers produce output in your browser? You're not overriding the config in php.ini in the code you've shown us. Did you check your logs?
ini_set('diplay_error', 1);
error_reporting(E_ALL);
I just get a blank white page
Would it be so hard to put
print "finished";
at the end of the code? Then you'd at least know if the code executed.
The main issue you have right now is you need to get the results
while ($row = $result->fetch_assoc()) {
//do something with row
}
See ( for mysqli->query method )
http://php.net/manual/en/mysqli.query.php
false on failure and mysqli_query() will return a mysqli_result object on success
See ( for the result objects definition )
http://php.net/manual/en/class.mysqli-result.php
Now as others mentioned I would never just concatenate user data into your query. Imagine a hacker knows the name of a valid table, not hard considering your sending it through the request. All they would have to do is send a value like this:
$value = 'real_table; DROP DATABASE';
And your query becomes.
$sql = "SELECT * FROM real_table; DROP DATABASE";
I won't say that this would actually work as there are ( maybe ) some restrictions on running multiple queries in a single request,user permissions etc... That might save your bacon, but I certainly wouldn't risk it.
So you have 2 choices.
Use a white list of tables
Query the DB for the schema
The first one is easy to do, make a list of tables
$whitelist = [
'table1',
'table2'
];
Then compare your user input
$safeTable = false;
if( false !== ($index = array_search($table, $whitelist))) {
$safeTable = $whitelist[$index];
}else{
//log error and
exit();
}
// SQL query
$sql = "SELECT * FROM $safeTable";
$result = $conn->query($sql);
For the second one,
$schema = $conn->query('SELECT `TABLE_NAME` FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA` LIKE "database"');
$whitelist = [];
while ($row = $result->fetch_assoc()) {
$whitelist[] = $row['TABLE_NAME'];
}
$safeTable = false;
if( false !== ($index = array_search($table, $whitelist))) {
$safeTable = $whitelist[$index];
}else{
//log error and
exit();
}
// SQL query
$sql = "SELECT * FROM $safeTable";
$result = $conn->query($sql);
This will return a list of all the tables in that database, from which you can build an array and then compare. The nice thing about the second one is that if you add a table then you don't have to change the code, which may or may not be a good thing. You have to have a user with permission to read from information_schema database. And you have to do an additional query.
-note- I am not directly using the users input, I'm using their input to find my data. It's less prone to breaking when there is a coder error. Consider this:
///all my codes are broken;
--if(!in_array($_GET['table'], $whitelist))) {
-- //log error and
-- exit();
--}
// SQL query
$sql = "SELECT * FROM {$_GET['table']}";
$result = $conn->query($sql);
Against this:
$safeTable = false;
// all my codes are broken
-- if( false !== ($index = array_search($_GET['table'], $whitelist))) {
-- $safeTable = $whitelist[$index];
-- }else{
-- //log error and
-- exit();
-- }
// SQL query
$sql = "SELECT * FROM $safeTable"; //$safeTable is undefined or false;
$result = $conn->query($sql);
Were using our code for inclusion, instead of exclusion. So if it breaks, it's never included. The other way, if it breaks it's never excluded. Which is not a situation we want to be even remotely possible.
I hope that helps you understand some of the pitfalls. The #1 rule for SQL (or anything on the web), is Never Trust the User. Never put their data into your SQL.

Post data to mysql DB

I'am trying to send data from android as JSON to PHP in order to parse it and save in MySQL DB
this is the part of the PHP CODE
$JsonString = $_POST["DATA"];
$JsonData = json_decode($JsonString, TRUE);
$Add_First_Only = 0;
foreach ($JsonData['items'] as $item)
{
$Order_ID = $item['Order_ID'];
$Order_Row_Number = $item['Order_Row_Number'];
$Order_Item_ID = $item['Order_Item_ID'];
$Order_Course_ID = $item['Order_Course_ID'];
$Order_Seat_No = $item['Order_Seat_No'];
$Order_Row_Value_wo_Options = $item['Order_Row_Value_wo_Options'];
$Order_Row_Value_with_options = $item['Order_Row_Value_with_options'];
if ($Add_First_Only == 0)
{
$result = mysqli_query($con,
"INSERT INTO order_items (Order_ID,Order_Row_Number,Order_Item_ID,Order_Course_ID,Order_Seat_No,Order_Row_Value_wo_Options, Order_Row_Value_with_options)
VALUES
(['$Order_ID'],['$Order_Row_Number'],['$Order_Item_ID'],['$Order_Course_ID'],
['$Order_Seat_No'],['$Order_Row_Value_wo_Options'],['$Order_Row_Value_with_options'])"
);
$Add_First_Only = 1;
}
}
and this is the error I get on the Eclipse LogCAT
12-16 02:00:01.800: V/TAG(1841): Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '['26'],['1'],['1'],['1'],['1'],['0'],['1'])' at line 4
As you can see from the error it self that I have values for the variables so non of them is a null value
The Question is what should I change or add to my sql syntax to fix this error ?
Remove the brackets around ['$Order_ID'] and the others
Use '$Order_ID' instead of ['$Order_ID'] etc. for your VALUES
if ($Add_First_Only == 0)
{
$result = mysqli_query($con,
"INSERT INTO order_items (Order_ID,Order_Row_Number,Order_Item_ID,Order_Course_ID,Order_Seat_No,Order_Row_Value_wo_Options, Order_Row_Value_with_options)
VALUES
('$Order_ID','$Order_Row_Number','$Order_Item_ID','$Order_Course_ID',
'$Order_Seat_No','$Order_Row_Value_wo_Options','$Order_Row_Value_with_options')"
);
$Add_First_Only = 1;
}
Don't wrap the parameters in the SQL statemenst with square brackets (example: ['$Order_ID']).
I often find it helpful to echo or error_log the SQL statement that is created and try running it in a SQL tool. This should give you better error messages, and reveal syntax errors (if the tool has syntax highlighting).
Also, look at what php.net has to say about prepared statements. SQL-statements of this type are vulnerable to SQL-injection attacks which are one of the most common ways to attack systems.
When you use Single quotes '' around the data you want to INSERT into DB you tell PHP that this data is string type and your database probably expects INTEGER data.

php -$result->fetch_array does not work

I am trying to select a table within my database with a GET Method.
Now when I hardcode the value of the variable in there (the table name) it works as expected and it returns the values in an array.
But when I try to determine the table name through a variable, I get the following error:
Fatal error: Call to a member function fetch_array() on a non-object in
Now I have tried the var_dump($result); but that returns bool(false).
Now the variable does carry a value, because when I echo it back to the screen it gives the value I would expect.
So why does not return the value when making the query for my table search???
$result = $mysqli->query("SELECT * FROM PodcastSermons WHERE sermonSeries = ". $series); //This where a change needs to happen
var_dump($result);
$posts = array();
while($row = $result->fetch_array())
{
$ID=$row['ID'];
$sermonTitle=$row['sermonTitle'];
$sermonSpeaker=$row['sermonSpeaker'];
$sermonSeries=$row['sermonSeries'];
$sermonDate=$row['sermonDate'];
$linkToImage=$row['linkToImage'];
$linkToAudioFile=$row['linkToAudioFile'];
$posts []= array (
'ID'=> $ID,
'sermonTitle'=> $sermonTitle,
'sermonSpeaker'=> $sermonSpeaker,
'sermonSeries'=> $sermonSeries,
'sermonDate'=> $sermonDate,
'linkToImage'=> $linkToImage,
'linkToAudioFile'=> $linkToAudioFile
);
}
$response['posts'] = $posts;
var_dump($posts);
PS I have read about the depreciation in mysql style and that I know have to use mysqli writing. I am running PHP Version 5.2.6-1+lenny16
If the $series is a string you need to put quotes around the variable..
Try...
$result = $mysqli->query("SELECT * FROM PodcastSermons WHERE sermonSeries = '". $series ."'");
Hope it helps.
Now I have tried the var_dump($result); but that returns bool(false).
Because your query failed.
Try:
if( ! $result = $mysqli->query("SELECT * FROM PodcastSermons WHERE sermonSeries = ". $series); ) {
echo "An error has occurred: \n" . var_export($mysqli->error_list, TRUE);
} else {
//do stuff
}
The central question seems to me: Where does $series come from? Where does that variable ever get initialized?
If you're passing this in from the web form, two things: either use $_GET or $_POST (whatever action you use in your form). And then you have to sanitize what comes from there, in order to not be vulnerable to SQL injection attacks. Prepared statements are your friend in this case; they help harden your script against this kind of attacks.
try this
$result = $mysqli->query("SELECT * FROM PodcastSermons WHERE sermonSeries = '$series' ");
$result = $mysqli->query("SELECT * FROM PodcastSermons WHERE sermonSeries = ". $series); //This where a change needs to happen
You should be using Prepared Statements if the variable: $series is user defined.
$result->prepare("SELECT * FROM PodcastSermons WHERE `sermonSeries`=?");
$result->bind_param('s', $series);
$result->execute();
Also, Print_r($result); to check if your initial $result to see if it has been populated; Furthermore, in your SQL Query is sermonSeries properly matched to your SQL Table?
Update:
while($row = $result->fetch_array())
{
Try Modifying this to:
while($row = $result->fetch_array(MYSQLI_ASSOC))
{
http://uk1.php.net/manual/en/mysqli-result.fetch-array.php
your query simply fails. check var_dump($series); before executing.
i assume it might be a string and you just don't quote it?
just a tip: first build a string with your commandtext before
calling $mysqli->query. and use that string (like $mysqli->query($cmd);
dump that string :) might open your eyes ;)
that way you can extract it and execute it directly against the database (f.e. phpmyadmin).

PHP Works but gives sql SYNTAX error

I just wrote this bit of code which echo's out what it's supposed to but after the echo statement it give me the error-
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near '' at line 1
why's this happening? how do i fix it?
<?php
$myclasses = explode(',', $_SESSION['classlist']);
$theirclasses = explode(',', $user_info['classlist']);
$common_classes = array_intersect($myclasses, $theirclasses);
if (count($common_classes) > 0) {
foreach ($common_classes as $class) {
$classes = mysql_query("SELECT * FROM classes WHERE class_id = ".$class) or die(mysql_error());
while($currentRow = mysql_fetch_array($classes)){
echo $currentRow['class_name'];
}
}
}
else {
}
?>
Try wrapping your query with quote:
$classes = mysql_query("SELECT * FROM classes WHERE class_id = '".$class."'") or die(mysql_error());
or change your query altogether by using PDO. Because, mysql_* function are deprecated.
I am going to assume that something is wrong in the $class variable when passed to the query. What I usually do in such scenarios is assign the SQL query to a string variable and dump it to test the entire query at once. Helps me find out SQL syntax errors or if there's any undesired characters.
<?php
$myclasses = explode(',', $_SESSION['classlist']);
$theirclasses = explode(',', $user_info['classlist']);
$common_classes = array_intersect($myclasses, $theirclasses);
if (count($common_classes) > 0) {
foreach ($common_classes as $class) {
$sql = "SELECT * FROM classes WHERE class_id = '{$class}'" ; // use {} inside double quotes
var_dump($sql); // check out the what the query becomes
$classes = mysql_query($sql) or die(mysql_error());
while($currentRow = mysql_fetch_array($classes)){
echo $currentRow['class_name'];
}
}
}
else {
}
If $class is empty you'd get that error which would leave your query as SELECT * FROM classes WHERE class_id = which is not valid. Try quote it. If you quote it, at least you'll get SELECT * FROM classes WHERE class_id = ''
"SELECT * FROM classes WHERE class_id = '".$class."'";

mysql_num_rows error in PHP with mysql_query

Hi i am too new too php and mysql and i want to count the member number due to the search made by user. However, mysql_num_rows doesnt work.
mysql_num_rows(mysql_query("SELECT * FROM members WHERE $title LIKE '%$_POST[search]%' LIMIT $start,$member_number"));
It says "mysql_num_rows(): supplied argument is not a valid MySQL result resource in ..."
NOTE: $title is a select menu which user choose where to search. LIMIT is, as you know :), number of member which is shown in a page.
And also $start= ($page-1)*$member_number; in order to set the first entry in that page. I think the problem is here but i cant solve it. :(
Your query probably has an error, in which case mysql_query will return false.
For this reason, you should not group commands like this. Do it like this:
$result = mysql_query("...");
if (!$result)
{ echo mysql_error(); die(); } // or some other error handling method
// like, a generic error message on a public site
$count = mysql_num_rows($result);
Also, you have a number of SQL injection vulnerabilities in your code. You need to sanitize the incoming $search variable:
$search = mysql_real_escape_string($_POST["search"]);
... mysql_query(".... WHERE $title LIKE '%$search%'");
if $start and $end come from outside, you also need to sanitize those before using them in your LIMIT clause. You can't use mysql_real_escape_string() here, because they are numeric values. Use intval() to make sure they contain only numbers.
Using a dynamic column name is also difficult from a sanitation point of view: You won't be able to apply mysql_real_escape_string() here, either. You should ideally compare against a list of allowed column names to prevent injection.
you have to use GET method in your form, not POST.
mysql_num_rows doesn't make sense here.
If you're using limit, you already know the number*.
If you want to know number, you shouldn't use limit nor request rows but select number itself.
// get your $title safe
$fields = array("name","lastname");
$key = array_search($_GET['title'],$fields));
$title = $fields[$key];
//escape your $search
$search = mysql_real_escape_string($_GET['search']);
$sql = "SELECT count(*) FROM members WHERE $title LIKE '%$search%'";
$res = mysql_query($query) or trigger_error(mysql_error()." in ".$sql);
$row = mysql_fetch_row($res);
$members_found = $row[0]
in case you need just 5 records to show on the page, no need for mysql_num_rows() again:
// Get LIMIT params
$member_number = 5;
$start = 0;
if (isset($_GET['page'])){
$start = abs($_GET['page']-1)*$member_number;
}
// get your $title safe
$fields = array("name","lastname");
$key = array_search($_GET['title'],$fields));
$title = $fields[$key];
//escape your $search
$search = mysql_real_escape_string($_GET['search']);
$sql = "SELECT count(*) FROM members
WHERE `$title` LIKE '%$search%'
LIMIT $start, $member_number";
$res = mysql_query($query) or trigger_error(mysql_error()." in ".$sql);
while($row = mysql_fetch_assoc($res){
$data[] = $row;
}
Now you have selected rows in $data for the further use.
This kind of error generally indicates there is an error in your SQL query -- so it has not been successful, and mysql_query() doesn't return a valid resource ; which, so, cannot be used as a parameter to mysql_num_rows().
You should echo your SQL query, in order to check if it's build OK.
And/or, if mysql_query() returns false, you could use mysql_error() to get the error message : it'll help you debug your query ;-)
Typically, your code would look a bit like this :
$query = "select ..."; // note : don't forget about escaping your data
$result = mysql_query($query);
if (!$result) {
trigger_error(mysql_error()." in ".$query);
} else {
// use the resultset
}

Categories