MySQL prepare statement using variable - php

I am using below PHP + MySQL prepare statement to select values from database, passing the variable into the statement using function, however I could not get my wanted result. The problem is I don't know how to using the variable in the prepare statement.
Question:
Could you take a look whether the syntax I am using is correct?
public function getToken($committeeValue){
$stmt = $this->conn->prepare("SELECT u.token FROM users u INNER JOIN committee c ON u.email = c.email WHERE c.'$committeeValue' = 1");
$stmt->execute();
}

Please try the below one.
public function getToken($committeeValue){
$stmt = $this->conn->prepare("SELECT u.token FROM users u INNER JOIN committee c ON u.email = c.email WHERE c.".$committeeValue." = 1");
$stmt->execute();
}
I think you are made a mistake to appending a php variable within the string.Please try this.

You made the mistake of concatenating string in PHP.
So please try this below:
public function getToken($committeeValue){
$committeeValue = trim($committeeValue);
if(!empty($committeeValue)){
$query = "SELECT u.token FROM users u INNER JOIN committee c ON u.email = c.email WHERE c.".$committeeValue." = 1";
$stmt = $this->conn->prepare($query);
$stmt->execute();
}
}

Using var content directly is not safe because it allow to inject SQL statements.
The safe way is, in your case:
public function getToken($committeeValue){
$committeeValue = trim($committeeValue);
if(!empty($committeeValue)){
$query = "SELECT u.token FROM users u INNER JOIN committee c ON u.email = c.email WHERE c.? = 1";
$stmt = $this->conn->prepare($query);
$stmt->bindParam(1, $committeeValue);
$stmt->execute();
}
}
The query will be compiled without the var content so you dont have to worry about SQL injection.

Related

PHP, PDO, SQLite INNER JOIN Statement And Variable

I need to do a PHP PDO call to my db with an INNER JOIN and WHERE clause.
In navicat GUI this statement is running fine and i can see the results. The problem come out lather in php environment about string concatenation.
I would like to format this request so that it can be digested by php:
SELECT * FROM tsourcetb as T INNER JOIN users as U ON U.username = T.username WHERE U.username = $username AND T.username = $username;
what I tried to do
$sth = $db->prepare("SELECT * FROM tsourcetb as T INNER JOIN users as U ON U.username = T.username WHERE U.username = $username AND T.username = $username");
the return is an error indicating that there is no table with the variable name. Basically it takes the variable as the name of the table the return is an error indicating that there is no table with the variable name. Basically it takes the variable as the table name and not the table name as it should like (SELECT * FROM $username) jumping out the first part of statement).
The intent is to have all the records of table A where the username field is = to the username field of table B with value passed from a variable.
Thank for any suggestion to achieve my goal.
UPDATE
php is magic need to try and retray. At the end tish one help me to goal:
$username = ($_POST['username']);
$password = ($_POST['password']);
$statement = $db->prepare('SELECT p.* FROM `tsourcetb` as p LEFT JOIN `users`as s ON p.username = s.username WHERE s.username = :username;');
$statement->bindParam(':username', $username, PDO::PARAM_STR);
$statement->execute();
/* look here -> $statement->fetchall(PDO::FETCH_ASSOC) */
$array_select = $statement->fetchall(PDO::FETCH_ASSOC);
echo json_encode($array_select, JSON_PRETTY_PRINT);
<?php
$sth = $db->prepare("SELECT * FROM `tsourcetb` as T INNER JOIN users as U ON U.username = T.username WHERE U.username = ? AND T.username = ? ");
$sth->execute([$username,$username]);
$results = $sth->fetchall();
?>
wrapper your table name with backticks and also use placeholders
Try this:
$stmt = $db->prepare("SELECT * FROM tsourcetb as T INNER JOIN users as U ON U.username = T.username WHERE U.username = :username AND T.username = :username");
$stmt->bindValue(':username', $username, PDO::PARAM_STR);
$stmt->execute();
You need to bind a value with prepared statement:
Source: Docs
You have to bind parameters when you are making an dynamic query with PDO.
Change this in your query.
$username -> :username
And before you make the call
$yourQueryObj->bindValue(':username', $username, PDO::PARAM_STR);
That's why prepared statments are safer than regular variables as you assign it's type before it's sent for query.
You can read about it here
http://php.net/manual/en/pdostatement.bindvalue.php
You should be able also execute with array of parameters after preparing like that :
$sth = execute(array(':username'=> $username));

