What is the procedural mysqli way of preparing SQL statements? - php

I have a SQL query in my code that I want to convert to a prepared statement to stop vulnerabilities like SQL injections. So this is what I want to convert:
<?php
$query = "SELECT * from `wp_posts` WHERE ID=$pid ";
$result = mysqli_query($link, $query);
//$id=$row['Gallery_Id'];
while($row = mysqli_fetch_array($result)){
?>
<h2 align="center"> <?php echo $row['post_title']; ?> </h2><br>
<div class="paracenter">
<p id="cont"><?php echo $row['post_content']; ?></p>
<hr color="black" width="10%">
</div>
<?php } ?>
This is what I tried, but it doesn't work.
$query = "SELECT * from `wp_posts` WHERE ID=? ";
$stmt = mysqli_prepare($link, $query);
if($stmt){
mysqli_stmt_bind_param($stmt, "i", $pid);
mysqli_stmt_bind_result($stmt, $dbpid);
mysqli_stmt_execute($stmt);
mysqli_stmt_fetch($stmt);
}
$result = mysqli_query($link, $query);
//$id=$row['Gallery_Id'];
while($row = mysqli_stmt_fetch($result)){
?>
<h2 align="center"> <?php echo $row['post_title']; ?> </h2><br>
<div class="paracenter">
<p id="cont"><?php echo $row['post_content']; ?></p>
<hr color="black" width="10%">
</div>
<?php } ?>
Almost all the examples online doesn't use the procedural method I use. How can I rectify this?

