Using a Drupal variable in SQL query - php

I'm trying to stuff a variable into a SQL query to return a value to a page.
$sql = 'SELECT account FROM users WHERE uid = arg(1)';
Where arg(1) = the user currently being viewed. I am outputting arg(1) at the top of the page, so I know it's there, but Drupal doesn't seem to want to take it. I've tried escaping several different ways. Below is the full code
function accountselect_getclientaccount() {
global $user;
$sql = 'SELECT account FROM users WHERE uid = arg(1)';
$result = db_result(db_query($sql));
return $result;
}

You could try:
$uid = arg(1);
$result = db_result(db_query("SELECT account FROM {users} WHERE uid = %d", $uid));

To avoid sql-injection, you should use placeholders (see db_query for more info):
$result = db_query("SELECT * FROM {users} WHERE uid = %d", arg(1));
Also note that db_result is meant for single-column, single-result queries. You probably want to use db_fetch_object. Additionally, there isn't a column in the users table called account.

function accountselect_getclientaccount() {
return (arg(0) == 'user') ? db_result(db_query('SELECT account FROM {users} WHERE uid = %d', arg(1))) : FALSE;
}
I don't know why you're using the global $user. Maybe you should be using $user->uid instead of arg(1)? This would save you checking arg(1) is actually a user ID.
This might be better:
function accountselect_getclientaccount($account) {
return db_result(db_query('SELECT account FROM {users} WHERE uid = %d', $account->uid));
}
Also: see the user hook. It might be best practice to return the 'account' col on the load operation (if you're not doing that already)
http://api.drupal.org/api/function/hook_user/6

Related

how to upgrade designation in php data

i am working with a mlm company's site where i hv to design to upgrade the status of member from one step to higher after adding 5 members every member has to upgrade to upper level.i have some code but i dont know how to call this function
here is my code:-
function CheckAndUpgradeDesignation($username,$des)
{
if($des=='Crown')
return;
$q="SELECT introducer_id FROM members WHERE user_id='$username'";
$rs=mysql_query($q);
$r=mysql_fetch_array($rs);
$id=$r['introducer_id'];
$q="SELECT count(*) as total from members WHERE introducer_id='$id' AND designation='$des'";
$rs1=mysql_query($q);
$r1=mysql_fetch_array($rs1);
$t=$r1['total'];
if($t==5)
{
if($des=="VIP")
$des1="Journey";
else
if($des=="Journey")
$des1="Executive";
else
if($des=="Executive")
$des1="DreamFlight";
else
if($des=="DreamFlight")
$des1="Safari";
else
if($des=="Safari")
$des1="GoldRace";
else
if($des=="GoldRace")
$des1="RoyalRace";
else
if($des=="RoyalRace")
$des1="Aashiyana";
else
if($des=="Aashiyana")
$des1="Crown";
$q="UPDATE members SET designation='$des1' WHERE user_id='$id'";
mysql_query($q);
CheckAndUpgradeDesignation($id,$des1);
}
}
pls check anyone is this code looks right or need some change...............if u hv some question ask me
You would call the function like this: CheckAndUpgradeDesignation('1', 'GoldRace');
Also you might rename the function parameter $username to $userid, because the SQL uses user_id.
Please escape the values inserted into the SQL statment properly to avoid injections.
Maybe refactor the function into 3 functions:
fetchDesignation($user_id) - which returns the designation for a user_id
raiseDesignation($des) - which is the logic part to level up and returns the new level or false
updateDesignation($user_id, $des) - which inserts the new level into the db
This suggestions is a bit more flexible, but it depends on the use case.
It allows testing the logic for raiseDesignation() in a seperate unit-test, without touching the db. Also fetching the designation for a user_id is now seperate.
I could refactor your code separating some important tasks. In the other hand, I recommend you don't try to write large functions with lot of code, because it could be no easy to understand.
<?php
function CheckAndUpgradeDesignation($userId, $designation)
{
if ($designation == 'Crown') {
return;
}
$introducerId = GetIntroducerIdByUserId($userId);
$memberTotal = GetTotalOfMembersByIntroducerIdAndDesignationId($introducerId, $designation);
if ($memberTotal == 5) {
$designationValue = VerifyDesignation($designation);
UpdateDesignation($designationValue, $introducerId);
CheckAndUpgradeDesignation($introducerId, $designationValue);
}
}
function VerifyDesignation($designation)
{
$designationList = array(
'VIP' => 'Journey',
'Journey' => 'Executive',
'Executive' => 'DreamFlight',
'DreamFlight' => 'Safari',
'Safari' => 'GoldRace',
'GoldRace' => 'RoyalRace',
'RoyalRace' => 'Aashiyana',
'Aashiyana' => 'Crown'
);
if (key_exists($designation, $designationList)) {
return $designationList[$designation];
}
return null;
}
function GetIntroducerIdByUserId($id)
{
$query = "SELECT introducer_id FROM members WHERE user_id='$id'";
$result = mysql_query($query);
$response = mysql_fetch_array($result);
return $response['introducer_id'];
}
function GetTotalOfMembersByIntroducerIdAndDesignationId($introducerId, $designation)
{
$query = "SELECT count(*) as total from members WHERE introducer_id='$introducerId' AND designation = '$designation'";
$result = mysql_query($query);
$response = mysql_fetch_array($result);
return $response['total'];
}
function UpdateDesignation($designationValue, $introducerId)
{
$query = "UPDATE members SET designation='$designationValue' WHERE user_id = '$introducerId'";
mysql_query($query);
}
Also check VerifyDesignation function it could be more efficient instead use multiple if statements.
I hope it can help you.

Is using mysql_num_rows (rowCount in PDO) necessary in update or insert query?

Should I be using mysql_num_rows (rowCount in PDO) in update or insert query?
Currently, my code looks likes this,
public function update_username(){
$q = "UPDATE usertable SET username = '$user_name' WHERE id = '$user_id' LIMIT 1";
$r = $db->query($q);
if($r){
$message = "Updated successfully";
return $message;
}else{
return false;
}
}
Should I change it to like this?
public function update_username(){
$q = "UPDATE usertable SET username = '$user_name' WHERE id = '$user_id' LIMIT 1";
$r = $db->query($q);
if($r){
$num = $r->rowCount();
if($num == 1){
$message = "Updated successfully";
return $message;
}else{
$message = "An error occurred";
return $message;
}
}else{
return false;
}
}
Normally, query goes through without any error, so I shouldn't worry about it too much, but which one would be a better coding practice? Or do you suggest something else?
Thanks so much in advance!
Actually the two codes do something different.
The first one will print "Update success" if the query was successfully executed. But a query can be successfully executed also without affecting any row, i.e. you have a WHERE statamenet that does not match. The second code will not print "Update success" if no rows were affected.
Of course, if you're sure that your WHERE statement has to match, you can use both codes without any difference and using the second one could help you to spot any potential bug, i.e. it doesn't match and so something went wrong (probably the id was different from the one you expected).
Generally, to answer your question, mysql_num_rows is needed only if you want to know how many lines were affected. It's not mandatory at all to use it.
So, it depends on what you want. Both are good, but they are different.
If you are 100% sure the variables are created by you and not someone else you can do it like that, but you can minimize the code more:
public function update_username(){
$q = "UPDATE usertable SET username = '$user_name' WHERE id = '$user_id'";
if($db->query($q)){
return "Updated successfully";
}
return false;
}
First, because a query is executed successfully, doesn't necessarily mean that anything has been updated. So if you need to distinct the difference between a queries validity or the update change, then yes, rowCount would be a good practice.
Second, a prepared statement would be more wise to use when assigning variables (SQL injection, etc).
public function update_username(){
$q = "UPDATE usertable SET username = :user_name WHERE id = :user_id LIMIT 1";
$r = $db->prepare($q);
$r->bindValue(':user_name', $user_name);
$r->bindValue(':user_id', $user_id);
if($r->execute()){
$message = "Updated successfully: updated ".$r->rowCount();
return $message;
}else{
return false;
}
}
To avoid code duplication, maybe you should consider avoiding writing the same execution code for a query, and move that to a method/function which does that all for you, e.g
public function validateStmt($r) {
// validate query
if($r->execute()) {
// check result set
if($r->rowCount() > 0) {
return $r;
}
else {
// if a result set IS expected, then you might consider to handle this as
// a warning or an error
}
}
else {
// query invalid
}
}
Depending on the situation, you will have to choose which part you should use. mysql_num_rows() is used to check how many rows have been affected from your query you have executed. So, it's up to you to decide whether it is really necessary to add the mysql_num_rows() function in to your code or not.

PHP convert session variable from array into int

I am storing session information in an array called 'Auth'. That array contains 2 session information: id and password. My problem is when I am using the id info for quering, it is not working. I am pretty sure it is due to the fact that the id info in my table is an int, and the one from the session array isn't. So my question is to know how to convert that session id variable into an int. Here below the function in which I am using $_SESSION(['Auth']['id']). Thank you in advance for your replies. Cheers. Marc
The PHP code where I am using the session info:
<?php
session_start();
header('Content-Type: text/html; charset=utf-8');
require("connect.inc.php");
function isLogged(){
if(isset($_SESSION['Auth']) && isset($_SESSION['Auth']['id']) && isset($_SESSION['Auth']['pass'])){
extract($_SESSION['Auth']);
$result = mysql_query("SELECT * FROM usr_users WHERE usr_id = '$id' AND usr_pass = '$pass'");
if(mysql_num_rows($result)==1){
return true;
}
else{
return false;
}
}
}
?>
Here the PHP code where I set the session info:
<?php
session_start();
header('Content-Type: text/html; charset=utf-8');
require("connect.inc.php");
$identifiant = mysql_real_escape_string($_POST['identifiant']);
$pass = sha1($_POST['pass']);
$result = mysql_query("SELECT * FROM users WHERE usr_pseudo = '$identifiant' AND usr_pass = '$pass'");
if(mysql_num_rows($result)==1){
$data=mysql_fetch_assoc($result);
$_SESSION['Auth']=array(
'id'=>$data['usr_id'],
'pass'=>$pass
);
}
echo mysql_num_rows($result);
?>
extract() is a horribly ugly function, and you should wipe its existence out of your mind.
There's no need for it, since it's purely a holdover from PHP's early "lazy" days, when it tried to do everything for you, causing in part the miserable security reputation PHP has.
You can directly embed session variables wherever you want, even when it's an arbitrarily "deep" array reference like your session is:
$sql = "SELECT ... WHERE id={$_SESSION['Auth']['id']} ...";
or even
$id = $_SESSION['Auth']['id']'
$sql = "SELECT ... WHERE id=$id";
will both work the same way, and not litter your variable namespace with useless junk.
You can cast any variable into any type by using the cast methods.
$usr_id = (int)$data['usr_id']
This would return a type of integer. If the id includes anything else but integers, 0 is returned.
http://php.net/manual/en/language.types.type-juggling.php
You should not query DB each time you'd like to check if the user is logged in. And you don't need to store password in the seesion.
You have to query db only once when you login user (your second part of the code).
And it would be better if you create a simple wrapper for your auth logic. Something like this simple class with static functions:
<?php
class Auth
{
public static function login($identifiant, $password)
{
// query db then
// $_SESSION['Auth']['id'] = value from db
return self::id();
}
public static function isLogged()
{
return (bool)self::id()
}
public static function id()
{
return (isset($_SESSION['Auth']['id'])) ? $_SESSION['Auth']['id'] : false)
}
public static function logout()
{
$_SESSION['Auth'] = array();
}
}
// usage
Auth::login($_POST['identifiant'], $_POST['password']);
if (Auth::isLogged()) {
$sql = "select * from posts where user = " . Auth::id() . "";
}
Auth::logout();
If you are "pretty sure it is due to the fact that the id info in (your) table is an int, and the one from the session array isn't".
Then here's a simple way to convert your session id from array into a variable (cast it).
$id = (int)$_SESSION['id'];
Hope it helps.
you should not enclose integers in single quotes in the SQL
try this
$result = mysql_query("SELECT * FROM usr_users WHERE usr_id = $id AND usr_pass = '$pass'");

