How do I show a user's credit based on their session - php

I'm developing a simple LAMP app where users can credit their account using Paypal. I suspect this is a simple issue, but have spent quite a while experimenting to no avail and would appreciate any thoughts:
System has a user management system working fine using sessions, but I can't get it to display the current user's credit.
But I've been trying things along the lines of:
$result = mysql_query("
SELECT *
FROM users
INNER JOIN account
ON account.UserID=account.UserID
ORDER BY account.accountID");
while($_SESSION['Username'] = $row['Username'] )
{
echo $row['Username'];
echo $row['Credit'];
}
I suspect the while statement is invalid, but I want it to echo username and credit where the current session username = the username stored in the database.
Thanks so much for taking a look - very much appreciated.

Okay there is actually a lot wrong with your code that can not be fixed by you as you have obviously no knowledge of php at all.
But let me explain this so you can get a good understanding of what you did wrong:
First of all, your mysql statement is just wrong.
Why do you join a field on itself? You won't get the corresponding users <-> account rows because users is never actually joined.
In addition to that, if you want to fetch a single row (you only want one because you only want to echo the data of one user, fetching more is only heavier in resources), tell mysql to do that. A simple example would be "WHERE a="b" LIMIT 1 (select only row where a is equal to "b", return after finding the first).
Now, to read something from your query, you need to fetch the corresponding data.
You can do that by using mysql_fetch_assoc / mysql_fetch_array / mysql_fetch_object.
This would look something like this: $data = mysql_fetch_array($query);.
In this case, you don't need to use a while() loop as you only have one row. A while loop is only necessary if you want to work with more then one row.
The rest of your code would be correct, though you don't need to call echo twice. You can simply connect both variables with a ".": echo $row['Username'].$row['Credit'];.
If you want to insert a space in between, connect it with another dot: echo $row['Username']." ".$row['Credit'];.

while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
if ($row['Username'] == $_SESSION['Username'])
{
echo $row['Username'];
echo $row['Credit'];
break; // I believe username is unuque.
}
}
But it's much better to get just 1 row from the table :
$result = mysql_query("
SELECT *
FROM users
INNER JOIN account
ON account.UserID=users.UserID
WHERE Username ='".mysql_real_escape_string($_SESSION['Username'])."'" );
if ($result && $row = mysql_fetch_array($result, MYSQL_ASSOC))
{
echo .....
}

You only have a mysql result, now you have to return that information as an associative array (or object)
while ($row = mysql_fetch_assoc($result)) {
if ($_SESSION['username'] == $row['Username']) {
echo $row['Username'];
echo $row['Credit'];
}
}
It appears as if you are using $_SESSION['username'] as a way to check user authentication on the site, much better to use a salted+hashed version of the username and possibly the login time (never include the password).

One thing that jumps out at me is that your query is joining on:
account.UserID=account.UserID
instead of:
account.UserID=user.ID
Also, this is not right:
while($_SESSION['Username'] = $row['Username'] )
The = sign is for assignment, not comparison, so you're actually setting the value of $_SESSION['Username'] to $row['Username']. Then, the expression is evaluated as a boolean (since it's within a while conditional), and if it's true once, it'll be true forever. Infinite loop city.

Related

How do I get only one value for the data I fetched from database using fetch function

