Correct Syntax to Add ORDER BY to SQL Query - php

How can I add ORDER BY field to the end of this SQL query
$sql = "SELECT item_id,field FROM item WHERE department=".$catid;? I can't get the syntax right due to the PHP variable at the end...
I tried $sql = "SELECT item_id,field FROM item WHERE department=".$catid ORDER BY field; but obviously that didn't work

You can fix your syntax error like this, using another concatenation operator . to append the ORDER BY clause:
$sql = "SELECT item_id,field FROM item WHERE department=".$catid." ORDER BY field";
As long as $catid is an integer, that will work, but it may leave you open to SQL injection, dependent on the source of the value in $catid.
Best practice is to use a prepared query. For MySQLi, something like this:
$sql = "SELECT item_id,field FROM item WHERE department=? ORDER BY field";
$stmt = $conn->prepare($sql);
$stmt->bind_param('i', $catid); // change to 's' if $catid is a string
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// do something with results
}

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.

Cannot echo result from mysql

All I need is to produce a row. I've looked at all the samples and I cannot for the life of me get the right information. Hence help is required please.
Connection to DB in the usual way. Here is my code for the query.
$sql = "SELECT * FROM table WHERE `u_password` = $pword AND `user` = $uname LIMIT 1";
$result = mysqli_query($mdb, $sql);
$row = mysqli_fetch_assoc($result);
//Then I try to retrieve say the user name....
echo $row['seeking'];
I've got a count in there and it produces a result of 1.
The error I get is
'Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result'
Help would be appreciated.
The error
Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result
Almost always means that the query failed for some reason, thus $result = mysqli_query returns FALSE rather than a mysql_result object so anything that then tries to use $result as an object will not work for obvious reasons.
The issue with your query is that text column data must be wrapped in quotes like this
$sql = "SELECT *
FROM table
WHERE `u_password` = '$pword' AND `user` = '$uname' LIMIT 1";
Your script is at risk of SQL Injection Attack
Have a look at what happened to Little Bobby Tables Even
if you are escaping inputs, its not safe!
You should use parameterized queries to avoid this.
$sql = "SELECT *
FROM table
WHERE `u_password` = ? AND `user` = ? LIMIT 1";
$stmt = mysqli_prepare($mdb, $sql);
// its also a good idea to check the staus of a prepare
// and show the error if it failed, at least while testing
if ( $stmt === FALSE ) {
echo mysqli_error($mdb);
exit;
}
$stmt->bind_param('ss', $pword, $uname );
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_assoc();
echo $row['seeking'];
You need to use prepared statements (in actuality you could get it to work by quoting your strings but prepared statements are much better). Like so:
$sql = "SELECT * FROM table WHERE `u_password` = ? AND `user` = ? LIMIT 1";
$stmt = mysqli_prepare($mdb, $sql);
$stmt->bind_param("ss",$pword,$uname);
if ($stmt->execute()) {
$result = $stmt->get_result();
$row = mysqli_fetch_assoc($result);
//Then I try to retrieve say the user name....
echo $row['seeking'];
} else { /* something went wrong */ }

How to prepare statement with mysqli for select query

I am very worried about sql injection. I have been reading up about it and been trying to prepare the following query:
$query_AcousticDB = "SELECT * FROM products WHERE Category = 'Acoustic ' ORDER BY RAND()";
$AcousticDB = mysqli_query($DB, $query_AcousticDB) or die(mysqli_connect_error());
$row_AcousticDB = mysqli_fetch_assoc($AcousticDB);
$totalRows_AcousticDB = mysqli_num_rows($AcousticDB);
which works great.
I thought that I only have to change to the following:
$query_AcousticDB = prepare("SELECT * FROM products WHERE Category = 'Acoustic ' ORDER BY RAND()");
However this doesn't work. I get the following error:Call to undefined function prepare()
I still would like to get my values as:<?php echo $row_AcousticDB['what ever']; ?>
Can somebody point me into the right direction?
How about this?
$category = "Acoustic";
$sql = "SELECT * FROM products WHERE Category = ? ORDER BY RAND()";
$stmt = $DB->prepare($sql);
$stmt->bind_param('s', $category);
$stmt->execute();
$row_AcousticDB = $stmt->get_result(); // altenative: $stmt->bind_result($row_AcousticDB);
$row_AcousticDB->fetch_array(MYSQLI_ASSOC)
If you let the user enter any data (in text boxes on website) or you pull anything out of database for use (risk of second order injection) make sure you sanitize it (cleanse it of any nasty tags like < or >) by using htmlspecialchars($category) or htmlentities($category).
With this method implemented into your code, you will be reasonably safe from SQL Injection :)
Try to make this variable global: Put this on the upper part of your script global $acousticDB; or else you may try this $acoustic='';

How to solve Illegal string offset ['id'] in php?

I'm sorry if this is a duplicate question but I don't know how to solve my problem. Every time I try to correct my error I fail. My code is:
if (isset($_GET["comment"])) {$id = $_GET["comment"];}
$query = "SELECT * FROM posts WHERE id = {$id['$id']};";
$get_comment = mysqli_query($con, $query);
Can anybody correct the code to not show an error anymore and tell me what did I wrong?
Try this:
$id = isset($_GET['comment']) ? $_GET['comment'] : 0;
$query = "SELECT * FROM `posts` WHERE `id` = " . intval($id);
The use of intval will protect you from SQL injection in this particular case. Ideally, you should learn PDO as it is extremely powerful and makes prepared statements much easier to handle to prevent all injections.
An example using PDO might look like:
$id = isset($_GET['comment']) ? $_GET['comment'] : 0;
$query = $pdo->prepare("SELECT * FROM `posts` WHERE `id` = :id");
$query->execute(array("id"=>$id));
$result = $query->fetch(PDO::FETCH_ASSOC); // for a single row
// $results = $query->fetchAll(PDO::FETCH_ASSOC); // for multiple rows
var_dump($result);
First of all you should prevent injestion.
if (isset($_GET["comment"])){
$id = (int)$_GET["comment"];
}
Notice, $id contanis int.
$query = "SELECT * FROM posts WHERE id = {$id}";
Assuming your $id is an integer and you only want to make the query if it is set, here's how you could do it using prepared statements, which protect you from MYSQL injection attacks:
if (isset($_GET["comment"])) {
$id = $_GET["comment"];
$stmt = mysqli_prepare($con, "SELECT * FROM posts WHERE id = ?");
mysqli_stmt_bind_param($stmt, 'i', $id);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $get_comment);
while (mysqli_stmt_fetch($stmt)) {
// use $get_comment
}
mysqli_stmt_close($stmt);
}
Most of these functions return a boolean indicating whether they were successful or not, so you might want to check their return values.
This approach looks a lot more heavy duty and is arguably overkill for a simple case of a statement containing a single integer but it's a good practice to get into.
You might want to look at the object-oriented style of mysqli which you might find a little cleaner-looking, or alternatively consider using PDO.

mysqli prepared statement without bind_param

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.

Categories