I am using php and sql to check user information from the database. I need to check if the username and password is correct and the account is active. I have this sql query, but it does not work. What is the method to do it?
SELECT * FROM foo WHERE (name='foo' AND password='foo') AND active=1
for me
SELECT * FROM foo WHERE (name="foo" AND password="foo") AND active=1
should be same as
SELECT * FROM foo WHERE name="foo" AND password="foo" AND active=1
the above query assumes that field active is of family type int In case its varchar or char you r query should be like this
SELECT * FROM foo WHERE name="foo" AND password="foo" AND active='1'
and the query should work and i assume you are taking care of SQL injections from php
Where you say, "When I remove AND active=1 part, it works fine. Any ideas?"
Try changing it to AND active<>1 to see if the issue lies in that field. It's possible 'active' may be null or some other value. Try outputting the value (try var_dump($var) in PHP) to see what is returned for the 'active' field. If the value is 0, a blanck string, or null, then you've isolated your problem.
The query looks correct (assuming columns name, password, and active exist in table foo), but if you're using it in PHP you might be running into trouble with the double quotes if they're inside a string you're declaring. You might need to escape them or use single quotes.
My query returns 0 row and I am sure that I have that fields in the database and typing the correct information. When I remove AND active=1 part, it works fine. Any ideas?
Yes.
The idea is very simple. Just check if a record with name='foo' and password='foo' has active=1. Then correct mistake and your data
Hint: a programmer cannot be sure when the logic says he is wrong.
First of all, use mysql_real_escape_string() or a PDO method to escape your input. You do not want people messing around in your database.
A simplified version of what I normally do is
SELECT main.id,
main.isActive,
(SELECT count(sub.id)
FROM users AS sub
WHERE sub.id = main.id
AND sub.credential = 'md5password'
LIMIT 1
) AS credentialMatches
FROM users AS main
WHERE main.identity = 'username'
Grab your result:
$result = mysql_query($sql);
$data = array();
if (false !== $result) {
while ($row = mysql_fetch_assoc($result)) {
$data[] = $row;
}
}
Handle your result:
if (count($data) < 1) {
// username not found
} else if (count($data) > 1) {
// multiple rows with the same username, bad thing
} else {
$row = $data[0]
if (false === (boolean) $row['isActive']) {
// user not active
} else if (true === (boolean) $row['credentialMatches']) {
// SUCCESS
// valid user and credential
}
}
Also note: ALWAYS store password at least as an MD5 hash like so WHERE credential = MD5('password'). Same when you are inserting: SET credential = MD5('password'). This way, when someone else will ever read you database, user passwords won't be revealed so easily.
An even better is to add an additional salt to hash, but that might be going to far for now.
You could debug your sql like this in php:
$sql = "SELECT * FROM foo WHERE (name='foo' AND password='foo') AND active=1";
$result = mysql_query($sql) or die (mysql_error());
This "or die (mysql_error())" will give you the exact error of that query, maybe the DB isn't selected if that happened use mysql?query($sql, $db)...
Hope it helps
Related
I'm using Postgresql 9.2 and PHP 5.5 on Linux. I have a database with "patient" records in it, and I'm displaying the records on a web page. That works fine, but now I need to add interactive filters so it will display only certain types of records depending on what filters the user engages, something like having 10 checkboxes from which I build an ad-hoc WHERE clause based off of that information and then rerun the query in realtime. I'm a bit unclear how to do that.
How would one approach this using PHP?
All you need to do is recieve all the data of your user's selected filters with $_POST or $_GET and then make a small function with a loop to concatenate everything the way your query needs it.
Something like this... IN THE CASE you have only ONE field in your DB to match with. It's a simple scenario and with more fields you'll need to make it so that you add the field you really need in each case, nothing too complex.
<?php
//recieve all the filters and save them in array
$keys[] = isset($_POST['filter1'])?'$_POST['filter1']':''; //this sends empty if the filter is not set.
$keys[] = isset($_POST['filter2'])?'$_POST['filter2']':'';
$keys[] = isset($_POST['filter3'])?'$_POST['filter3']':'';
//Go through the array and concatenate the string you need. Of course, you might need AND instead of OR, depending on what your needs are.
foreach ($keys as $id => $value) {
if($id > 0){
$filters.=" OR ";
}
$filters.=" your_field = '".$value."' ";
}
//at this point $filters has a string with all your
//Then make the connection and send the query. Notice how the select concatenates the $filters variable
$host = "localhost";
$user = "user";
$pass = "pass";
$db = "database";
$con = pg_connect("host=$host dbname=$db user=$user password=$pass")
or die ("Could not connect to server\n");
$query = "SELECT * FROM table WHERE ".$filters;
$rs = pg_query($con, $query) or die("Cannot execute query: $query\n");
while ($row = pg_fetch_row($rs)) {
echo "$row[0] $row[1] $row[2]\n";
//or whatever way you want to print it...
}
pg_close($con);
?>
The above code will get variables from a form that sent 3 variables (assuming all of them correspond to the SAME field in your DB, and makes a string to use as your WHERE clause.
If you have more than one field of your db to filter through, all you need to do is be careful on how you match the user input with your fields.
NOTE: I did not add it here for practical reasons... but please, please sanitize user input.. ALWAYS sanitize user input before using user controlled data in your queries.
Good luck.
Don't do string concatenation. Once you have the values just pass them to the constant query string:
$query = "
select a, b
from patient
where
($x is not null and x = $x)
or
('$y' != '' and y = '$y')
";
If the value was not informed by the user pass it as null or empty. In the above query the x = $x condition will be ignored if $x is null and the y = '$y' condition will be ignored if $y is empty.
With that said, a check box will always be either true or false. What is the exact problem you are facing?
Always sanitize the user input or use a driver to do it for you!
I have created a Where clause builder exactly for that purpose. It comes with the Pomm project but you can use it stand alone.
<?php
$where = Pomm\Query\Where::create("birthdate > ?", array($date->format('Y-m-d')))
->andWhere('gender = ?', array('M'));
$where2 = Pomm\Query\Where::createWhereIn('something_id', array(1, 15, 43, 104))
->orWhere($where);
$sql = sprintf("SELECT * FROM my_table WHERE %s", $where2);
$statement = $pdo->prepare($sql);
$statement->bind($where2->getValues());
$results = $statement->execute();
This way, your values are escaped and you can build dynamically your where clause. You will find more information in Pomm's documentation.
I have a strange mysql-thing going on here, it is about the following code:
$res = mysql_query("SELECT * FROM users WHERE group='".$group."'");
if (mysql_num_rows($res)==1) {
$row = mysql_fetch_assoc($res);
$uid = $row['uid'];
$user_update = mysql_query("UPDATE fe_users SET group = 5 WHERE group='".$group."'");
return 'ok';
} else {
return 'not ok';
}
I am checking, if there is a user with the group = $group. If so, the group is updated to 5 and after that the string "ok" is returned, if no user with group=$group exists, as you can see the string "not ok" is returned.
This should be very easy, but the problem now is, that if there is a user with group=$group, the update is done correctly, but instead of returning "ok", php returns "not ok", as if the change from the update is been taken into account for the above executed select retroactively. I dont understand this. Any help would be really appreciated.
Thanx in advance,
Jayden
I think 'group' is a reserved keyword that you have used as a field name, change it or use like
$res = mysql_query("SELECT * FROM users WHERE `group`='".$group."'");
and
$user_update = mysql_query("UPDATE fe_users SET `group` = 5 WHERE `group`='".$group."'");
and you can use count($res)==1 instead of mysql_num_rows($res)==1 if it is a problem.
Reference: Mysql Reserved keywords.
I am not sure if this has any merit but try using this style in your SELECT and UPDATE commands: WHERE group='$group', without using string joins. Other than that I can't seem to see why you are getting an update and not being returned "ok".
You are checking if mysql_num_rows($res)==1, so you'll return ok if there is exactly one user on that group. If there are two or more users, it will return not ok. Probably not what you want, right? I think you should check if mysql_num_rows($res)>=1.
You might consider modifying the placement of your brackets, and changing your num_rows check, like so:
$res = mysqli_query("SELECT uid FROM users WHERE `group` ='".$group."'");
if (mysqli_num_rows($res)>0) {//there was a result
while($row = mysqli_fetch_assoc($res)){
// grab the user id from the row
$uid = $row['uid'];
// and update their record
$user_update = mysqli_query("UPDATE fe_users SET `group` = 5 WHERE `group`='".$group."'");
if(mysqli_num_rows($user_update)==1){
return 'ok, updated user';
} else {
// database error
return 'not ok, unable to update user record';
}
}//end while row
}else{
return 'No results were found for this group.';
}
By selecting just the column you want, you reduce the query's overhead. By comparing the initial result to 0 instead of 1, you allow for groups with many members. By wrapping the update function in a while loop, you can loop through all the returned results, and update records for each one. By moving the test that returns 'ok'/'not ok' to check for success on the update operation, you're able to isolate database errors. The final else statement tells you if no update operation was performed because there are no members of the group.
BTW, for future-compatible code, I recommend using mysqli, as the "mysql_query" family of PHP functions are officially deprecated. See http://www.php.net/manual/en/mysqli.query.php for a quick start, it's largely the same thing.
HI everyone i tried for 3 days and i'm not able to solve this problem. This is the codes and i have went through it again and again but i found no errors. I tried at a blank page and it worked but when i put it inside the calendar it has the syntax error. Thanks a million for whoever who can assist.
/** QUERY THE DATABASE FOR AN ENTRY FOR THIS DAY !! IF MATCHES FOUND, PRINT THEM !! **/
$testquery = mysql_query("SELECT orgid FROM sub WHERE userid='$userid'");
while($row4 = mysql_fetch_assoc($testquery))
{
$org = $row4['orgid'];
echo "$org<br>";
$test2 = mysql_query("SELECT nameevent FROM event WHERE `userid`=$org AND EXTRACT(YEAR FROM startdate)='2010' AND EXTRACT(MONTH FROM startdate)='08' AND EXTRACT(DAY FROM startdate)='15'") or die(mysql_error());
while($row5=mysql_fetch_assoc($test2))
{
$namethis = $row5['nameevent'];
$calendar.=$namethis;
}
}
First question: what calendar are you talking about?
And here are my 2-cents: does the EXTRACT function returns a string or a number?
Are the "backticks" (userid) really in your query? Try to strip them off.
Bye!
It's a guess, given that you haven't provided the error message you're seeing, but I imagine that userid is a text field and so the value $org in the WHERE clause needs quotes around it. I say this as the commented out testquery has quotes around the userid field, although I appreciate that it works on a different table. Anyway try this:
SELECT nameevent FROM event WHERE userid='$org' AND EXTRACT(YEAR FROM startdate)='2010' AND EXTRACT(MONTH FROM startdate)='08' AND EXTRACT(DAY FROM startdate)='15'
In such cases it's often useful to echo the sql statement and run it using a database client
First step in debugging problems like this, is to print out the acutal statement you are running. I don't know PHP, but can you first build up the SQL and then print it before calling mysql_query()?
EXTRACT() returns a number not a character value, so you don't need the single quotes when comparing EXTRACT(YEAR FROM startdate) = 2010, but I doubt that this would throw an error (unlike in other databases) but there might be a system configuration that does this.
Another thing that looks a bit strange by just looking at the names of your columns/variables: you are first retrieving a column orgid from the user table. But you compare that to the userid column in the event table. Shouldn't you also be using $userid to retrieve from the event table?
Also in the first query you are putting single quotes around $userid while you are not doing that for the userid column in the event table. Is userid a number or a string? Numbers don't need single quotes.
Any of the mysql_* functions can fail. You have to test all the return values and if one of them indicates an error (usually when the function returns false) your script has to handle it somehow.
E.g. in your query
mysql_query("SELECT orgid FROM sub WHERE userid='$userid'")
you mix a parameter into the sql statement. Have you assured that this value (the value of $userid) is secure for this purpose? see http://en.wikipedia.org/wiki/SQL_injection
You can use a JOIN statement two combine your two sql queryies into one.
see also:
http://docs.php.net/mysql_error
http://docs.php.net/mysql_real_escape_string
http://www.w3schools.com/sql/sql_join.asp
Example of rudimentary error handling:
$mysql = mysql_connect('Fill in', 'the correct', 'values here');
if ( !$mysql ) { // some went wrong, error hanlding here
echo 'connection failed. ', mysql_error();
return;
}
$result = mysql_select_db('dbname', $mysql);
if (!$result ) {
echo 'select_db failed. ', mysql_error($mysql);
return;
}
// Is it safe to use $userid as a parmeter within an sql statement?
// see http://docs.php.net/mysql_real_escape_string
$sql = "SELECT orgid FROM sub WHERE userid='$userid'";
$testquery = mysql_query($sql, $mysql);
if (!$testquery ) {
echo 'query failed. ', mysql_error($mysql), "<br />\n";
echo 'query=<pre>', $sql, '</pre>';
return;
}
I'm new to PHP and SQL, but I need a way to store the result of an SQL Query into a variable.
The query is like this:
$q = "SELECT type FROM users WHERE username='foo user'";
$result = pg_query($q);
The query will only return one string; the user's account type, and I just need to store that in a variable so I can check to see if the user has permission to view a page.
I know I could probably just do this query:
"SELECT * FROM users WHERE username='foo user' and type='admin'";
if(pg_num_rows($result) == 1) {
//...
}
But it seems like a bad practice to me.
Either way, it would be good to know how to store it as a variable for future reference.
You can pass the result to pg_fetch_assoc() and then store the value, or did you want to get the value without the extra step?
$result = pg_query($q);
$row = pg_fetch_assoc($result);
$account_type = $row['type'];
Is that what you are looking for?
Use pg_fetch_result:
$result = pg_query($q);
$account_type = pg_fetch_result($result, 0, 0);
But on the other hand it's always good idea to check if you got any results so I'll keep the pg_num_rows check.
I have made the following search script but can only search one table column when querying the database:
$query = "select * from explore where site_name like '%".$searchterm."%'";
I would like to know how I can search the entire table(explore). Also, I would need to fix this line of code:
echo "$num_found. ".($row['site_name'])." <br />";
One last thing that is bugging me is when I push the submit button on a different page I always displays the message "Please enter a search term." even when I enter in something?
Thanks for any help, here is the entire script if needed:
<?php
// Set variables from form.
$searchterm = $_POST['searchterm'];
trim ($searchterm);
// Check if search term was entered.
if (!$serachterm)
{
echo "Please enter a search term.";
}
// Add slashes to search term.
if (!get_magic_quotes_gpc())
{
$searchterm = addcslashes($searchterm);
}
// Connects to database.
# $dbconn = new mysqli('localhost', 'root', 'root', 'ajax_demo');
if (mysqli_connect_errno())
{
echo "Could not connect to database. Please try again later.";
exit;
}
// Query the database.
$query = "select * from explore where site_name like '%".$searchterm."%'";
$result = $dbconn->query($query);
// Number of rows found.
$num_results = $result->num_rows;
echo "Found: ".$num_results."</p>";
// Loops through results.
for ($i=0; $i <$num_results; $i++)
{
$num_found = $i + 1;
$row = $result->fetch_assoc();
echo "$num_found. ".($row['site_name'])." <br />";
}
// Escape database.
$result->free();
$dbconn->close();
?>
Contrary to other answers, I think you want to use "OR" in your query, not "AND":
$query = "select * from explore where site_name like '%".$searchterm."%' or other_column like '%".$searchterm."%'";
Replace other_column with the name of a second column. You can keep repeating the part I added for each of your columns.
Note: this is assuming that your variable $searchterm has already been escaped for the database, for example with $mysqli->real_escape_string($searchterm);. Always ensure that is the case, or better yet use parameterised queries.
Similarly when outputting your variables like $row['site_name'] always make sure you escape them for HTML, for example using htmlspecialchars($row['site_name']).
One last thing that is bugging me is when I push the submit button on a different page I always displays the message "Please enter a search term." even when I enter in something?
Make sure that both forms use the same method (post in your example). The <form> tag should have the attribute method="post".
Also, what is wrong with the line of code you mentioned? Is there an error? It should work as far as I can tell.
A UNION query will provide results in a more optimized fashion than simply using OR. Please note that utilizing LIKE in such a manner will not allow you to utilize any indexes you may have on your table. You can use the following to provide a more optimized query at the expense of losing a few possible results:
$query = "SELECT * FROM explore WHERE site_name LIKE '".$searchterm."%'
UNION
SELECT * FROM explore WHERE other_field LIKE '".$searchterm."%'
UNION
SELECT * FROM explore WHERE third_field LIKE '".$searchterm."%'";
This query is probably as fast as you're going to get without using FULLTEXT searching. The downside, however, is that you can only match strings beginning with the searchterm.
To search other columns of table you need to add conditions to your sql
$query = "select * from explore where site_name like '%".$searchterm."%' or other_column like '%".$searchterm."%'";
But if you don't know that I would strongly advise going through some sql tutorial...
Also I didn't see anything wrong with this line
echo "$num_found. ".($row['site_name'])." <br />";
What error message are you getting?
Just add 'AND column = "condition"' to the WHERE clause of your query.
Be careful with adding lots of LIKE % conditions as these can be very slow especially if using a front wild card. This causes the RDBMS to search every row. You can optimize if you use an index on the column and only a trailing wildcard.
You are searching the whole table, just limiting the results to those where the site_name like '%".$searchterm."%'. If you want to search everything from that table, you need to remove the WHERE clause
Here's the corrected line. You had a few too many quotes in it.
echo $num_found.".".($row['site_name'])." <br />";
Regarding displaying the message, you have a typo in your code:
// Check if search term was entered.
if (!$serachterm)
should be:
// Check if search term was entered.
if (!$searchterm)
In the code you have written, !$serachterm always evaluates to true because you never declared a variable $seracherm (note the typo).
your code is very bugy for sql injection first do
do this
$searchterm = htmlspecialchars($searchterm);
trim($searchterm);
next
$query = mysql_real_escape_string($query);
finaly your search looks like this
$query = "select * from explore where site_name like '%$searchterm%';