To protect your query against injection attack, you have two options. The first is super simple and just as secure as a prepared statement.
Cast $pid as an integer.
$query = "SELECT post_title, post_content FROM wp_posts WHERE ID = " . (int)$pid;
Secure and done.
How to write a prepared statement with result binding... (I don't use procedural mysqli syntax)
if (!$stmt = $link->prepare("SELECT post_title, post_content FROM wp_posts WHERE ID = ?")) {
echo "Syntax Error # Prepare"; // $link->error; <-- never show actual error details to public
} elseif (!$stmt->bind_param("i", $pid) || !$stmt->execute() || !$stmt->bind_result($title, $content)) {
echo "Syntax Error # ParamBind | Execute | ResultBind"; // $stmt->error; <-- never show actual error details to public
} else {
while ($stmt->fetch()) {
echo "<div>";
echo "<h2 align=\"cente\">$title</h2><br>";
echo "<div class=\"paracenter\">";
echo "<p id=\"cont\">$content</p>";
echo "<hr color=\"black\" width=\"10%\">";
echo "</div> ";
}
}
Some additional notes.
If you are not going to use result binding, you should use mysqli_fetch_assoc() instead of mysqli_fetch_array(). mysqli_fetch_array() will generate a bloated result set of both indexed and associative keyed elements (double what you actually need).
When you use bind_result(), you need to replace * in the SELECT clause with the columns to be extracted.
My first elseif() expression contains three separate calls & checks on $stmt. As soon as any one of those calls returns a falsey/erroneous response, the conditional expression short circuits and the remaining calls in the expression are never executed.
If adopting my object-oriented mysqli style, be sure to align your database connection syntax as object-oriented as well.

Related

How can I add prepare statement in my comment printing system

I'm currently building a system where users can write and read comments. So the comments will be inserted into database (the inserting part is already protected with the prepared statement), so now I want to add the prepared statement at the comment printing part too.
This is the comment inserting part
<?php
if (isset($_POST['submit'])) {
$nickname=$_POST['user_nickname'];
$email=$_POST['user_email'];
$comment=$_POST['cmt_text'];
$course=$_POST['user_course'];
$rating=$_POST['user_rating'];
$classof=$_POST['user_classof'];
$school_id=$_POST['id'];
$db="INSERT INTO comments(user_nickname,user_email,cmt_text,user_course,user_rating,school_id,user_classof) VALUES(?,?,?,?,?,?,?)";
$stmt=mysqli_stmt_init($con);
if(!mysqli_stmt_prepare($stmt,$db)){
echo "Data Error";
}else{
mysqli_stmt_bind_param($stmt,"ssssiii", $nickname,$email,$comment,$course,$rating,$school_id,$classof);
mysqli_stmt_execute($stmt);
}
header("location:Done.php");
exit;
}?>
And this is where I want to add prepared statements
<?php
$sql = "SELECT * FROM comments WHERE school_id=$sid ORDER BY Datetime DESC ";
$result = mysqli_query($con, $sql);
if (mysqli_num_rows($result) > 0) {
while ($row = mysqli_fetch_assoc($result)) {
?>
<div class="single-item">
<h4><?php echo $row['user_nickname']; ?></h4>
<p><?php echo $row['Datetime'];
?></p>
<p><b>Course</b> : <?php echo $row['user_course'];
?></p>
<p><b>Class of</b> <?php echo $row['user_classof'];
?></b></p>
<p><b>Rating : </b><?php echo $row['user_rating'];
?>/5</p>
<p><b>Comment : </b><?php echo $row['cmt_text'];
?></p>
</div>
<?php
}
}
?>
I have tried adding, but I got stuck when it comes to the part where I need to put the parameter, since I am printing out all the comments, how can I add the ? parameter?
By the way, $sid is a specific id for one school. There's more than a hundred schools in thecomments table. I put all the comments from every schools in one table.
Just create a function in which you will prepare the data.
function selectComments(mysqli $mysqli, ?int $schoolId = null): array
{
if ($schoolId) {
$stmt = $mysqli->prepare('SELECT * FROM comments WHERE school_id=? ORDER BY Datetime DESC');
$stmt->bind_param('s', $schoolId);
$stmt->execute();
$result = $stmt->get_result();
} else {
$result = $mysqli->query('SELECT * FROM comments ORDER BY Datetime DESC');
}
return $result->fetch_all(MYSQLI_ASSOC);
}
Then you can call it like this:
foreach(selectComments($con, $sid) as $row) {
// your HTML table
}

Query with data from user in MSSQL with PHP [duplicate]

This question already has answers here:
sqlsrv_num_rows Not Returning Any Value
(2 answers)
Closed 2 years ago.
(I'm forced to work on microsoft sql server in my internship).
I don't understand why my query doesn't work in PHP (it returns no data), but it works when I put it directly in Microsoft SQL Server Management Studio (it returns the datas).
Here is my code :
<?php
require('conn.php');
if(isset($_POST['submit-search'])){
$search = $_POST['search'];
$sql = "SELECT codepo, codepsa, controle, FORMAT(date, 'dd-MM-yyyy hh:mm:ss') as date FROM dbo.codebarre where datediff(day, date, '$search') = 0";
var_dump($sql);
$result = sqlsrv_query($conn2, $sql);
$queryResult = sqlsrv_num_rows($result);
?>
(...)
<?php
if($queryResult > 0){
while($donnees = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) {
?>
<tbody>
<tr>
<th style="font-weight: normal;"><?php echo htmlspecialchars($donnees['codepo']); ?></th>
<td><?php echo htmlspecialchars($donnees['codepsa']); ?></td>
<td <?php if ($donnees['controle'] === 'NOK') {
echo 'style="color: red; font-weight: bold"';
} ?>><?php echo htmlspecialchars($donnees['controle']); ?></td>
<td><?php echo $donnees['date'] ?></td>
</tr>
</tbody>
<?php
}
} else {
echo "No data";
}
}
The var_dump($sql) returns me this :
string(138) "SELECT codepo, codepsa, controle, FORMAT(date,
'dd-MM-yyyy hh:mm:ss') as date FROM dbo.codebarre where datediff(day,
date, '20210107') = 0"
As I told you when I paste it in Management studio it works, so I don't understand why it doesn't here.
You have two options:
Execute sqlsrv_query() with the appropriate cursor type, if you want to get the exact number of the returned rows.
Use sqlsrv_has_rows() if you want to check if there are rows returned.
PHP code using sqlsrv_num_rows():
<?php
...
$result = sqlsrv_query($conn2, $sql, array(), array("Scrollable" => SQLSRV_CURSOR_KEYSET));
$queryResult = sqlsrv_num_rows($result);
if ($queryResult > 0) {
// Fetch data
}
...
?>
PHP code using sqlsrv_has_rows():
<?php
...
$result = sqlsrv_query($conn2, $sql);
$queryResult = sqlsrv_has_rows($result);
if ($queryResult) {
// Fetch data
}
...
?>
As an additional note, always use parameterized statements to prevent possible SQL injection issues. As is mentioned in the documentation, function sqlsrv_query() does both statement preparation and statement execution and can be used to execute parameterized queries.
<?php
...
$sql = "
SELECT codepo, codepsa, controle, FORMAT(date, 'dd-MM-yyyy hh:mm:ss') AS date
FROM dbo.codebarre
WHERE datediff(day, date, ?) = 0
";
$params = array($search);
$options = array("Scrollable" => SQLSRV_CURSOR_KEYSET);
$result = sqlsrv_query($conn2, $sql, $params, $options);
...
?>

How to fetch data form database using array

I am trying to fetch data from the database, but not retrieve data particular id.
this is my one page:
example1.php
<a style="color: #3498DB;" class="btn btn-default" href="http://www.example.com/getafreequote?id=<?php echo $row['product_id']; ?>">Get Quote</a>
example2.php
<?php
$id = isset($_GET['id'])?$_GET['id']:'';
$query = "SELECT * FROM oc_product_description WHERE product_id=$id";
$run1 = mysql_query($query);
while ($fetch1 = mysql_fetch_object($run1)){
?>
<div class="col-xs-12 col-sm-6">
<label for="GetListed_product"></label>
<input class="le-input" name="product" id="GetListed_product" type="text" value="<?php
$b = $fetch1->product_id;
$q2 ="SELECT product_id,name FROM oc_product_description WHERE product_id = $b";
$q3 = mysql_fetch_assoc(mysql_query($q2));
echo $q3['name'];
?>" >
<span id="productmsg" class="msg"></span>
</div>
<?php
}
?>
</div>
but didnot get data form particular product id. I have got error show like this
Warning: mysql_fetch_object(): supplied argument is not a valid MySQL result resource in example.com/example2.php on line 71
Please don't use mysql functions they are deprecated. Use mysqli or PDO for database operations. Also the way you write the query string makes it easy for an SQL injection, use prepared statements instead. Here is an example:
$db = new PDO("...");
$statement = $db->prepare("select id from some_table where name = :name");
$statement->execute(array(':name' => "Jimbo"));
$row = $statement->fetch();
You can also use prepared statements for inserting or updating data. More examples here
As said by FilipNikolovski, don't use mysql functions they are deprecated. Use mysqli or PDO for database operations.
For your problem, the function mysql_query is returning false. The query is not returning any result and thus mysql_query is returning false.
Make a check like this:
$query = "SELECT * FROM oc_product_description WHERE product_id=$id";
$run1 = mysql_query($query);
if($run1)
{
if(mysql_num_rows($run1) > 0)
{
while ($fetch1 = mysql_fetch_object($run1))
{
// your stuff here
}
}
else
{
echo "No records found.";
}
}
else
{
echo "Error in query : ".mysql_error();
}
This will help you to detect the problem and to solve as well.

How to fetch data in PHP with MySQLi?

I tried several times but cannot succeed in getting the right syntax—according to PHP 5.5.12 —to fetch single or multiple rows from my database.
session_start();
$con=mysqli_connect("localhost","root","","doortolearn");
if (!$con) {
echo "Could not connect to DBMS";
}
$query="select * from teacher where tremail='$_POST[email]' and trpasssword='$_POST[password]'";
$result=mysqli_query($con,$query);
$flag=FALSE;
while ($row=mysqli_fetch_array($result,MYSQLI_BOTH)) {
$_SESSION['email']=$row['email'];
$flag=TRUE;
}
First, you have no single quotes ' around $_POST[password]:
$query = "SELECT * FROM teacher WHERE tremail='". $_POST['email'] ."' and trpasssword='" . $_POST['password'] . "'";
$result = mysqli_query($con, $query) or die(mysqli_error($con));
$flag = FALSE;
while ($row = mysqli_fetch_array($result, MYSQLI_BOTH)) {
$_SESSION['email'] = $row['email'];
$flag = TRUE;
}
But past that, do you even have a MySQL database connection set here? I see $con but is that really working?
Also, check if there are errors by adding or die(mysql_error($con)) to your mysqli_query($con, $query) line.
Also, you have a $_SESSION value, but do you even set session_start at the beginning of your script?
But I also recommend you use mysqli_stmt_bind_param for your values to at least escape them if you are not going to do basic validation:
$query = "SELECT * FROM teacher WHERE tremail=? and trpasssword=?";
mysqli_stmt_bind_param($query, 'ss', $_POST['email'], $_POST['password']);
$result = mysqli_query($con, $query) or die(mysqli_error($con));
$flag = FALSE;
while ($row = mysqli_fetch_array($result, MYSQLI_BOTH)) {
$_SESSION['email'] = $row['email'];
$flag = TRUE;
}
To successfully fetch data from MySQL using mysqli extension in PHP you need to perform more or less three actions: connect, execute prepared statement, fetch data.
Connection:
The connection is really simple. There should always be only 3 lines of code for opening a connection. You enable error reporting, create new instance of mysqli, and set the correct charset.
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'user', 'pass', 'db_name');
$mysqli->set_charset('utf8mb4');
Prepared statement
This is the tricky part. You need to prepare SQL statement to be executed. Careful, never concatenate PHP variables into SQL directly. Bind the variables using placeholders. Once the statement is ready you can execute it on the server.
$stmt = $mysqli->prepare('SELECT * FROM teacher WHERE tremail=?');
$stmt->bind_param('s', $_POST['email']);
$stmt->execute();
Fetch the data
If your prepared statement should return some results, you need to fetch them and do something with the records. To fetch the result use get_result(). This will give you an object that you can iterate on to fetch each row one by one.
$result = $stmt->get_result();
foreach ($result as $row) {
echo $row['user_id'];
}
If you are only starting learning PHP, please consider learning PDO instead. It is easier to use and offers more functionality. Use mysqli only for legacy projects.
can You try this code
<?php $query=mysqli_query($connection, "SELECT * FROM user");
while($rows=mysqli_fetch_array($query)){ ?>
<tr>
<td><?php echo $rows['name']; ?></td>
<td><?php echo $rows['age']; ?></td>
<td><?php echo $rows['mobile']; ?></td>
<td><?php echo $rows['email']; ?></td>
</tr>
<?php } ?>
$r =$mysqli->query("select * from users");
while ( $row = $r->fetch_assoc() )
{
?>
<tr>
<td><?php echo $i++; ?></td>
<td><?php echo $row['name']; ?></td>
<td><?php echo $row['pwd']; ?></td>
</tr>
<?php
}
?>

