Passing mysqli connection to a PHP function - out of synch - php

I have a problem when performing mysql commands when I invoke a function in another file. If I have the code in the same file, it works fine. The code looks like:
authenticate:
{
$conn = new mysqli($dbserver, "dbuser", "pass", $dbname);
$sql = 'SELECT userId, salt, pwd, isAdmin FROM users where username = ?';
$stmt = $conn->stmt_init();
$stmt->prepare($sql);
$stmt->bind_param('s', $username);
$stmt->bind_result($userId, $salt, $storedPwd, $isAdmin);
$stmt->execute();
$stmt->fetch();
}
Now, if I call a function, immediately after fetch, it fails on the bind_param line. I call it like this:
updateUserActivity ($conn, $tpcLang, 'LI', $userId);
the beginning of this function is:
function updateUserActivity ($conn, $lang, $activityType, $userId)
{
// check that activity is valid
$sql = 'SELECT activityType
FROM activityType
WHERE activityType = ?';
$stmt = $conn->stmt_init();
$stmt->prepare($sql);
$stmt->bind_param('s', $activityType);
$stmt->bind_result($activityTypeInDB);
$stmt->execute();
$stmt->fetch();
if ($activityType == $activityTypeInDB){
$success=1;
} else {
$success=0;
$msg = $lang->get('UPDATE_USER_INVALID_ACTIVITY_ERROR_MSG') . " " . $activityType . " (" . $stmt->errno . "): " . $stmt->error;
error_log ($msg);
}
// continue on to add a row in the userActivity table
}
The error I get on the bind_param is: invalid object or resource mysqli_stmt, and the DB error is: Commands out of sync; you can't run this command now.
Any suggestions would be greatly appreciated.

try adding this after your fetch.
mysqli_free_result($result);
or
mysqli_close($conn);

Related

PHP inserting with bind_param

I am currently working trying to use the statements mysqli_prepare and bind_param in order to pass arguements more safely into my query. I was doing mysqli_query to execute them before which worked fine. My professor is requiring us to use prepare though. I currently am getting the proper values from my form but the data isn't being entered into customer table. Also, I have mysqli_error() on my execute() commands but I am not getting any errors at all which is making debugging difficult. Here is the php part located in register.php
<?php
require 'connection.php';
$result = "";
if(isset($_POST['register'])) {
#Fetch the data from the fields
$username = $_POST['username'];
$password = $_POST['password'];
$name = $_POST['name'];
$total = 0.0;
#echo $username . " " . $password . " " . $name . " " . $total;
#Prepare sql query to see if account already exists
$query = mysqli_prepare("SELECT * FROM customer WHERE username=?");
$query->bind_param("s", $username);
$query->execute() or die(mysqli_error());
if(mysqli_num_rows($query) > 0) {
#This username already exists in db
$result = "Username already exists";
} else {
$insert = mysqli_prepare("INSERT INTO customer(username, password, name, total) VALUES (?, ?, ?, ?)");
$insert->bind_param("sssd", $username, $password, $name, $total);
$insert->execute() or die(mysqli_error());
#$result = "Account registered!"
}
}
?>
I establish connection to my db like this in connection.php
$conn = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
Like I said before, I can get the query to execute with mysqli_query but for some reason I cannot get param to work. Also tried adding or die but no errors are being printed

Error: call to a member function bind_param() , when doing 2nd bind_param()

I got the error
Fatal error: Uncaught Error: Call to a member function bind_param() on boolean
on this line:
$stmt->bind_param("i", $r);
Is my query prepared correctly?
I checked the name of the table and columns and they are correct
$stmt = $conn->prepare("UPDATE db_control SET cve_usuario=? WHERE cve_control=1");
$stmt->bind_param("i", $r);
heres my whole code:
<?php
$servername = "localhost";
$username = "usuario";
$password = "usuario";
$database = "proyectofinal";
// Create connection
$conn = new mysqli($servername, $username, $password, $database);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$stmt = $conn->prepare("SELECT cve_usuario FROM db_control");
if($stmt->execute())
{
$stmt->bind_result($r);
if($stmt->fetch()){
echo $r;
}
$r = $r + 1;
echo "<br>" . $r;
$stmt = $conn->prepare("UPDATE db_control SET cve_usuario=? WHERE cve_control=1");
$stmt->bind_param("i", $r);
if($stmt->execute())
{
/*do something*/
}
}
?>
From the documentation of mysqli::prepare:
Return Values
mysqli_prepare() returns a statement object or FALSE if an error occurred.
You should check that the prepare call succeeded with a strict check ($stmt !== FALSE), though a simple if ($stmt) works in this specific case also.
If you want to know what made your prepare call fail, you can check the error code / message:
$stmt = $conn->prepare("...");
if ($stmt) {
// bind parameters, execute statement, etc
} else {
echo "MySQLi error: " . $conn->error;
}
I solved it! Forgot to close the connection before preparing the 2nd query.
That do the trick! Thanks

