Hi I'm trying to use prepared statements within functions. I have the following function which is supposed to return the details of a country in a DB based on inputting the ID of the country - I then use an array to get the company name after. I don't know how to output the data to be used in the array from the function when I use prepared statements. I know I'm missing something basic. Please see below.
function findCountryname($countryID){
include 'connect.php';
$stmt = $conn->prepare("SELECT * FROM countries WHERE id=? and
pic!='NULL'");
$stmt->bind_param("i", $countryID);
$stmt->execute();
}
The 'connect.php' file consists of the following:
<?php
global $conn, $dbname, $username,$servername, $password;
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "country";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
?>
This was the original function:
function findCountryname($countryID){
$result = mysql_query("SELECT * FROM `countries` WHERE `id`=' $countryID '
and `pic` != 'nothing' ");
return $result;
}
There is no reason to use globals or an include inside a function. If you insist on procedural code, you should inject the mysqli object into the function as an argument.
After the statement execution, you need to retrieve the mysqli result object for manipulation. If you're just getting the first row, the below example will work. If you expect multiple rows, you will have to call fetch_assoc in a loop as it will only retrieve one row at a time.
function findCountryname($countryID, mysqli $conn) {
$stmt = $conn->prepare("SELECT * FROM countries WHERE id=? and pic!='NULL'");
$stmt->bind_param("i", $countryID);
$stmt->execute();
// Get the mysqli result object
$result = $stmt->get_result();
// Return the first row of data in an associative array
$data = $result->fetch_assoc()
return $data;
}
You can use mysqli's fetch_assoc to fetch the resulting data from the query and store it in an array, then return that array.
So your function now becomes :-
function findCountryname($countryID){
include 'connect.php';
$stmt = $conn->prepare("SELECT * FROM countries WHERE id=? and
pic!='NULL'");
$stmt->bind_param("i", $countryID);
$stmt->execute();
$data = $stmt->fetch_assoc();
return $data;
}
Related
I am finding it difficult to write a SQL prepared statement for my search form, can I get help on fixing it? Everything works great without a SQL prepared bind statement but am sure it's not so secure.
Here is my CODE:
<?php
// Define Database connection parameters
$dbserver = "localhost";
$username = "root";
$password = "";
$dbname = "student";
// Lets Connect to theDatabase Table, But if there is an Error lets tell before its too late to figured
$conn = mysqli_connect ( $dbserver, $username, $password, $dbname ) or die ( ' I can not connect to the database ' );
// Its time to Capture the varibles and user inpute from the form , also we need to sanitize the input to avoid SQL Injection
$study_group = mysqli_real_escape_string ( $conn, $_POST['matric_number']);
/* Lets try to use bind Statement to reduce further hacking
I am also avoiding using "LIKE" Clause because IVariable direct Exact results so will be using the Direct Varible
*/
$sql = $conn->prepare (" SELECT * FROM study_circle WHERE matric = ? ") ;
$sql->bind_param('s', $study_group);
$sql ->execute();
$results = mysqli_query ($conn, $sql);
$mysqlResults = mysqli_num_rows ($results);
if ( $mysqlResults > 0 )
{
while ( $row = mysqli_fetch_assoc ( $results ))
{
// Display results in table form
echo " <div>
<h4> ".$row['full_name']."</h4>
</div>";
}
} else {
echo " Please Ensure your Matric Number is correct, We can not find anything relting to your data";
}
if you use prepared statement you should not use mysqli_real_escape_string
Try comment the mysqli_real_escape_string row and use $_POST['matric_number'] directly in bind_param
// $study_group = mysqli_real_escape_string ( $conn, $_POST['matric_number']);
/* Lets try to use bind Statement to reduce further hacking
I am also avoiding using "LIKE" Clause because IVariable direct Exact results so will be using the Direct Varible
*/
$sql = $conn->prepare (" SELECT * FROM study_circle WHERE matric = ? ") ;
$sql->bind_param('s', $_POST['matric_number']);
$sql ->execute();
The binding param and prepared statement prevents SQL injection so you don't need mysqli_real_escape_string operation
Trying to just set up something to verify that username = password via num_rows = 1.
Trying to use prepared statements, that I have never used before and i'm missing something. Where does the var in bind_results('s',$variable) come from??
Also, its just not working for me.
<?php
require ($_SERVER['DOCUMENT_ROOT'].'/db-connect.php');
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$user = $_POST['username'];
//$user = $mysqli->real_escape_string($user);//
$password = $_POST['password'];
//$password = $mysqli->real_escape_string($password);//
if ($stmt = $mysqli->prepare("SELECT * FROM users WHERE username = ? AND password = ?")) {
$stmt->bind_result('ss', $username);
$stmt->execute();
$result = $stmt->num_rows;
echo $result;
$stmt->close();
}
$mysqli->close();
?>
I see three problems with this:
$stmt->bind_result('ss', $username);
First, bind_result PHP documentation:
"Binds columns in the result set to variables."
I think you're looking for bind_param. PHP documentation:
"Bind variables for the parameter markers in the SQL statement that was passed to mysqli_prepare()."
Second, your statement has two parameter markers (?), your bind statement indicates two strings (ss), but you provide only one variable ($username).
Third, $username is not what you're getting from $_POST['username']. You've assigned that to $user. $username is for your database connection.
I think it should work for you with this line instead:
$stmt->bind_param('ss', $user, $password);
This question already has answers here:
How do I loop through a MySQL query via PDO in PHP?
(3 answers)
Closed 9 years ago.
I am currently using MySQL with PHP but am looking to start MySQLi or PDO
I have while loops like:
$sql="select from ... ";
$rs=mysql_query($sql);
while($result=mysql_fetch_array($rs))
{
$sql2="select from table2 where id = $result["tbl1_id"] ";
}
If I put my MySQLi or PDO queries into a function how can I run things like the above? Doing while loops with queries inside the while loops?
Or is if easier to not do the functions at all and just run the prepared statements as normal?
You wouldn't. And to be honest.. Even in the old days you would not do it this way, but like this:
$sql="select from ... ";
$rs=mysql_query($sql);
$ids = array()
while($result=mysql_fetch_array($rs))
{
$ids[] = $result["tbl1_id"];
}
$sql2="select from table2 where id in ".implode(',', $ids) .";
Or even better, you use a join to run the query just once, on all the tables that need to provide info.
In PDO you can do the same thing. Get all the ID's and the execute a query
I usually take the approach of preparing the query and not using a function. Also I am not clear as to what exactly it is that you want. You want to make your queries as quick and efficient as possible so you should not look to run a while look within another while loop.
This is how my PDO queries usually look
My connection:
$host = "localhost";
$db_name = "assignment";
$username = "root";
$password = "";
try {
$connection = new PDO("mysql:host={$host};dbname={$db_name}", $username, $password);
}catch(PDOException $exception){ //to handle connection error
echo "Connection error: " . $exception->getMessage();
}
MY query:
$query = "SELECT * FROM Table";
$stmt = $connection->prepare( $query );
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
extract($row);
}
It's a duplication question like oGeez say, you have to learn how to code PDO in PHP and other before asking question,
this is the answer:
$dbh = new PDO("mysql:host=" . HOST . ";dbname=" . BASE, USER, PASS, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$query = 'SELECT * FROM table';
$stmt = $dbh->query($query);
$items = $stmt->fetchAll(PDO::FETCH_OBJ);
foreach($items as $item {
print_r($item);
}
the main reason to put it in a function would be if you use the query in multiple files. i have a web app with many queries and i like to keep them in a separate file so that they're easier to track down if i need to make changes. the main thing is that you 1) have to pass your database as a parameter and 2) return the results
function pdoquery($db, $parameter){
$query = "SELECT * FROM table WHERE column=?";
$stmt = $db->prepare($query);
$stmt->bindValue(1, $parameter, PDO::PARAM_STR); //or PARAM_INT
if (!$stmt->execute()) {
echo "Could not get results: (" . $stmt->errorCode . ") " . $stmt->errorInfo;
exit;
}
else
$result = $stmt->fetch();
$db = null;
return $result;
}
but as others have mentioned, if its only used once, there's no need for a function, and looping through the results is best done outside of the function as well. however, it is possible to do it inside the function if you want to.
want i want is to query my db with post variable in the query. It's not really working for me, does anyone know how to do it properly?
Here is what i have so far.
$query = "SELECT column FROM `table` WHERE 'name' = '$_POST[checkname]'";
$result = mysqli_query($db, $query) or die ("no query");
$cod = mysqli_fetch($result);
echo $cod;
Any help is appreciated. Thanks guys.
Mysqli supports prepared statements, which protect against sql injection attacks. It would look like this:
/* Create a prepared statement */
$stmt = $mysqli -> prepare("SELECT column FROM table WHERE name=?");
/* Bind parameters */
$stmt -> bind_param("s", $_POST['checkname']);
/* Execute it */
$stmt -> execute();
/* Bind results */
$stmt -> bind_result($result);
/* Fetch the value */
$stmt -> fetch();
echo $result;
Check the manual for more info.
A quick rundown, in response to the comment:
In $stmt->prepare("..."), you're forming your query, and you hold the place of any variables you intend to use with a "?"
In $stmt -> bind_param(...), you're binding the variables to their corresponding question mark. The first argument is the type, the following arguments are the variables. If you were using a string and an integer, inside the parenthesis it would look like "si", $stringVar, $intVar
In $stmt -> bind_result(...) you are stating what you are binding the results to. If the query was for a name and age, inside the parethesis would look like $name, age
In $stmt->fetch(), you're fetching the result. If it was multiple rows returned, you would do something like:
while($stmt->fetch()) {
//code here
}
Alternatively, you could use PDO. It would look something like this:
/* Create a prepared statement */
$stmt = $pdo->prepare("SELECT column FROM table WHERE name=:checkname");
/* Bind parameters */
$stmt->bindParam(':checkname', $_POST['checkname']);
/* Execute it */
$stmt->execute();
/* Fetch results */
$obj = $stmt->fetchObject();
echo $obj->column;
Check the manual for more info.
//it is apsulutly
// work
if(isset($_POST['checkname']))
{
$post = mysql_real_escape_string(trim($_POST[' checkname ']));
$query = "SELECT column FROM `table` WHERE name = '$post'";
$result = mysqli_query($db, $query) or die ("no query");
$cod = mysqli_fetch_all($result);
echo implode($cod[0]);
echo implode($cod[1]);//For particular cell
}
it works, just try it out like this
following your code...
if(isset($_POST['checkname']))
{
//to avoid SQL injections
$post = mysql_real_escape_string(trim($_POST['checkname']));
$query = "SELECT column FROM `table` WHERE name = '$post'";``
$result = mysqli_query($db, $query) or die ("no query");
$cod = mysqli_fetch($result);
echo $cod;
}
In a class, I have some PDO:
$userFName = 'userFName';
include('dbconnect.php'); // Normally I'd store the db connect script outside of webroot
$pdo = new PDO("mysql:host=$db_host;dbname=$db_name;", $db_user, $db_password);
$stmt = $pdo->prepare('SELECT userFName FROM Users WHERE username = :uname AND password = :pword AND roleID = 1');
$stmt->bindParam(':uname', $this->user->username);
$stmt->bindParam(':pword', $this->user->password);
$stmt->bindColumn(4, $userFName, PDO::PARAM_STR);
$stmt->execute();
$familiar = $stmt->fetch(PDO::FETCH_BOUND);
$this->user->firstName = $familiar;
It's returning the ID in the first column instead of the VARCHAR contents in the 4th column. Any idea why?
When using PDO::FETCH_BOUND with fetch(), the method will not return a result record. Instead the value of the column should be available in the variable you have bound using $stmt->bindColumn() earlier.
So change your code to:
$stmt->bindColumn(1, $userFName, PDO::PARAM_STR);
$stmt->execute();
$stmt->fetch(PDO::FETCH_BOUND);
$this->user->firstName = $userFName; // <-- use the bound variable
However you won't need that bindColumn() call. You could simplify the code as this:
$stmt->execute();
$row = $stmt->fetch(); // uses PDO::FETCH_ASSOC by default
$this->user->firstName = $row['FName'];
There is too much code in your class. And one fault. To send a distinct query to get just one property from database, creating a distinct connection for this is a dead overkill.
Connection have to be moved away unconditionally and you must think of getting ALL user data with one query.
Proper code
function __construct($pdo) {
$this->pdo = $pdo;
// Normally you should include somewhere in a bootstrap file
// not in the application class
// and instantiate PDO in that bootstrap as well
// and only PASS already created instance to the class
}
function getUserFName() {
$sql = 'SELECT * FROM Users WHERE username = ? AND password = ? AND roleID = 1';
$stmt = $pdo->prepare($sql);
$stmt->execute(array($this->user->username,$this->user->password));
return $stmt->fetchColumn();
}