I´m trying to do the following query in PHP
$sqlstr = mysql_query("SELECT * FROM sales where passport = $row['passport']");
if (mysql_numrows($sqlstr) != 0) {
while ($row = mysql_fetch_array($sqlstr)) {
echo $row['firstname'];
}}
How can I incorporate the value of $row['passport'] into my query?
First of all you forgot the single-quotes. sAc corrected this already in his answer. But I would consider to also use an escaping function due to security-issues:
$sqlstr = mysql_query("
SELECT
*
FROM
sales
WHERE
passport = '" . mysql_real_escape_string($row['passport']) . "'");
You are missing quotes:
$sqlstr = mysql_query("SELECT * FROM sales where passport = '{$row['passport']}'");
I would avoid manually escaping/sanitizing your variables and just use prepared statements. This was something I didn't learn until much later in my web development career, and I wish I'd known about it sooner. It will save you a lot of trouble and is just safer all around.
You can use the mysqli_stmt class to perform MySQL queries using prepared statements, or you could use the PHP Data Objects (PDO) extension, which works with MySQL, PostgreSQL and other RDBMSes.
Just to show you what it looks like, here's the first example from the PDOStatement->bindParam doc page:
<?php
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();
?>
Related
I'm having some trouble using a variable declared in PHP with an SQL query. I have used the resources at How to include a PHP variable inside a MySQL insert statement but have had no luck with them. I realize this is prone to SQL injection and if someone wants to show me how to protect against that, I will gladly implement that. (I think by using mysql_real_escape_string but that may be deprecated?)
<?php
$q = 'Hospital_Name';
$query = "SELECT * FROM database.table WHERE field_name = 'hospital_name' AND value = '$q'";
$query_result = mysqli_query($conn, $query);
while ($row = mysqli_fetch_assoc($query_result)) {
echo $row['value'];
}
?>
I have tried switching '$q' with $q and that doesn't work. If I substitute the hospital name directly into the query, the SQL query and PHP output code works so I know that's not the problem unless for some reason it uses different logic with a variable when connecting to the database and executing the query.
Thank you in advance.
Edit: I'll go ahead and post more of my actual code instead of just the problem areas since unfortunately none of the answers provided have worked. I am trying to print out a "Case ID" that is the primary key tied to a patient. I am using a REDCap clinical database and their table structure is a little different than normal relational databases. My code is as follows:
<?php
$q = 'Hospital_Name';
$query = "SELECT * FROM database.table WHERE field_name = 'case_id' AND record in (SELECT distinct record FROM database.table WHERE field_name = 'hospital_name' AND value = '$q')";
$query_result = mysqli_query($conn, $query);
while ($row = mysqli_fetch_assoc($query_result)) {
echo $row['value'];
}
?>
I have tried substituting $q with '$q' and '".$q."' and none of those print out the case_id that I need. I also tried using the mysqli_stmt_* functions but they printed nothing but blank as well. Our server uses PHP version 5.3.3 if that is helpful.
Thanks again.
Do it like so
<?php
$q = 'mercy_west';
$query = "SELECT col1,col2,col3,col4 FROM database.table WHERE field_name = 'hospital_name' AND value = ?";
if($stmt = $db->query($query)){
$stmt->bind_param("s",$q); // s is for string, i for integer, number of these must match your ? marks in query. Then variable you're binding is the $q, Must match number of ? as well
$stmt->execute();
$stmt->bind_result($col1,$col2,$col3,$col4); // Can initialize these above with $col1 = "", but these bind what you're selecting. If you select 5 times, must have 5 variables, and they go in in order. select id,name, bind_result($id,name)
$stmt->store_result();
while($stmt->fetch()){ // fetch the results
echo $col1;
}
$stmt->close();
}
?>
Yes mysql_real_escape_string() is deprecated.
One solution, as hinted by answers like this one in that post you included a link to, is to use prepared statements. MySQLi and PDO both support binding parameters with prepared statements.
To continue using the mysqli_* functions, use:
mysqli_prepare() to get a prepared statement
mysqli_stmt_bind_param() to bind the parameter (e.g. for the WHERE condition value='$q')
mysqli_stmt_execute() to execute the statement
mysqli_stmt_bind_result() to send the output to a variable.
<?php
$q = 'Hospital_Name';
$query = "SELECT value FROM database.table WHERE field_name = 'hospital_name' AND value = ?";
$statement = mysqli_prepare($conn, $query);
//Bind parameter for $q; substituted for first ? in $query
//first parameter: 's' -> string
mysqli_stmt_bind_param($statement, 's', $q);
//execute the statement
mysqli_stmt_execute($statement);
//bind an output variable
mysqli_stmt_bind_result($stmt, $value);
while ( mysqli_stmt_fetch($stmt)) {
echo $value; //print the value from each returned row
}
If you consider using PDO, look at bindparam(). You will need to determine the parameters for the PDO constructor but then can use it to get prepared statements with the prepare() method.
$postid = $_GET['p'];
$stmt = $conn->prepare("SELECT * FROM posts WHERE post_id=:postid");
$stmt->bindValue(':postid', $postid);
$stmt->execute();
while($postRows = mysqli_fetch_assoc($stmt)){
$posts[] = $postRows;
}
The above code does not work.
Usually I'd do:
$postid = mysqli_real_escape_string($conn,$_GET['p']);
$result = mysqli_query($conn,"SELECT * FROM posts WHERE post_id='$postid'");
while($postRows = mysqli_fetch_assoc($result)){
$posts[] = $postRows;
}
which works for me.
I can't seem to get my head around this because online explanations do a poor job of actually explaining how to do these, so I have been using mysqli_real_escape_string instead but I understand it can be vulnerable.
Can anyone help me understand how to properly do these queries?
You can try this code
$stmt = $conn->prepare("SELECT * FROM posts WHERE post_id=:postid");
$stmt->bindValue(':postid', $postid, PDO::PARAM_INT);
$stmt->execute();
$posts = $stmt->fetchAll(PDO::FETCH_ASSOC);
This could help you:Mysql prepare statement - Select
And an Example from PHP on using bindValue()website(http://php.net/manual/en/pdostatement.bindvalue.php example#2):
<?php
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?');
$sth->bindValue(1, $calories, PDO::PARAM_INT);
$sth->bindValue(2, $colour, PDO::PARAM_STR);
$sth->execute();
?>
In this example they are specifying parameter type in the bindValue() statement such as PDO::PARAM_STR and PDO::PARAM_INT. You too try specifying your parameter as such.
Or you can also prepare statements and bind values using bindParam(':placeholder',$variable_or_value); (http://www.w3schools.com/php/php_mysql_prepared_statements.asp)
Prepared statements are used for executing same query multiple times with different or changing values. It gives more efficiency. For simple or random queries there is no need to prepare statements infact it will only decrease the effificeny b creating overheads for preparations. And prepared statements are generally applied on INSERT and UPDATE statements
I guess what you want to do might be:
$stmt = $conn->prepare('SELECT * FROM posts WHERE post_id = ?');
//Use 's' for a string or 'i' for an integer
$stmt->bind_param('s', $postid);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc())
{ }
As I said in comments, you are mixing MySQL APIs (mysqli_ and PDO).
You need to use the same API from connecting to querying. Those different APIs do not intermix.
In order to use PDO, you need to:
Connect using PDO http://php.net/manual/en/pdo.connections.php
Query with PDO http://php.net/manual/en/pdo.query.php
Then if you want to use PDO with prepared statements:
http://php.net/pdo.prepared-statements
You cannot connect with mysqli_ then mix MySQL functions with PDO.
That's how it rolls.
Footnotes:
If you want to stick with mysqli_, then it too has prepared statements.
http://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php
The choice is yours. Remember to use the same MySQL API.
Error checking:
http://php.net/manual/en/pdo.error-handling.php - if using all PDO
http://php.net/manual/en/mysqli.error.php - If using all MySQLi
Add error reporting to the top of your file(s) which will help find errors.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// rest of your code
Sidenote: Displaying errors should only be done in staging, and never production.
I have a seen a mysql code that looks like this
select * from customer
where name = :name;
In Mysql using colons in front of the value is not permitted, my assumption is the query is provided with a colon to bind it with PHP functions.
What I am looking for is which function is used to bind the queries with colons?
So far I have checked mysqli_stmt_bind_param but mechanism used to replace parameter with value is question mark and not colon.
You're correct with the binding, but there are two ways;
? - a simple placeholder, which you would bind with numerical indexes. For example;
$sql = "INSERT INTO `foo` (`bar`,`baz`) VALUES (?, ?)";
$smt = $pdo->prepare($sql);
$smt->bindParam(1, $bar);
$smt->bindParam(2, $baz);
// ...
:foo - a simple placeholder, which you would bind with a string index. For example;
$sql = "INSERT INTO `foo` (`bar`,`baz`) VALUES (:bar, :baz)";
$smt = $pdo->prepare($sql);
$smt->bindParam(':bar', $bar);
$smt->bindParam(':baz', $baz);
// ...
There are two database APIs available that involve binding;
PDO
MySQLi
You can see this article by "Use the Index, Luke" to see how binding is actually done.
Here is an example taken from php.net:
<?php
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();
?>
You should try searching on Google before asking here as this is simple function call.
For more details, please check: http://php.net/manual/en/pdostatement.bindparam.php
Im trying to work with PDO for the first time and I'm just wanting to know how secure what I'm doing is, I'm also new to PHP.
I have a query that when a user is passed ot my page, the page takes a variable using GET and then runs.
With PHP I've always used mysql_real_escape to sanitize my variables.
Can anybody see security flaws with this?
// Get USER ID of person
$userID = $_GET['userID'];
// Get persons
$sql = "SELECT * FROM persons WHERE id =$userID";
$q = $conn->query($sql) or die($conn->error());
while($r = $q->fetch(PDO::FETCH_LAZY)){
echo '<div class="mis-per">';
echo '<span class="date-submitted">' . $r['date_submitted'] . '</span>';
// MORE STUF
echo '</div>';
}
Don't use query, use prepare:
http://php.net/manual/de/pdo.prepare.php
$userID = $_GET['userID'];
$sql = "SELECT * FROM persons WHERE id = :userid";
$q = $conn->prepare($sql)
$q->execute(array(':userid' => $userID ));
while($r = $q->fetch(PDO::FETCH_ASSOC)){
echo '<div class="mis-per">';
echo '<span class="date-submitted">' . $r['date_submitted'] . '</span>';
// MORE STUF
echo '</div>';
}
The SQL statement can contain zero or more named (:name) or question mark (?) parameter markers for which real values will be substituted when the statement is executed.
With anything you use, it's about how you use it rather than what you use. I'd argue that PDO itself is very safe as long as you use it properly.
$sql = "SELECT * FROM persons WHERE id =$userID";
That's bad *. Better :
$sql = "SELECT * FROM persons WHERE id = " . $conn->quote($userID);
Better :
$q = $conn->prepare('SELECT * FROM persons WHERE id = ?')->execute(array($userID));
* This is bad, and that's because if $userID is "1 OR 1", the query becomes SELECT * FROM persons WHERE id =1 OR 1 which will always return all values in the persons table.
As the comments say: Atm there is no security whatsoever against SQLI. PDO offers you (if the database driver supports it (mysql does)) Prepared Statements. Think of it like a query-template that is compiled/passed to the dbms and later filled with values.
here is an example of usage:
$sql = 'SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour';
//Prepare the Query
$sth = $dbh->prepare($sql);
//Execute the query with values (so no tainted things can happen)
$sth->execute(array(':calories' => 150, ':colour' => 'red'));
$red = $sth->fetchAll();
Adjust as follows (you can use either :userId or simply ? as Tom van der Woerdt suggests, even if I think the first one gives more clearness, especially when there are more than just one parameter):
$sql = "SELECT * FROM persons WHERE id =:userID";
$q = $conn->prepare( $sql );
$q->bindValue( ":userID", $userID, PDO::PARAM_INT ); // or PDO::PARAM_STR, it depends
$q->execute();
$r = $st->fetch();
...
...
I am new to PDO objects and cannot find a single piece of documentation that will help me. Say I got a simple code to delete a row:
$count = $dbh->exec("DELETE FROM fruit WHERE colour = 'red'");
That will return affected rows, but how would I use prepared statements with that? Can use use $dbh->prepare AND $dbh->exec or query !?
It should be the same as any other statement:
$stmt = $dbh->prepare("DELETE FROM fruit WHERE colour = ?");
$stmt->execute(array('red'));
$count = $stmt->rowCount();
The PDO Statement rowCount() should be what you are looking to do.
EDIT
Fixed by adding the ->rowCount() which will return the row count. ->execute in a statement will return a bool, true or false whether the query errored out or not. Of course all of this information is readily available at the PDO Statement Manual
$dbh->prepare returns a PDOStatement object. You then call $stmt->execute to get the result.
More info in the PDO manual
Here's an example from the manual:
<?php
/* Execute a prepared statement by passing an array of insert values */
$calories = 150;
$colour = 'red';
$stmt = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?');
$stmt->execute(array($calories, $colour));
?>