Use parameter of php function as column name in SQL query

This is for a school project. I am new in PHP and MySQL.
I am trying to write a function in PHP with one string parameter, which will become the column name of a SQL query which is used in a prepare() statement inside this function.
Here is the code:
function checkCredentials($dbFieldToCheck) {
$statement = $conn->prepare("SELECT id FROM user WHERE ".$dbFieldToCheck." = ? AND password = PASSWORD(?)");
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
$statement->bind_param("ss", $_POST["username/email"], $_POST["password"]);
$statement->execute();
$result = $statement->get_result();
$row = $result->fetch_assoc();
return $row;
}
Then I call this function twice in two different variables:
$row1 = checkCredentials('email');
$row2 = checkCredentials('username');
Finally I do something with these two variables (not useful here I guess).
I have tried different ways to write the parameter in the SQL statement also different ways to write it in the function call. Now I am even starting to think that my function is not even called at all...
What I want to achieve works if I just execute the code inside the function two times with the column name hard coded. But this is not nice :)
Any help is very much appreciated. Thanks!
Add to the parameter of your function the submitted POST data and your connection variable. When you call your function, it will look like this:
checkCredentials($dbFieldToCheck, $conn, $_POST["username/email"], $_POST["password"]);
Your function will look something like this:
function checkCredentials(string $dbFieldToCheck, $conn, $username, $password) {
$statement = $conn->prepare("SELECT id FROM user WHERE ".$dbFieldToCheck." = ? AND password = PASSWORD(?)");
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
$statement->bind_param("ss", $username, $password);
$statement->execute();
$result = $statement->get_result();
$row = $result->fetch_assoc();
return $row;
}
You can use global to call variables inside your function (you can refer here for the cons of using global).
My guess is that your function doesn't know about $conn because it wasn't declared in its scope.
Your function should begin like this :
global $conn;
See the manual for more information about variable scope.
EDIT :
As apokryfos pointed out in the comments, the use of global is not recommended. It would be better to pass $conn as a parameter to checkCredentials.
See the accepted answer to this question for details. Quote :
A function call should not have to rely on anything outside
I guess you can modify your code like this:
$servername = "localhost:3306";//replace with your mysql server address
$username = "username";//replace with your mysql user
$password = "password";//replace with your mysql password
// Create connection
$conn = new mysqli($servername, $username, $password);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
function checkCredentials(string $dbFieldToCheck, $conn, $username, $password) {
$statement = $conn->prepare("SELECT id FROM user WHERE ".$dbFieldToCheck." = ? AND password = PASSWORD(?)");
if (!$statement) die("Prepare failed: (" . $conn->errno . ") " . $conn->error);
$statement->bind_param("ss", $username, $password);
$statement->execute();
$result = $statement->get_result();
$row = $result->fetch_assoc();
return $row;
}
checkCredentials('email');
Using PHP with MYSQL is not complex, this doc can help you get the basic idea how they work together
(http://www.w3schools.com/php/php_mysql_connect.asp).

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 php sql statement does not execute

I have the strangest problem and I can figure out what is happening. There are no error being displayed and I've var_dumped $stmt and for will just not return anything.
The test data that i am trying to retrieve is correct and when i try the statement manually through phpmyadmin it would perfectly so I'm stumped any ideas?
$sql = "SELECT UserID,Password FROM Account WHERE ProfileName = ? OR Email = ? LIMIT 1";
$stmt = $conn->prepare($sql);
$username = strtolower($username);
$stmt->bind_param('ss', $username, $username);
$stmt->bind_result($userID, $dbPassword);
$stmt->execute();
$stmt->fetch();
The bind_result() call must be done after execute() not before.
Change to:
$stmt->bind_param('ss', $username, $username);
$stmt->execute();
$stmt->bind_result($userID, $dbPassword);
$stmt->fetch();
From the Manual:
Note that all columns must be bound after mysqli_stmt_execute() and prior to calling mysqli_stmt_fetch().
Also, you can narrow down the problem by checking if prepare() succeeded and then subsequently if there are any rows:
if($stmt = $conn->prepare($sql))
{
$stmt->bind_param('ss', $username, $username);
$stmt->execute();
$stmt->bind_result($userID, $dbPassword);
if($stmt->num_rows > 0)
{
$stmt->fetch();
}
else
{
echo 'Query succeeded, but no rows found!';
}
}
else
{
echo "Prepare failed: (" . $conn->errno . ") " . $conn->error;
// use trigger_error() not echo in production, after development
}
If prepare() fails, it means there is a either a connection error, syntax error or missing table/field name in the query.

Categories