What is the correct syntax for this PHP based SQL statement?

I have the following SQL statement which has been verified as working:
INSERT INTO community_players (community_id, player_id)
SELECT communities.id, users.id
FROM communities INNER JOIN users ON communities.admin = users.user_email
WHERE users.user_email = 'steve.downs#gmail.com'
AND communities.code = 'HX99f9'
I now want to replace the dummy email and community code data with the variables in the below php function, and submit it to the database.
This is my function:
public function insertNewAdminIntoCommunity($email, $code)
{
$sql = "insert into community_players (community_id, player_id) select communuities.id, users.id from communuities inner join users on communities.admin = users.user_email where users.user_email = '".$email."' and communities.code = '".$code."'";
$statement = $this->conn->prepare($sql);
if(!$statement) throw new Exception($statement->error);
$statement->bind_param("ss", $email, $code);
$returnValue = $statement->execute();
return $returnValue;
}
However it is throwing out errors back into Xcode - II thought maybe I have incorrect syntax when trying to use the variables in the function within the sql statement?
Any ideas?
Thanks
You should not concatenate the variables into the SQL string, as you do here:
users.user_email = '".$email."' and communities.code = '".$code."'";
as that defeats the whole purpose of prepared statements. Prepared statements help protect against SQL-injection, by allowing you to define placeholders that will be replaced with properly escaped values.
You should therefore use placeholders (question marks, without surrounding quotes):
users.user_email = ? and communities.code = ?";
What $statement->bind_param("ss", $email, $code); then does, is bind your variables to the two placeholders. Each s of the first argument signifies that the respective values should be treated as a string.1 MySQL takes care of properly escaping the values this way.
The error therefore most likely is telling you that you are trying to bind values to non-existent placeholders.
See the mysqli_stmt::bind_param() documentation for more available options.
You have a communuities in some field and communities in others
be sure you are using the proper table name in all case
$sql = "insert into community_players (community_id, player_id)
select communuities.id, users.id
from communuities
inner join users on communities.admin = users.user_email
where users.user_email = '".$email."' and communities.code = '".$code. "'";
and i suggest the use PDO with binding param instead string concat ..(and others connections)

Prepared statement, loop results to get more results

I have a query where I'm taking several results from a single table. I then need to loop through each result to get information from other tables, however, I can't get it to work.
Here's my code:
<?php
$type = 1;
if ($stmt = $cxn->prepare('SELECT username FROM users WHERE type = ?')) {
$stmt->bind_param('i', $type);
$stmt->execute();
$stmt->bind_result($username);
while ($stmt->fetch()) {
if ($stmt = $cxn->prepare('SELECT count FROM posts WHERE username = ?')) {
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->bind_result($result2);
$stmt->close();
}
}
$stmt->close();
}
?>
I get an error:
Call to a member function fetch() on a non-object
How do I fix this?
I would highly recommend a native SQL JOIN for this because it will avoid unnecessary overhead in sending potentially thousands of queries:
SELECT
u.username,
p.count
FROM
users u
LEFT JOIN // processed as LEFT OUTER JOIN so the syntax is interchangeable just fyi
posts p
ON u.username = p.username
WHERE
p.type = ?
Explaining LEFT JOIN only, we'll keep it simple =)
In the SQL above we start with username from the users table as a whole
users u just grants us the shortcut syntax for u.username so that SQL is readable and doesn't fubar
Next we want to attach the posts p table where u.username = p.username because we need the p.count for each username
Lastly we filter this conglomerate of data based on p.type being equal to something
Please note that are many things at play here depending on the DBMS. Such things include query optimizers, the exact point of filtering, etc... but that is far outside the scope of simply getting the hang of what we are trying to achieve conceptually so I will not go into detail because it will only cause confusion.
You are overwritting your stmt variable. You should use another one, like
$type = 1;
if ($stmt = $cxn->prepare('SELECT username FROM users WHERE type = ?')) {
$stmt->bind_param('i', $type);
$stmt->execute();
$stmt->bind_result($username);
while ($stmt->fetch()) {
if ($stmtCnt = $cxn->prepare('SELECT count FROM posts WHERE username = ?')) {
$stmtCnt->bind_param('s', $username);
$stmtCnt->execute();
$stmtCnt->bind_result($result2);
$stmtCnt->close();
}
}
$stmt->close();
}

