mysqli prepared multiple statements search not excuting - php

I'm trying to transition my old Mysqli queries to mysqli prepared statements, and I don't seem able to figure out how to get this working as a mysqli prepared statements - see my code below. My original query works fine see below.
<?php
// DB Settings
define('DB_SERVER', 'localhost');
define('DB_USER', 'xxxx');
define('DB_PASSWORD', 'xxxx');
define('DB_NAME', 'xxxx');
$mysqli = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME);
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$name = "Smith"; //Smith is Master 6 times and once as Junior Stewart Total 7 rows in my database
$search_query = '%'.$name.'%';
//Original Query - this works fine
$sql = "SELECT Master, `Junior Steward` AS `Junior_Steward` FROM past_officers WHERE `Master` LIKE
'$search_query' OR `Junior Steward` LIKE '$search_query' ";
$stmt = mysqli_stmt_init($mysqli);
if (mysqli_stmt_prepare($stmt, $sql)) {
mysqli_stmt_bind_param($stmt, "s", $search_query);
mysqli_stmt_bind_result($stmt, $Master, $Junior_Steward);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$count = mysqli_stmt_num_rows($stmt);
printf("Number of rows: %d.\n", mysqli_stmt_num_rows($stmt));//Prints number of rows
if ($count == 0) {
echo $output = "<p>There was no search results</p>"; //asign to variable $output message "There was no search results"
}
while (mysqli_stmt_fetch($stmt)) {
echo "<p>Master: $Master Junior Steward: $Junior_Steward</p>";
}
}
/* Prepared Statements Binds two variables to a prepared statement as parameters*/
//This doesn't work
$sql = "SELECT Master, `Junior Steward` AS `Junior_Steward` FROM past_officers WHERE `Master` LIKE ? OR `Junior
Steward` LIKE ?";
$stmt = mysqli_stmt_init($mysqli);
if (mysqli_stmt_prepare($stmt, $sql)) {
mysqli_stmt_bind_param($stmt, "s", $search_query);
mysqli_stmt_bind_result($stmt, $Master, $Junior_Steward);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$count = mysqli_stmt_num_rows($stmt);
printf("Number of rows: %d.\n", mysqli_stmt_num_rows($stmt));//Prints number of rows
if ($count == 0) {
echo $output = "<p>There was no search results</p>"; //asign to variable $output message "There was no search results"
}
while (mysqli_stmt_fetch($stmt)) {
echo "<p>Master: $Master Junior Steward: $Junior_Steward</p>";
}
}
/* Prepared Statements Bind one variable to a prepared statement as parameters*/
//This works but only for one parameter
$sql = "SELECT Master FROM past_officers WHERE `Master` LIKE ? ";
$stmt = mysqli_stmt_init($mysqli);
if (mysqli_stmt_prepare($stmt, $sql)) {
mysqli_stmt_bind_param($stmt, "s", $search_query);
mysqli_stmt_bind_result($stmt, $Master);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$count = mysqli_stmt_num_rows($stmt);
printf("Number of rows: %d.\n", mysqli_stmt_num_rows($stmt));//Prints number of rows
if ($count == 0) {
echo $output = "<p>There was no search results</p>"; //asign to variable $output message "There was no search results"
}
while (mysqli_stmt_fetch($stmt)) {
echo "<p>Master: $Master </p>";
}
}
$stmt->close();
$mysqli->close()
?>

You are using both the class mysqli and the functions from mysqli. You are not actually using one of them.
Choose between one of them, or use the class or use the functions like mysqli_connect();
Here is an example of how you should execute prepared statements using the class mysqli.
$stmt = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME);
$username = "Jordy";
$password = "MyLittleSecret";
if($query = $stmt->prepare("SELECT * FROM users WHERE username = ? AND password = ?")) {
$query->bind_param("ss", $username, $password);
$query->execute();
}
http://php.net/manual/en/mysqli.quickstart.prepared-statements.php

Related

Problems with my first prepared MySQLi

Following a question earlier about sanitising a string, I'm now attempting to use the principles seen at How can I prevent SQL injection in PHP?
$connection = mysqli_connect('localhost', 'user', 'xxxxx');
$database = mysqli_select_db($connection, 'xxxxx');
$param1 = $_GET['q'];
//prepared mysqli statement
$stmt = mysqli_stmt_init($connection);
$stmt = $connection->prepare('SELECT * FROM CONTACTS WHERE SURNAME = ?');
$stmt->bind_param('s', $param1); // 's' specifies the variable type => 'string'
$stmt->execute();
$result = $stmt->get_result();
$num_rows = mysqli_num_rows($result);
echo "Records Found:".$num_rows."<br/><br/><hr/>";
while ($row = $result->fetch_assoc()) {
echo $result['COMPANY']." ".$result['FORENAME']." ".$result['SURNAME'];
}
However, although $connection and $database are both processing correctly, I'm getting the following error:
Fatal error: Call to undefined method mysqli_stmt::get_result() in
/my_first_mysqli.php on line xxxx
Am I not getting the syntax correct or does it have more to do with the php version 5.2.0 I'm rocking. (Yes, I'm upgrading code before upgrading server).
If it's the latter, is there a simpler MySQLi method I can use that will work before I upgrade the php version?
EDIT
I've updated this now which is a bit cleaner:
$servername = "localhost"; $username = "xxxx"; $password = "xxxx"; $dbname = "xxxx";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$param1 = $_GET['q'];
$stmt = mysqli_prepare($conn, "SELECT CONTACTID, COMPANY, FORENAME, SURNAME FROM CONTACTS WHERE SURNAME = ?");
/* bind parameters for markers */
mysqli_stmt_bind_param($stmt, "s", $param1);
/* execute query */
mysqli_stmt_execute($stmt);
/* bind result variables */
mysqli_stmt_bind_result($stmt, $CONTACTID, $COMPANY, $FORENAME, $SURNAME);
/* fetch value */
mysqli_stmt_fetch($stmt);
$num_rows = mysqli_num_rows($stmt);
echo "Records Found:".$num_rows."<br/><br/><hr/>";
/* close statement */
mysqli_stmt_close($stmt);
mysqli_close ($conn);
I'm obviously not getting a recordset result to loop through and don't know how to... The rest appears to work without throwing an error.
Thanks for all the contributions. I now have a working procedural solution that I thought I'd post for reference.
It's a bit cumbersome but it's fine and I believe it follows good modern practice.
$servername = "localhost"; $username = "xxxx"; $password = "xxxx"; $dbname = "xxxx";
$conn = new mysqli($servername, $username, $password, $dbname);// Create connection
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$param1 = $_GET['q'];
$stmt = mysqli_prepare($conn, "SELECT CONTACTID, COMPANY, FORENAME, SURNAME FROM CONTACTS WHERE SURNAME = ?");
mysqli_stmt_bind_param($stmt, "s", $param1);// bind parameters for markers
mysqli_stmt_execute($stmt);// execute query
mysqli_stmt_bind_result($stmt, $CONTACTID, $COMPANY, $FORENAME, $SURNAME);// bind result variables
// fetch values
while (mysqli_stmt_fetch($stmt)) {
echo $CONTACTID."<br>";
echo $COMPANY."<br>";
echo $FORENAME."<br>";
echo $SURNAME."<br>";
echo "<hr/>";
}
mysqli_stmt_close($stmt);// close statement
mysqli_close ($conn);
Feedback welcome if you can see any improvements.

Return number of rows doesn't work

This is the code I currently have:
$stmt = $mysqli->prepare("SELECT * FROM Account WHERE accountKey=? AND accountUsername=?");
$stmt->bind_param('ss', $key,$username);
$stmt->execute();
$stmt->store_result();
$numrows = $stmt->num_rows;
The problem is the query is fine. I tryed it on PHPMyAdmin and it return me one result. When I check how many result I got with this one is always 0 when it should be 1... Do you know what could happen...
Query from PHPMyAdmin:
http://i.imgur.com/PFrXNgf.png
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
include("../script/connection.php");
$link = mysqli_connect($SQLhost, $SQLusername, $SQLpassword, $SQLdatabase);
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$key = '4dc5f0ea67ca3791614b28c310cd1c79';
$username = 'jean8mathieu';
$query = "SELECT * FROM Account WHERE accountKey=? AND accountUsername=?";
if ($stmt = mysqli_prepare($link, $query)) {
mysqli_stmt_bind_param($stmt, 'ss', $key, $username);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
printf("Number of rows: %d.\n", mysqli_stmt_num_rows($stmt));
mysqli_stmt_close($stmt);
} else {
printf('errno: %d, error: %s', $mysqli->errno, $mysqli->error);
exit;
}
mysqli_close($link);

PHP/MySQL: Check if username exists

I'm a beginner in php and I want to check if the username entered already exists.
Here is my code.
<?php
ini_set('display_errors',1);
error_reporting(E_ALL);
if (isset($_POST['submit'])) {
include "connect.php";
ValidateUser();
}
function ValidateUser()
{
if (!empty($_POST['username']) AND !empty($_POST['password'])) {
$queryrow=mysqli_query("SELECT * FROM websiteusers WHERE username = '$_POST['username']'");
if ($rows=mysqli_num_rows($queryrow)=0) {
RegisterUser();
}
}
function RegisterUser() {
echo "works up to here";
}
?>
It doesn't even give me an error despite turning error reporting on.
Have you even initialized a mysqli_connect?
$Connection = mysqli_connect("host","user","pass","database");
Then pass it to a function which uses mysqli_query() by:
function foo ($DB){
mysqli_query($DB,"QUERY HERE");
// Do other stuff
return /* Whatever you wish to return here*/
}
foo($Connection);
What you are trying to achieve can be done very easily with the following code. A bigger concern is security. It is good practice to both sanitize your input every time the user has a chance to input text.
Also, using prepared query's will put yet another layer of security.
Although this isn't using your provided code directly, I believe it is good to teach good habits.
If you have any questions feel free to ask.
$username = $_POST['username']; <-- sanitize this
$message = null;
$mysqli = new mysqli("localhost", "user", "password", "database");
$stmt = $mysqli->prepare("SELECT username FROM websiteusers WHERE username=?");
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql);
$stmt->fetch();
if ($stmt->num_rows() > 0) {
RegisterUser();
} else {
$message .= 'username already exists';
}
Later on when you require more items to be queried, or more results to be bound:
$stmt = $mysqli->prepare("SELECT username,password,other1,other2 FROM websiteusers WHERE username=?");
$stmt->bind_param('s', $username); <-- the "s" means the argument is a strings, if a argument is stored as an int use "i", but one character for each argument is required.
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql);
$stmt->fetch();
Multiple Arguments:
$stmt = $mysqli->prepare("SELECT username,password,other1,other2 FROM websiteusers WHERE username=? AND authenticated=?");
$stmt->bind_param('si', $username,$isauthenticated); <-- second argument is a INT or BOOL
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql,$passwordsql,$other1sql,$other2sql);
$stmt->fetch();
When your expecting multiple results, and lets say you want to dump them into arrays:
$userarray = array();
$stmt = $mysqli->prepare("SELECT username FROM websiteusers WHERE username=?");
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($usernamesql);
while($stmt->fetch()){
array_push($userarray, $usernamesql);
}
$userarray is now an array of all the results fetched from the database.
Here is the right way to do this:
<?php
ini_set('display_errors',1);
error_reporting(E_ALL);
if (isset($_POST['submit'])) {
$mysqli = new mysqli("localhost", "user", "password", "database");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
if(check_user($mysqli, $_POST['username']){
registerUser();
}else{
echo 'user exist, cannot register';
}
}
function check_user($conn, $username){
$query = "SELECT * FROM websiteusers WHERE username = ?";
if ($stmt = $conn->prepare($query)) {
$stmt->bind_param("s", $username);
$stmt->execute();
$stmt->close();
}
return $stmt->num_rows === 0;
}
function registerUser() {
echo "registering user ...";
}
Read up on prepared statement

Mysqli prepared statements error? [duplicate]

This question already has answers here:
mysqli_stmt::bind_result(): Number of bind variables doesn't match number of fields in prepared statement
(2 answers)
Closed 1 year ago.
I've ran into this error with prepared statements, I've just started with prepared statements so go easy on me please, Heres the error:
Warning: mysqli_stmt::bind_result(): Number of bind variables doesn't match number of fields in prepared statement in C:\wamp\www\darkhorizons\login.php on line 31
Heres my code:
if (isset($_POST['submit'])){
$username = $_POST['username'];
$password = $_POST['password'];
if(isset($username) && isset($password)) {
$mysqli = new mysqli("localhost","root","","phplogin") or die("Couldnt connect!");
if(mysqli_connect_errno()){
echo "Connection failed: ". mysqli_connect_errno();
exit();
}
if($stmt = $mysqli -> prepare("SELECT * FROM users WHERE username =? AND password =? LIMIT 1")){
$stmt -> bind_param("ss", $username, $password);
$stmt -> execute();
$stmt -> bind_result($result);
$stmt -> fetch();
$numrows = mysqli_num_rows($result);
} else {
die("Please enter a username and password!");
}
if($numrows == 1){
$_SESSION['username'] = $_POST['username'];
$_SESSION['loggedin'] = true ;
$query = "SELECT adminflag FROM users WHERE username = '{$_SESSION['username']}' LIMIT 1;";
$result2 = mysqli_query($connect, $query);
$numrows2 = mysqli_num_rows($result2);
if ($numrows2 == 1) {
$_SESSION['isadmin'] = true;
}
header("Location: {$pageLoc}");
exit(); //It's good to use exit or die (same thing) AFTER using header to redirect
} else {
}
}
}
As a side note, Please ignore any mistakes in the code below the prepared statement, im redoing my login script that ive been using to learn.
Going through your code you didn't really need to query you DB twice, you should read the adminflag in that same select.
SELECT * is never a good idea always select specific fields.
And I also noticed you are using two differnt style, I suggest you to stick to the Object oriented approach.
<?php
if (isset($_POST['submit'], $_POST['username'] , $_POST['password'])){
$username = $_POST['username'];
$password = $_POST['password'];
$mysqli = new mysqli("localhost","root","","phplogin");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$query = "SELECT adminflag FROM users WHERE username = ? AND password = ? LIMIT 1";
if ($stmt = $mysqli->prepare($query)) {
$stmt -> bind_param("ss", $username, $password);
$stmt->execute();
$stmt->store_result();
$numrows = $stmt->num_rows;
printf("Number of rows: %d.\n", $numrows );
if($numrows == 1){
$stmt->bind_result($admin_flag);
$stmt->fetch();
session_start();
if ($admin_flag== 1) {
$_SESSION['isadmin'] = true;
}
$_SESSION['username'] = $username;
$_SESSION['loggedin'] = true ;
header("Location: {$pageLoc}");
}else{
echo 'user not found';
}
}
$stmt->close();
$mysqli->close();
}else{
echo 'required field missing';
}
?>

Produce login error only if not correct login

I know this has something to do with the num_rows part but after numerous attempts I still can't figure this out. Basically no matter what I enter I am receiving the 'login failed' message. If my login is correct I receive login failed and login correct. I obviously only want the error if the username/password are incorrect. Thanks in advance for any help!
else if(!$error_msg && $_POST['login']){
//Build the SQL query to match the record that matches the password and username
$sql = "SELECT id, username, password_1 FROM members WHERE username = ? AND password_1 = ? LIMIT 1";
//Prepare our query
if($stmt = $mysqli->prepare($sql)){
//Bind the Parameters to the query
$stmt->bind_param('ss', $username, $password_1);
//Execute the query
$result = $stmt->execute();
//If the query doesn't execute
if($result === false){
echo '<p class="error">No Execution</p>';
}
//Bind the results of what the query gave us to our three variables
$stmt->bind_result($id, $username, $password_1);
if($stmt->num_rows !== 1){
echo '<p class="error">Login failed</p>';
}
while($stmt->fetch()){
echo "Hey The query matched a record and you should be signed in now";
echo $id;
echo $username;
echo $password_1;
}//End While
else{
echo $mysqli->error;
echo "No entry found";
}
$mysqli->close();
}
Give this a try, working on my server.
Some of your conditional statements are missing, but am sure you can incorporate them into it.
<?php
DEFINE ('DB_USER', 'xxx');
DEFINE ('DB_PASSWORD', 'xxx');
DEFINE ('DB_HOST', 'xxx');
DEFINE ('DB_NAME', 'xxx');
$mysqli = #mysqli_connect (DB_HOST, DB_USER, DB_PASSWORD, DB_NAME)
OR die("could not connect");
$username = "username"; // replace with actual
$password_1 = "password"; // replace with actual
$sql = "SELECT id, username, password_1 FROM members WHERE username = ? AND password_1 = ? LIMIT 1";
if($stmt = $mysqli->prepare($sql)){
$stmt->bind_param('ss',$username,$password_1);
/* execute query */
$stmt->execute();
/* Store the result (to get properties) */
$stmt->store_result();
/* Get the number of rows */
$num_of_rows = $stmt->num_rows;
/* Bind the result to variables */
$stmt->bind_result($id, $username, $password_1);
if($stmt->num_rows !== 1){
echo '<p class="error">Login failed</p>';
}
while ($stmt->fetch()) {
echo 'ID: '.$id.'<br>';
echo 'Name: '.$username.'<br>';
echo 'Password: '.$password_1.'<br>';
}
/* free results */
$stmt->free_result();
/* close statement */
$stmt->close();
}
/* close connection */
$mysqli->close();

Categories