How to use while loops in mysqli query

Am sorry for the really stupid question. i have a code like so and i would like the result to be done on a while loop. i was using mysql befor and the query was simple and executed well.
example
$sql_query = mysql_query($query);
while($row = mysql_fetch_array($sql_query)
{
$data_a = $row['a']; $data_b = $row['b'];
}
now i use oop and i have a database class and a connection handler that is injected in to the new class am extending from the database class. my proble no is after the code executes, i get this error method *mysqli_stmt::fetch_assoc()* here is my code
<?php
class recentWorks extends DatabaseModelBase
{
public function show($tbl, $num_to_show, $site_url="")
{
$statement = $this->prepare('SELECT * FROM '.$tbl.' WHERE RAND()<(SELECT (( '.$num_to_show.' /COUNT(*))*10) FROM '.$tbl.' ) ORDER BY RAND() LIMIT '.$num_to_show.' ');
$statement->execute();
while ($recent_results = $statement->fetch_assoc())
{
$featured_work_name=$recent_results['name']; $featured_work_url=$recent_results['url']; $featured_work_thumb=$recent_results['img_thumb'];
$featured_work_id=$recent_results['id'];$featured_work_desc=$recent_results['desc'];$featured_work_img=$recent_results['img_url'];
?>
<li>
<a href="<?php echo $featured_work_img; ?>" class="fancybox thumb poshytip" title="Click To View Enlarged Image">
<img src="<?php echo $featured_work_thumb; ?>" width="282px" height="150px" alt="<?php echo $featured_work_name; ?>' Image" />
</a>
<div class="excerpt">
<span class="main_header"><?php echo ucwords($featured_work_name); ?>
</span>
<?php echo substr($featured_work_desc,0,300); ?>
</div>
</li>
<?php
}
$statement->close();
}
}
?>
please someone debug this for me
Let's see what you had before
$sql_query = mysql_query($query);
`----- missing error checking and handling
while ($row = mysql_fetch_array($sql_query))
`---- missing error handline
{
$data_a = $row['a']; $data_b = $row['b'];
`----- complicated way of setting variables as arrays
}
Now let's see what you have now (selected lines)
$statement = $this->prepare('SELECT * FROM '.$tbl.' WHERE RAND()<(SELECT (( '.$num_to_show.' /COUNT(*))*10) FROM '.$tbl.' ) ORDER BY RAND() LIMIT '.$num_to_show.' ');
`---- using prepare as if it would have been mysql_query()
$statement->execute();
`----- same here
This is wrong. Just telling you. I suggest you search for some well-working mysqli_* tutorial first. One that either explains you how to build SQL queries and fire them and that explains what prepared statements are and how to use them.
My suggestion: Start with the PHP manual, it compares the different libraries and shows examples for all mysql, mysqli and PDO.
You have even a comparison side-by-side of mysql and mysqli for a more easy migration: Dual procedural and object-oriented interface.

Categories