Prepared statements for zend

I am using zf1. The Modal query is:
$select = $postTable->select()
->setIntegrityCheck(false)
->from('posts')
->joinLeft('users', 'users.id = posts.user_id', array('post_first_name' => 'first_name'))
->where('posts.property_id = ?', $id);
$postTable->fetchAll($select);
I am trying to use prepared statement for this query. I haven't figured out how to convert this into prepared statement so please help me by converting this query into prepared statement.
just use like below
$params = array($property_id);
$sql = "SELECT post_first_name as first_name " .
"FROM posts" .
"left join users on users.id = posts.user_id WHERE posts.property_id = ?";
$stmt = $db->query($sql, $params);
$dealers = $stmt->fetchAll();
above is just procedure code you can set your column name and table name as you require.
Hope this will sure help you.

Using two queries at the same time. PDO

Okay so, I don't really know anything about PDO, my friend just asked me to post this here since he's not very good at English. Anyway, this is how he explained it to me:
The code provided is supposed to get a couple of values, save them, and it's supposed to get something out of another table with the help of the values gotten from earlier. The problem according to my friend is that it doesn't get the second value.
Code:
$user_email = $_SESSION['user_email'];
$query = $db->prepare("SELECT username,id,password FROM user WHERE email=:email");
$query->bindParam(':email', $user_email, PDO::PARAM_INT);
$query->execute();
$row = $query->fetch();
$user_username=$row['username'];
$user_group=$row['group'];
$query_group = $db->prepare("SELECT color,name FROM group WHERE id=:id");
$query_group->bindParam(':id', $user_group, PDO::PARAM_INT);
$query_group->execute();
$row = $query_group->fetch();
$group_color=$row['color'];
$group_name=$row['name'];
The word group used as a table name needs to be enclosed in backticks. group is a reserved key word (GROUP BY clause).
SELECT
color,
name
FROM `group`
WHERE id = :id
Using the above would work.
You can shorten the entire code by using a JOIN clause too. As commented above by Prix, the code shall be:
$user_email = $_SESSION['user_email'];
$query = $db->prepare("SELECT
u.username,
u.id,
u.password,
g.color,
g.name
FROM user u
JOIN `group` g
ON g.id = u.id
WHERE u.email = :email");
// I think emails are supposed to be `PDO::PARAM_STR`
$query->bindParam(':email', $user_email, PDO::PARAM_INT);
$query->execute();
$row = $query->fetch();
$user_username = $row['username'];
$group_color = $row['color'];
$group_name = $row['name'];
You don't have group in your select statement .
If you don't use * in your select you must have the field name in your query .
$query = $db->prepare("SELECT username,id,password FROM user WHERE email=:email");
This query gives you only username,id,password back NOT the field group .
so try to use $row['group'] is wrong .
$user_group=$row['group'];
So also put group in your select statement
Place also group in backticks it's a reserved word
$query = $db->prepare("SELECT id, username, password, `group` FROM user WHERE email=:email");
This is also a reason for important variables (e.g for next query) to consider their validity.
if (isset($row['group'])) {
database logic
} else {
error
}
With this simple test you would have found the error itself.

Categories