Writing this MySQLi query as a prepared statement - php

I have an existing MySQLi query:
$conn = dbConnect('query');
$galNumb = "SELECT COUNT(pj_gallery_id) FROM pj_galleries WHERE project = {$project}";
$gNumb = $conn->query($galNumb);
$row = $gNumb->fetch_row();
$galTotal = $row[0];
This counts the number of galleries per project that match the value in the query string contained in $project.
It works perfect but is not secure compared to a prepared statement. I have been researching this for two days and can not learn how to write this statement as a prepared statement. Any and all help will be insanely appreciated.
UPDATE:
I am flying by the seat of my pants here. I simply need to be shown how to code the above as a prepared statement. This sort of thing isn't resonating with my brain like learning PHP did and I'm just not getting any of this. The PHP manual is confusing and seems to be written for people who already understand PHP.
In short, I need a prepared statement version of the above code so that I can echo the result on the page. Currently, with what is in my DB, the number should be 3, and it consistently returns 1.
I wish I knew more so that I could better phrase my questions, but alas, I'm still learning. My apologies.
UPDATE 2:
Based on suggestions and research, I have this query written, but it ALWAYS returns the value 1, regardless of what's actually in the database:
$galNumb = "SELECT COUNT(pj_gallery_id) FROM pj_galleries WHERE project_part = ?";
$stmt = $conn->prepare($galNumb);
$stmt->bind_param('i', $project);
$gNumb = $stmt->execute();
Again, All I want to do is COUNT how many galleries are in each project. I know this should be simple but it isn't for me. There is currently 1 project in the DB with 3 galleries. The query should return 3.

This is as simple as it gets. This will prepare a sql statement, execute it and fetch the first row.
<?php
// create the prepared statement
$stmt = $conn->prepare('SELECT COUNT(pj_gallery_id) FROM pj_galleries WHERE project = ?');
// bind a variable to the statment
// the character denotes the type of the variable
// 's' for string
// 'i' for integer
$stmt->bind_param('i', $project);
// execute the query
$stmt->execute();
// get the result variable
$result = $stmt->get_result();
// fetch the row
$row = $result->fetch_row();
if ($row) {
echo "The count is " . $row[0];
}
?>
The documentation is pretty straightforward. You have a code example at the bottom.
http://php.net/manual/en/mysqli.prepare.php

$stmt = $dbConnection->prepare('SELECT COUNT(pj_gallery_id) FROM pj_galleries WHERE project = ?');
$stmt->bind_param('s', $project);
$stmt->execute();

Related

Using PHP variable in SQL query

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.

PHP: How to select single value from single row in MySQL without using array for results

I am new to PHP and have a really basic question.
If I know the result of a query is only a single value (cell) from a single row in MySQL how can I simplify the below without having to go through an array of results and without increasing the risk of SQL injection ?
In the example below I would just need to echo a single email as the result of the query.
I found a couple of posts suggesting different approaches with fetch_field for this but I am not sure what is the best way here since some of these seem to be pretty old or deprecated now.
My PHP:
$stmt = $conn->prepare("SELECT email FROM Users WHERE userName = ? LIMIT 1");
$stmt->bind_param('s', $userName);
$stmt->execute();
$result = $stmt->get_result();
$arr = $result->fetch_assoc();
echo $arr["email"];
Many thanks in advance.
You can avoid caring what the column is called by just doing this:
<?php
$stmt = $conn->prepare("SELECT email FROM Users WHERE userName = ? LIMIT 1");
$stmt->bind_param('s', $userName);
$stmt->execute();
$email = $stmt->get_result()->fetch_object()->email;
echo $email;

PDO: When to use bindParam, execute(array)) and PDO::FETCH_ASSOC?

