I need to execute a sql query where I need to use a apostrophe because I search for an email address. When I now type the '' in the query they become a variable pointer but they should just tell mysql that this is a string.
How can I tell the program to use them in a different way? I already tried pdo->quote.
$statement = $pdo->prepare("SELECT user_id FROM tbl_server WHERE user_id = (SELECT user_id from tbl_user where Email = ':email') "); // here i need the normal apostrophe
$result = $statement->execute(array('email' => $email));
$user = $statement->fetch();
You must not quote :email in the query; the database driver will determine how to handle the parameter because it knows the passed type and the column's type in the database. But you need to prepend the : to email when executing the parameterized query.
$statement = $pdo->prepare("SELECT user_id FROM tbl_server WHERE user_id = (SELECT user_id from tbl_user where Email = :email) "); // here i need the normal apostrophe
$result = $statement->execute(array(':email' => $email));
$user = $statement->fetch();
By the way you should check whether $result is true or false, also your query might deliver an empty result set. So you should check whether $user === false (i.e. no user found) after fetching.
Related
I am working on a reservation system for a local resort which is accessed via reasonably secure LAN only, as such I am not immediately concerned with SQL injection. My main concern is the functionality to lookup up reservations based upon the PK(s) returned by a query on individual guests. To do this, I have been using the mysqli query object returned by a query of a table containing guest information:
$get_guest_id = "SELECT id FROM guests WHERE fname = '$fname' OR lname = '$lname' OR phone = '$phone' OR email = '$email'";
$guest_id_result = mysqli_query($con, $get_guest_id);
I have tried using this query object as I would a set within mySQL:
$search_by_id = "SELECT * FROM reservation WHERE guest_id IN '$guest_id_result'";
But this does not return as expected:
Returns false on failure. For successful queries which produce a result set, such as SELECT, SHOW, DESCRIBE or EXPLAIN, mysqli_query() will return a mysqli_result object. For other successful queries, mysqli_query() will return true.
Rather than returning true, false, or a result set, the PHP script stops executing at this statement.
Is there a different way to pass the data contained within a mysqli query object to another query, in a manner similar to a set?
The problem is that you're trying to cast an object into a string for your query...
The best solution would probably be to turn the two queries into a singular one, additionally updating the code to use a prepared statement.
Query
SELECT * FROM reservations
WHERE guest_id IN (SELECT id
FROM guests
WHERE fname = ?
OR lname = ?
OR phone = ?
OR email = ?
);
Code
$sql = "
SELECT * FROM reservations
WHERE guest_id IN (SELECT id
FROM guests
WHERE fname = ?
OR lname = ?
OR phone = ?
OR email = ?
);
";
$query = $con->prepare($sql);
$query->bind_param("ssss", $fname, $lname, $phone, $email);
$query->execute();
$result = $query->get_result();
while ($row = $result->fetch_assoc()) {
echo $row["guest_id"], PHP_EOL; // Example output printing the guest_id of guests with reservations (followed by a newline)
}
Here I want to add another variable using AND.
$query = $db->prepare("SELECT *
FROM messages WHERE Subject_Code = ' ".$_SESSION['sub1']." ' ");
I want to add Week = ' ".$_SESSION["weekS1"]." ' to this query using AND. How can I do it?
PHP PDO supports positional (?) and named (:email) placeholders, the latter always begins from a colon and can be written using letters, digits and underscores only. Also note that no quotes have to be ever used around placeholders.
Eg:
The following becomes
$sql = "SELECT * FROM users WHERE email = '$email' AND status='$status'";
To
$sql = 'SELECT * FROM users WHERE email = ? AND status=?';
OR
$sql = 'SELECT * FROM users WHERE email = :email AND status=:status';
With placeholders, you have to prepare it, using the PDO::prepare() method
To get the query executed, you must run execute() method of this object, passing variables in it, in the form of array
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ? AND status=?');
$stmt->execute([$email, $status]);
$user = $stmt->fetch();
// or
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email AND status=:status');
$stmt->execute(['email' => $email, 'status' => $status]);
$user = $stmt->fetch();
Very Good Reference for full tutorial : https://phpdelusions.net/pdo
If you are using PHP5+, You are supposed to bind your parameters outside of the query string when executing your statement.
Example:
$query = $db->prepare('SELECT * FROM messages WHERE Subject_Code = :subj AND Week = :week')
$query->execute(array(
':subj' => $_SESSION['sub1'],
':week' => $_SESSION["weekS1"],
));
This question already has answers here:
Row count with PDO
(21 answers)
Closed 5 years ago.
Some one told me rowCount not safe so I like to ask it here, I have 2 examples and like to know what is the safest and nice way to check if something exists?
$sql = "SELECT count(*) FROM users WHERE username = 'administrator'";
$result = $db->prepare($sql);
$result->execute();
echo $result->fetchColumn() ? 'true' : 'false';
or
$sql = "SELECT username FROM users WHERE username = ?";
$result = $db->prepare($sql);
$result->execute(array('administrator'));
echo $result->rowCount() ? 'true' : 'false';
The best way to check it with prepare and fetchColumn
SELECT COUNT(*) statement with the same predicates as your intended
SELECT statement, then use PDOStatement::fetchColumn() to retrieve the
number of rows that will be returned.
$sql = "SELECT COUNT(*) FROM users WHERE username = ?";// use `COUNT(*)`
$result = $db->prepare($sql);
$result->execute(array('administrator'));
echo $result->fetchColumn() ? 'true' : 'false';
SELECT 1 FROM users WHERE username = 'administrator' LIMIT 1
Using rowCount() isn't unsafe, but just improper.
The #1 rule when working with databases is
Always select the exact data you need.
with as less post-processing as possible.
So if you need to check whatever data for existence, then ask your database to check and then fetch the result.
However, you have to keep in mind that there are 2 possible scenarios:
In case you indeed need to check wherever something exists in a database, but don't need the data, then (assuming username has an unique index on it):
$sql = "SELECT 1 FROM users WHERE username = ?";
$result = $db->prepare($sql);
$result->execute(array('administrator'));
echo $result->fetchColumn() ? 'true' : 'false';
But often you need the data itself if it happens to be found. In this case you just select that data:
$sql = "SELECT * FROM users WHERE username = ?";
$result = $db->prepare($sql);
$result->execute(array('administrator'));
$user = $result->fetch();
echo $user ? 'true' : 'false';
I am stressing on it because the wording of the other answer suggests that you have to run 2 queries: one to check the existence and one to get the data, which is a nonsense.
As of the rowCount() method - you need it too seldom to talk about.
I have a strange problem where every time I do a simple DELETE query to delete WHERE email =. For some reason after deletion it also does a new INSERT with the same email? There is no INSERT anywhere and there are no triggers... Does anybody know why this happens? The table has a email and a nr with auto_increment.
$check_email = $_POST['email'];
$query = "SELECT `email` FROM `newsletter` WHERE email = '$check_email';";
$sth = $dbh->prepare($query);
$sth->execute();
$row = $sth->fetch(PDO::FETCH_ASSOC);
$check_users_email = $row['email'];
if($check_users_email != ''){
$query_update = "DELETE FROM `newsletter` WHERE email = '$check_users_email';";
}
$sth = $dbh->prepare($query_update);
$sth->execute();
Before deletion: email=test#email.com | nr=1
After deletion: email=test#email.com | nr=2
it might be in your sql string, since you're using prepared statements.
in PDO you should use named or unnamed placeholders. then after preparing the query, you pass the prams as an array when you execute the statement.
If you're using PDO, no need to use single quotes. just the column name and for the search value just use placeholders and then pass on the values on execution as an array.
NOTE: i renamed the PDO object $sth inside the 'if' statement, just to avoid name clash. also i moved the last 2 lines inside the 'if' statement, because you need the value of the sql string '$query_update' which will not be available if that statement returned false.
also to check if the variable $check_users_email is empty, you can use empty() or strlen().
try this:
$check_email = $_POST['email'];
$query = "SELECT email FROM newsletter WHERE email = :check_email";
$sth = $dbh->prepare($query);
$sth->execute(array(':check_email' => $check_email));
$row = $sth->fetch(PDO::FETCH_ASSOC);
$check_users_email = $row['email'];
if($check_users_email != ''){
$query_update = "DELETE FROM newsletter WHERE email = :check_users_email";
$sth2 = $dbh->prepare($query_update);
$sth2->execute(array(':check_users_email' => $check_users_email));
}
I have this code for selecting fname from the latest record on the user table.
$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);
$sdt=$mysqli->('SELECT fname FROM user ORDER BY id DESC LIMIT 1');
$sdt->bind_result($code);
$sdt->fetch();
echo $code ;
I used prepared statement with bind_param earlier, but for now in the above code for first time I want to use prepared statement without binding parameters and I do not know how to select from table without using bind_param(). How to do that?
If, like in your case, there is nothing to bind, then just use query()
$res = $mysqli->query('SELECT fname FROM user ORDER BY id DESC LIMIT 1');
$fname = $res->fetch_row()[0] ?? false;
But if even a single variable is going to be used in the query, then you must substitute it with a placeholder and therefore prepare your query.
However, in 2022 and beyond, (starting PHP 8.1) you can indeed skip bind_param even for a prepared query, sending variables directly to execute(), in the form of array:
$query = "SELECT * FROM `customers` WHERE `Customer_ID`=?";
$stmt = $db->prepare($query);
$stmt->execute([$_POST['ID']]);
$result = $stmt->get_result();
$row = $result->fetch_assoc();
The answer ticked is open to SQL injection. What is the point of using a prepared statement and not correctly preparing the data. You should never just put a string in the query line. The point of a prepared statement is that it is prepared. Here is one example
$query = "SELECT `Customer_ID`,`CompanyName` FROM `customers` WHERE `Customer_ID`=?";
$stmt = $db->prepare($query);
$stmt->bind_param('i',$_POST['ID']);
$stmt->execute();
$stmt->bind_result($id,$CompanyName);
In Raffi's code you should do this
$bla = $_POST['something'];
$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE);
$stmt = $mysqli->prepare("SELECT `fname` FROM `user` WHERE `bla` = ? ORDER BY `id` DESC LIMIT 1");
$stmt->bind_param('s',$_POST['something']);
$stmt->execute();
$stmt->bind_result($code);
$stmt->fetch();
echo $code;
Please be aware I don't know if your post data is a string or an integer. If it was an integer you would put
$stmt->bind_param('i',$_POST['something']);
instead. I know you were saying without bind param, but trust me that is really really bad if you are taking in input from a page, and not preparing it correctly first.