I am new to php and had chosen to stick to PDO format. I have been able to set up a workable registration and login system, but my challenge is fetching data from my database which would be used in other page of the user profile page I created. I had tried all the many examples and methods I was able to get on the internet but there are not working, or rather I don't know how to use it, where I want to insert the variable will still be empty.
The only fetch function I was able to get will select all the row, for instance, if it is email, it will fetch all the registered emails in the database which is not suppose to be. The email should only be for the user whose profile is opened.
Here are the codes. I am sure someone will help me figure this out. Thanks
$data = $pdo->query("SELECT * FROM databaseName")->fetchAll();
//this one is in the body where i want to insert the email
foreach ($data as $row) {
echo $row['email']."<br />\n";
}
I tried everything my little knowledge of php but all to no avail. If i decide to use any other one, nothing will show.
You can try other alternative to achieve the same,
$stmt = $pdo->query('SELECT * FROM databasetable');
while ($row = $stmt->fetch())
{
echo $row['email'] . "\n";
}
If you are only interested in the email from the returned results, I would look to do the following:
$stmt = $pdo->query('SELECT `email` FROM databasetable');
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
echo $row['email'] . "\n";
}
Or
$stmt = $pdo->query('SELECT `email` FROM databasetable');
$data = $stmt->fetchAll(PDO::FETCH_ASSOC))
foreach($data as $row)
{
echo $row['email'] . "\n";
}
If you want to check that the data coming back is good, I would add a "print_r($data);".
You can just take the first element of the results.
$stmt = $pdo->query('SELECT `email` FROM databasetable LIMIT 1');
$data = $stmt->fetchAll(PDO::FETCH_ASSOC)[0];
or use fetch()
$stmt = $pdo->query('SELECT `email` FROM databasetable LIMIT 1');
$data = $stmt->fetch(PDO::FETCH_ASSOC);
I´ve also put a LIMIT at the end of your query, so you dont fetch unneeded data.
Unless I am missing something then surely you should be specifying a where in your SQL query, why would you get the entire database and loop through it until you find the email you want?
When you redirect the logged in user you must(or if you aren't then you should) be passing something about the user, e.g setting the userid in the session. Then you can use this to create more useful profile data with a query that says select email from table where userid = :userid - then when you fetch the result you will have the data you need.
Naturally I can't write the exact query without knowing your structure but getting a whole tables worth of data every time is unscalable

Alternate to mysqli_num_rows for this php script

I know this has been asked a lot but I can't find no other method that does not relate to num_rows I basically want to see if a record a exist in the database in a if else statement and in other words I don't mind using it but for personal complicated reasons I need to stay away from that because it conflicts on other things I want to add down the road. So this is my code example is there another way to do this with out using mysqli_num_rows?
<?php
$servername='localhost';
$username='angel';
$password='1234';
$db_name='test';
$connect= new mysqli($servername,$username,$password,$db_name);
$query="SELECT*FROM members WHERE first_name='bob'";
$result= $connect->query($query);
if($result->num_rows >0){
echo 'Exist';
}
else{
echo 'Does not exist';
}
?>
just to fill in the options pool
$query = "SELECT id FROM members WHERE first_name='bob'";
then check you get an id returned; assuming the table has an id column, if not just use another one
You could issue a separate query where all you do is count the results:
$getCount = "SELECT COUNT(*) AS `MemberCount` FROM members WHERE first_name='bob'";
Then use the results to determine your program's path.

Is it bad to put a Query inside an while loop?

I built a Query inside an While loop to get the status from my users. Is there any problem by doing that?
I would like to do it in a different way.
My code.
$output = array();
while($row = mysqli_fetch_assoc($result))
{
if ($row['user_id'] != $id)
{
$checkstatus= mysqli_query($con,"SELECT session_id, status FROM frei_session WHERE session_id = '".$row['user_id']."' ");
$status = mysqli_fetch_row($checkstatus);
if(!$status[0]){
$row['status'] = 0;
}
$output[] = $row;
}
}
$json = json_encode(array("contacts" => $output ));
print($json);
Thank you.
It will blow up your code and can result in very bad performance, escpecially when your main query is returning a lot of rows. A SQL-Server can connect different tables much more efficient by using Joins. For me it seems like a good scenario to use them here. Especially the LEFT-JOIN can be usefull to load a session. It will return NULL for the requested fields when there is no session connected with the current user.
But because I don't even know your main query or much less the use behind your code, you've to decide whether a user without a session makes sense in your case. If not, use a EQUAL-JOIN instead. Then your query wouldn't return any data if no session exists.
An example how can such a JOIN can look when you've two tables USER and SESSION:
SELECT user.username, user.email,
session.status AS session_status
FROM user, session
WHERE user.userid = 123
AND session.session_id = user.user_id
I don't see any problem with having a query like yours inside the while loop. It would become problematic if the query was inefficient (imagine if the query would return 10 lines and you would only use/need 1), but you are targeting your user in the where clause, so it's OK.

PHP, admins usersystem

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
}
}?>

mysql - strange thing with update and select statements

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.

Categories