Formatting array output using foreach function

I have a script that follows that is supposed to collect data from a field"UserID" in my sql table, submit all data into an array, and then compare a variable to whats in the array. If the value of the variable is already in the array, tell the user that that value is invalid.
$sql = "SELECT *" //User info
. " FROM Users" ;
$result = mysql_query($sql);
//insert where line for assessorid
$users = array();
while(($user = mysql_fetch_assoc($result))) {
$users[] = $user;
}
foreach($users as $user){
$user['UserID'];
}
I need the output of $users to be equivalent to array('user1','user2','user3');
Whats happening is data comes in from a form as $user_name. I want to use this in a statement like follows:
if(in_array($user_name,$users)){
echo "username available"
}
else{
echo "not available"}
I tried using the extract function, but that just created a big mess.
Im not sure what is incorrect about what I'm doing, unless the format of $users as an array cannot be parsed in the in_array() function as it is formatted currently. Any advice is much appreciated. Thanks!
$sql = "SELECT USERID FROM Users" ;
$result = mysql_query($sql);
$users = array();
while(($user = mysql_fetch_assoc($result))) {
$users[] = $user['USERID'];
}
When you are saying
$users[] = $user;
You are not specifying which column in the result set to be appended to the array.
Maybe I am missing something... Why not do it like this:
SELECT UserID FROM Users WHERE Username = 'username'
Then just use mysql_num_rows() to check if the username already exists or not. This should be both faster and more efficient (memory-wise).
In that case, you collect all data from the database and need to do some inefficient processing in PHP as well. It is better to query for that value to see if it is in the database, so:
$username = mysql_real_escape_string($username);
$query = "
select
count('x') as usercount
from
users u
where
u.username = '$username'";
The, if the 'usercount' is 0, the username does not exist. If > 0, the username does exist. This way, you let the database do the work it is designed to do, and the only value that is actually retreived is that single number.
Have you tried modifying your query? Currently you are getting all of the values for every user, but you just seen to need UserID. You could do this:
$sql = "SELECT UserID FROM Users";
$result = mysql_query($sql);
$users = array();
while(($user = mysql_fetch_assoc($result)))
{
$users[] = $user['UserID'];
}
// ...
if (in_array($user_name, $users))
{
echo 'Username not available';
}
else
{
echo 'Username available';
}
Or you could just look up in the database for the given username:
$sql = 'SELECT count(*) FROM Users WHERE UserID = '.mysql_escape_string($user_name);
$result = mysql_query($sql);
// and then just check if the resulting row is equal to 0
Are you attempting to write a script that will check if a username is taken?
If so, it may be easier (and more efficient) to structure the actual query towards this end rather than relying on the programmatic approach.
$sql = "SELECT COUNT(*) FROM Users WHERE Username = '$username'";
Then you could apply this result to a count and allow the user to register or not based on whether a value greater than zero (a user has already taken that name) or not (its free) is returned.
As has been mentioned, that is a rather inefficient way to check for an existing username. The suggestions for modifying your query are good advice.
However, to address the problem with the code you provided:
in_array() will not detect the presence of a value in a multi-dimensional array. Your $users array probably looks something like this:
$users = array(
array('userID', 'foo', 'bar'),
array('userID', 'foo', 'bar'),
array('userID', 'foo', 'bar')
)
and in_array will not search below the first set of indexes. If this is really what you want to do, see this question: in_array() and multidimensional array

PHP get result string from PostgreSQL Query

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.

Categories