im having trouble getting data from two seperate tables
so far i have this
<?
include('config.php');
$xid = $_GET['xid'];
$result = mysql_query("SELECT * FROM `config`") or trigger_error(mysql_error());
while($row = mysql_fetch_array($result)){
foreach($row AS $key => $value) { $row[$key] = stripslashes($value); }
$result = mysql_query("SELECT * FROM `utinfo` WHERE `xid` = $xid") or trigger_error(mysql_error());
while($row2 = mysql_fetch_array($result)){
foreach($row2 AS $key => $value) { $row2[$key] = stripslashes($value); }
$un = urldecode($row2['un']);
};
switch ($row['module'])
{
case 1:
echo "Function 1 for user $uid on account $un";
break;
case 2:
echo "Function 2 for user $uid on account $un";
break;
case 3:
echo "Function 3 for user $uid on account $un";
break;
default:
echo "No module defined.";
};
};
?>
The config table config has the row named modules, and its populated by 2 entries, one of which is 1, the other 3. So i should be seeing case 1 and then case 3. But all im getting is the default echo.
(This is not an answer to the OP, but something you really should care about, so I think it's worth writting it)
It seems there is a enormous SQL-injection in your code.
The normal way of calling your page would be with something like "xid=5" in the URL, to get informations of user #5.
Now, suppose someone give "xid=5 or 1=1". The resulting query would be :
SELECT * FROM `utinfo` WHERE `xid` = 5 or 1=1
The condition is always true ; you'd get informations of ALL users as an output, as you iterate through the resultset.
Another possibility : "xid=5; delete from utinfo;" ; which would give this query :
SELECT * FROM `utinfo` WHERE `xid` = 5; delete from utinfo;
That would empty your table :-(
You must always escape / check / sanitize / whatever you data before putting them in a SQL query, especially (but not only) if they come from a user of the application.
For strings, see the mysql_real_escape_string function.
For data that sould be integers, you could use intval (worst case, if data was not valid, you'll get 0, which might get no result from the DB, but, at least, won't break it ^^ )
Another solution would be to use prepared statements ; but those are not available with mysql_* function : you have to switch to either
mysqli_*
or PDO
Anyway, for a new application, you shouldn't use mysql_* : it is old, and doesn't get new functionnalities / improvements that mysqli and PDO get...
stripslashes() is used on strings. Your case values are integers. It seems like you have a type mismatch here?
Why are you not using PDO? You should really standardis on PDO if you can.
Table names in SQL select should not be quoted.
You should consider using prepared statements in order to avoid SQL Injection and then you don't have to worry about having to quote your paramaters
The first answer is probably correct regarding type mismatches, you should be able to fix the issue by using the following code:
switch ((integer) $row['module'])
See the following:
http://us.php.net/manual/en/language.types.type-juggling.php#language.types.typecasting
Alternatively, you could try this:
settype($row['module'], "integer");
switch ($row['module'])
See:
http://us.php.net/manual/en/function.settype.php
I would also suggest echo'ing the value of $row['module'] onto the page just to check that it is indeed an integer.
Related
I'm wrapping up my website, but I've an issue with breaking
if statement inside foreach statement,
I want when a student try to pick a job that he/she already had chosen, the if() fail and break from the WHOLE foreach() loop, this is my code,the break inside the if() only break out the if(), not the whole foreach
please please help me.
thank you
foreach($_POST['JobId'] AS $i){
$sqlCheckingBeofrAdding ="SELECT * FROM JobsLists WHERE JobId = '".$i."' AND SSU = '".$SSU."' ";
$rs = mysqli_query($dbCIE ,$sqlCheckingBeofrAdding);
$row1 = mysqli_fetch_assoc($rs);
if($row1 > 0){
echo "You Already Have this Job In your List";
break;
}
//insert into junction table..
$sqlUpdate = "UPDATE Jobs SET NoStudent=NoStudent-1 WHERE JobId = '" . $i . "'";
$resultUpdate = mysqli_query($dbCIE,$sqlUpdate) or die(mysqli_error($dbCIE));
$sqlInsert ="INSERT INTO JobsLists(`JobID` , `SSU`) VALUES(".$i.",'".$SSU."' )";
$MyQuery= mysqli_query($dbCIE, $sqlInsert) or die(mysqli_error($dbCIE));
}
If your query is only return the single student record than you can use return and this will not execute the further code inside the loop.
If your query returns multiple students record than you can use continue
For point 1:
if($row1 > 0){
echo "You Already Have this Job In your List";
return;
}
For point 2:
if(condition){
echo "You Already Have this Job In your List";
continue;
}
You can use break; OR return; (if this is a function.) Let me know if you need code.
The break statement in PHP accepts a numeric argument.
Try changing your break; to break 2; or use a return;
The php manual says:
break ends execution of the current for, foreach, while, do-while or switch structure.
I do not think your break is breaking out of the if. I suspect a different problem with your code.
Break does not break ifs. This is how the language works.
Ensure you have a debug line before and after the if instead of simple MySQL operations. This seems to be a problem with the code.
For example, add some echo lines before and after the if and you'll have a better idea on what's going on.
The code itself seems to have a lot of problems:
1-You don't need to retrieve all fields (select *) in order to see if at least one entry exists. This is a misuse of the database layer.
2-In case you need to check if one entry exists, add LIMIT 1 to your SQL query. This will avoid MySQL to scan the entire table in case the query is not using any unique key, which is very likely.
3-mysqli_fetch_assoc returns an associative array, but then you compare the array against "> 0". Would you confirm that Array() > 0 ?
4-You seem to be using camelCased variables, but then all of the sudden you have $MyQuery, when it should be $myQuery to match the convention you're using.
5-You're storing the result of the query, in a variable named $MyQuery. This is a bad practice, as the variable name should describe what it contains. Therefore you'll want to call it $myResult or $rs as you did in the first query.
6-None of the variables used in the SQL statements are escaped.
Double check your code using the rubber duck technique and I'm sure you'll find the issue is not related to the if/break; but to something else. Not to offend, but this code seems very immature.
id 1stPayment 2ndPayment 3rdPayment 4thPayment Tuition
8 0 200 2000 2000 9000
8 2000 0 0 0 0
9 0 0 0 0 1000
10 1 0 0 0 0
i want to add all the tuition of id-8 and echo the result of the sum of the tuition. how can i sum all the tuition with out adding the tuition of other id's. the table name is "students_payments"... "i also want to echo the tuition of an id in its own page, like when i access the account of id-8 it shows the sum of its tuition. :D
i have this code, but when i access the account of id-9 and id-10 it shows the added value of all the tuition. tnx in advanced.. :D
<?php
include("confstudents.php");
$id = $_GET['id'];
$result = mysql_query("select * from student_payments where id='$id' ");
while ($res = mysql_fetch_assoc($result)) {
$result = mysql_query("SELECT SUM(Tuition) FROM student_payments");
while ($row = mysql_fetch_assoc($result)) {
$TT = $row['SUM(Tuition)'];
echo "Php $TT";
}
}
?>
You query should be
SELECT SUM(Tuition) as TotalTuition FROM student_payments WHERE id='$id' GROUP BY id
Then you can just echo TotalTuition.
Warning
your code is vulnerable to sql injection you need to escape all get and post and the better approach will be using Prepared statement
Good Read
How to prevent SQL injection in PHP?
Are PDO prepared statements sufficient to prevent SQL injection?
Note
The entire ext/mysql PHP extension, which provides all functions named with the prefix mysql_, is officially deprecated as of PHP v5.5.0 and will be removed in the future. So use either PDO or MySQLi
Good read
The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead
PDO Tutorial for MySQL Developers
Pdo Tutorial For Beginners
A few things about your code:
Always cast data to what you expect them to be (in the case of your id, that should be an integer).
Never put any unescaped strings into SQL queries. You never know what people type into your applications input fields. In this case I don't use mysql_escape, as the id was casted to integer, which is of no harm to the query.
Never (!) use mysql_query in a loop. You never need it and it will always slow down your application without providing any use.
If your database expects an integer, then give it an integer and not a string. id is expected to be an integer, but '$id' will always be a string. Unfortunately MySQL silently tries to cast this to integer instead of complaining...
As I am very picky: id is an abbreviation for identifier, which in turn means, that you can identify something by it. Resulting from that, an identifier must always be unique. I hope you chose it merely to explain your question.
Use ' instead of " for strings wherever you can. This will keep the PHP parser from trying to interpret the string. Makes your code a little more save and faster.
Though mysql_* functions are deprecated, I have only extended your code. So for an answer to your question see the code below.
<?php
include("confstudents.php");
$id = (int)$_GET['id']; // cast to int to prevent SQL injection; if you can't do that (e.g. it is a string), use mysql_escape()
if ($id <= 0) { // check if the id is at all valid and break here if it isn't
die('Invalid ID');
}
$result = mysql_query('SELECT SUM(tuition) sum_tuition FROM student_payments WHERE id = ' . $id);
if ($result === FALSE) { // Check if the statement was able be processed
die('Error in SQL statement'); // break here, if it wasn't
}
$res = mysql_fetch_assoc($result); // with the SQL above, there's always exactly one row in the result
echo 'Php ' . $res['sum_tuition'];
?>
You can add some more debugging code such as mysql_error() to find errors in your SQL statements. But don't display that to your users. They might know, how use it for exploiting your application...
<?php
include("confstudents.php");
$id = $_GET['id'];
$result = mysql_query("SELECT SUM(Tuition) FROM student_payments where id='$id'");
while ($row = mysql_fetch_array($result)) {
$TT = $row['SUM(Tuition)'];
echo "$TT";
}
?>
I was wondering if you think this is possible:
Ok so I have a database storing usernames and I would like to echo the admins which are inside a file called admins.php IF they match the usernames inside the database so far I have got:
admins.php;
$admins = array("username","username2","username3");
and
$users="SELECT username from usrsys";
$query_users=mysql_query($users);
while loop here.
The while loop should hopefully echo the users which matches the admins.php file. I assume I should use something like (inarray()), but I am really not sure.
You should definitely use IN clause in your SQL to do this. Selecting everything from the table in order to determine in PHP if it contains the user names you're looking for makes no sense and is very wasteful. Can you imagine what would happen if you had a table of 1 million users and you needed to see if two of them were on that list? You would be asking your DBMS to return 1 million rows to PHP so that you can search through each of those names and then determine whether or not any of them are the ones you're looking for. You're asking your DBMS to do a lot of work (send over all the rows in the table), and you're also asking PHP to do a lot of work (store all those rows in memory and compute a match), unnecessarily.
There is a much more efficient and faster solution depending on what you want.
First, if you only need to know that all of those users exist in the table then use SELECT COUNT(username) instead and your database will return a single row with a value for how many rows were found in the table. That way you have an all or nothing approach (if that's what you're looking for). Either there were 3 rows found in the table and 3 elements in the array or there weren't. This also utilizes your table indexes (which you should have properly indexed) and means faster results.
$admins = array("username","username2","username3");
// Make sure you properly escape your data before you put in your SQL
$list = array_map('mysql_real_escape_string', $admins);
// You're going to need to quote the strings as well before they work in your SQL
foreach ($list as $k => $v) $list[$k] = "'$v'";
$list = implode(',', $list);
$users = "SELECT COUNT(username) FROM usrsys WHERE username IN($list)";
$query_users = mysql_query($users);
if (!$query_users) {
echo "Huston we have a problem! " . mysql_error(); // Basic error handling (DEBUG ONLY)
exit;
}
if (false === $result = mysql_fetch_row($query_users)) {
echo "Huston we have a problme! " . mysql_error(); // Basic error handling (DEBUG ONLY)
}
if ($result[0] == count($admins)) {
echo "All admins found! We have {$result[0]} admins in the table... Mission complete. Returning to base, over...";
}
If you actually do want all the data then remove the COUNT from the SQL and you will simply get all the rows for those users (if any are found).
$admins = array("username","username2","username3");
// Make sure you properly escape your data before you put in your SQL
$list = array_map('mysql_real_escape_string', $admins);
// You're going to need to quote the strings as well before they work in your SQL
foreach ($list as $k => $v) $list[$k] = "'$v'";
$list = implode(',', $list);
$users = "SELECT username FROM usrsys WHERE username IN($list)";
$query_users = mysql_query($users);
if (!$query_users) {
echo "Huston we have a problem! " . mysql_error(); // Basic error handling (DEBUG ONLY)
exit;
}
// Loop over the result set
while ($result = mysql_fetch_assoc($query_users)) {
echo "User name found: {$result['username']}\n";
}
However, I really urge you to reconsider using the old ext/mysql API to interface with your MySQL database in PHP since it is deprecated and has been discouraged from use for quite some time. I would really urge you to start using the new alternative APIs such as PDO or MySQLi and see the guide in the manual for help with choosing an API.
In PDO, for example this process would be quite simple with prepared statements and parameterized queries as you don't have to worry about all this escaping.
There's an example in the PDOStatement::Execute page (Example #5) that shows you just how to do use the IN clause that way with prepared statements... You can then reuse this statement in other places in your code and it offers a performance benefit as well as making it harder for you to inadvertently expose yourself to SQL injection vulnerabilities.
// Connect to your database
$pdo = new PDO("mysql:dbname=mydb;host=127.0.0.1", $username, $password);
// List of admins we want to find in the table
$admins = array("username","username2","username3");
// Create the place holders for your paratmers
$place_holders = implode(',', array_fill(0, count($admins), '?'));
// Create the prepared statement
$sth = $dbh->prepare("SELECT username FROM usrsys WHERE username IN ($place_holders)");
// Execute the statement
$sth->execute($admins);
// Iterate over the result set
foreach ($sth->fetchAll(PDO::FETCH_ASSOC) as $row) {
echo "We found the user name: {$row['username']}!\n";
}
Your PHP code even looks so much better with PDO :)
Just include admins.php file and use the next construction in your loop:
while ($row = mysql_fetch_array($users)) {
if (in_array($users[0], $admins))
echo $users[0];
}
Try this:
<?php
# include admins.php file that holds the admins array
include "admins.php";
# join all values in the admins array using "," as a separator (to use them in the sql statement)
$admins = join(",", $admins);
# execute the query
$result = mysql_query("
SELECT username
FROM usrsys
WHERE username IN ($admins)
");
if ($result) {
while ($row = mysql_fetch_array($result)) {
echo $row["username"] . "<br>";
}
}
?>
If your looking for syntax to pull in only the users from your $admins array then you could use something like:
$users="SELECT username FROM usrsys WHERE username IN ('".join("','",$admins)."')";
Where the php function JOIN will print username,username2,username3. Your resulting MySQL statement will look like:
SELECT username FROM usrsys WHERE username IN ('username','username2','username3')
Alternatively, if your looking to iterate through your $query_vars array and separate your admins from non-admins then you could use something like:
<?php
while($row = mysql_fetch_assoc($query_users)){
if(in_array($row['username'],$admins)){
//do admin stuff here
}else{
//do NON-admin stuff here
}
}?>
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
I'm trying to write a simple, full text search with PHP and PDO. I'm not quite sure what the best method is to search a DB via SQL and PDO. I found this this script, but it's old MySQL extension. I wrote this function witch should count the search matches, but the SQL is not working. The incoming search string look like this: 23+more+people
function checkSearchResult ($searchterm) {
//globals
global $lang; global $dbh_pdo; global $db_prefix;
$searchterm = trim($searchterm);
$searchterm = explode('+', $searchterm);
foreach ($searchterm as $value) {
$sql = "SELECT COUNT(*), MATCH (article_title_".$lang.", article_text_".$lang.") AGINST (':queryString') AS score FROM ".$db_prefix."_base WHERE MATCH (article_title_".$lang.", article_text_".$lang.") AGAINST ('+:queryString')";
$sth = $dbh_pdo->prepare($sql);
$sql_data = array('queryString' => $value);
$sth->execute($sql_data);
echo $sth->queryString;
$row = $sth->fetchColumn();
if ($row < 1) {
$sql = "SELECT * FROM article_title_".$lang." LIKE :queryString OR aricle_text_".$lang." LIKE :queryString";
$sth = $dbh_pdo->prepare($sql);
$sql_data = array('queryString' => $value);
$sth->execute($sql_data);
$row = $sth->fetchColumn();
}
}
//$row stays empty - no idea what is wrong
if ($row > 1) {
return true;
}
else {
return false;
}
}
When you prepare the $sql_data array, you need to prefix the parameter name with a colon:
array('queryString' => $value);
should be:
array(':queryString' => $value);
In your first SELECT, you have AGINST instead of AGAINST.
Your second SELECT appears to be missing a table name after FROM, and a WHERE clause. The LIKE parameters are also not correctly formatted. It should be something like:
sql = "SELECT * FROM ".$db_prefix."_base WHERE article_title_".$lang." LIKE '%:queryString%' OR aricle_text_".$lang." LIKE '%:queryString%'";
Update 1 >>
For both SELECT statements, you need unique identifiers for each parameter, and the LIKE wildcards should be placed in the value, not the statement. So your second statement should look like this:
sql = "SELECT * FROM ".$db_prefix."_base WHERE article_title_".$lang." LIKE :queryString OR aricle_text_".$lang." LIKE :queryString2";
Note queryString1 and queryString2, without quotes or % wildcards. You then need to update your array too:
$sql_data = array(':queryString1' => "%$value%", ':queryString2' => "%$value%");
See the Parameters section of PDOStatement->execute for details on using multiple parameters with the same value. Because of this, I tend to use question marks as placeholders, instead of named parameters. I find it simpler and neater, but it's a matter of choice. For example:
sql = "SELECT * FROM ".$db_prefix."_base WHERE article_title_".$lang." LIKE ? OR aricle_text_".$lang." LIKE ?";
$sql_data = array("%$value%", "%$value%");
<< End of Update 1
I'm not sure what the second SELECT is for, as I would have thought that if the first SELECT didn't find the query value, the second wouldn't find it either. But I've not done much with MySQL full text searches, so I might be missing something.
Anyway, you really need to check the SQL, and any errors, carefully. You can get error information by printing the results of PDOStatement->errorCode:
$sth->execute($sql_data);
$arr = $sth->errorInfo();
print_r($arr);
Update 2 >>
Another point worth mentioning: make sure that when you interpolate variables into your SQL statement, that you only use trusted data. That is, don't allow user supplied data to be used for table or column names. It's great that you are using prepared statements, but these only protect parameters, not SQL keywords, table names and column names. So:
"SELECT * FROM ".$db_prefix."_base"
...is using a variable as part of the table name. Make very sure that this variable contains trusted data. If it comes from user input, check it against a whitelist first.
<< End of Update 1
You should read the MySQL Full-Text Search Functions, and the String Comparison Functions. You need to learn how to construct basic SQL statements, or else writing even a simple search engine will prove extremely difficult.
There are plenty of PDO examples on the PHP site too. You could start with the documentation for PDOStatement->execute, which contains some examples of how to use the function.
If you have access to the MySQL CLI, or even PHPMyAdmin, you can try out your SQL without all the PHP confusing things. If you are going to be doing any database development work as part of your PHP application, you will find being able to test SQL independently of PHP a great help.