I'm new to PDO, in fact, this is the first time that I'm using it. All the while I've been using mysql which is depreciated. And so recently, I'm trying to update all my site to use PDO which is better and safer according to many sources that I found from the internet.
However, those tutorials is making me even more curious and full of questions. I've been google for the whole day and I still can't get the best answer or examples.
Let's start by this code below,
// query
$sql = "SELECT title FROM books ORDER BY title";
$q = $conn->query($sql);
$q->setFetchMode(PDO::FETCH_ASSOC);
// fetch
while($r = $q->fetch()){
print_r($r);
}
I do understand that it fetches the data just like mysql_fetch_assoc. But, here's another code that I found from the net.
$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
$stmt->execute(array('name' => $name));
foreach ($stmt as $row) {
// do something with $row
}
and lastly, this:
$stm = $pdo->prepare('SELECT * FROM table LIMIT ?, ?');
$stm->bindParam(1, $limit_from,PDO::PARAM_INT);
$stm->bindParam(2, $per_page,PDO::PARAM_INT);
$stm->execute();
$data = $stm->fetchAll();
Why are there so many different methods to fetch a data ?
I somehow found out that with bindParam, you're able to set integer or strings for the variable? But with this below...
$pdo->execute(array(':col2' => $col2, ':col3' => $col3, ':col4' => $col4));
Am I still able to mix integer and strings without declaring if it's integer or strings?
Is it ok if I do like this ? mixing strings and integer in execute array...
$sql = "INSERT INTO books (id,author) VALUES (:id,:author)";
$q = $conn->prepare($sql);
$q->execute(array(':author'=>'string', ':id'=>1));
And also, does all codes above avoid SQL injection ?
I somehow prefer the execute array method as it is shorter and I don't want to declare if it's integer or strings every time like using the bindParam method.

PHP, MySQL statement results in ZERO rows

hope someone can help me.
i have a very simple prepared SELECT statment in PHP:
$query_select = ("SELECT * FROM companies where user_name = ? ");
$stmt = $mysqli->prepare($query_select);
$stmt->bind_param("s", $user_name);
$stmt->execute();
$count = $stmt->num_rows;
in companies table I have several rows with the $user_name i`m trying to query. But i still get 0 rows as a result.
The strange thing is that the non PREPARED version works:
$query = 'SELECT * FROM companies WHERE user_name="'.$user_name.'"';
$result = $mysqli->query($query);
$count= $result->num_rows;
echo "Aantal: ".$count;
So my question is, does anyone know why the prepared version returns ZERO and the non prepared version returns the correct number of rows?
Add this line to your code between execute and num_rows statement.
$stmt->store_result();
You have to store it before counting it.
For mysqli prepared statements, you must take an additional step: storing the result.
Try this:
$query_select = ("SELECT * FROM companies where user_name = ? ");
$stmt = $mysqli->prepare($query_select);
$stmt->bind_param("s", $user_name);
$stmt->execute();
$stmt->store_result(); // <-- new line
$count = $stmt->num_rows;
May be you need to bind the result:
/* bind result variables */
$stmt->bind_result($district);
Full example here

how to use mysqli_fetch_array with prepared statements

so everyone told me to use prepared statements, but i have no idea what to do now.
$stmt = mysqli_prepare($con, "SELECT * FROM search WHERE `name2` LIKE '?' AND `approved`='approved'");
mysqli_stmt_bind_param($stmt, 's', $name);
/* execute prepared statement */
mysqli_stmt_execute($stmt);
That is my code, how do i make an array from it like
while ($row=mysqli_fetch_array($result))
from non-prepared
Glad to see you are deciding to use PDO!
//using MySQL
//refer here for reference http://www.php.net/manual/en/ref.pdo-mysql.php
$pdo = new PDO('mysql:host=xxx;port=xxx;dbname=xxx', $username, $password)
//write query
$sql = "SELECT * FROM search WHERE `name2` LIKE '?' AND `approved`='approved'";
//tell query what to replace ? marks with
$fill_array = array($name); // one item in array for the one ? in $sql above
//send query to DB for preparation
$prepare = $pdo->prepare($sql);
//send variables to DB, DB will bind them to the proper place and execute query
$prepare->execute($fill_array);
//get your array. I personally recommend PDO::FETCH_ASSOC but you are using ARRAY
$result = $prepare->fetchAll(PDO::FETCH_ARRAY);
echo '<pre>'.print_r($result, true).'</pre>';
Voila!
Please not that you will have to write code to escape $name and check for things like % signs and underscores because if someone literally types in % then the LIKE statement will return all records where approved='approved'

Categories