Throwing 'Call to a member function prepare() on a non-object' on the $mysqli->prepare. The original worked perfectly fine. Is this not possible in mysqli?
Guess I should have made it clear that mysqli is set correctly as in include - $mysqli = new mysqli($db_host, $db_user, $db_pass, $db_database);
original :
mysql_query("UPDATE test_users SET lastIP=currIP, dtLastLogin=dtCurrLogin WHERE user='".$user."'");
new mysqli version:
function user_login($user)
{
// Update user's last ip and last login date in db
$stmt = $mysqli->prepare("UPDATE test_users SET lastIP = currIP, dtLastLogin = dtCurrLogin WHERE user= ?");
// bind params
$stmt->bind_param('s', $user);
// execute prepared statement
$stmt->execute();
// close statement
$stmt->close();
You can do what you want to do with mysqli, but you haven't initialised the variable $mysqli in your function.
Either declare it as a global variable, or pass it in as an argument.
Related
I got a numerical ID of 20 characters witch looks like 10527391670258314752, given this ID, how can I get the username associated with it?
The table looks like this:
id | name | password | balance
10527391670258314752 | Jhon | 12345 | 12.51
The username retrieved from the database should then be stored into $_SESSION['name'].
I've tried this:
$connection = mysqli_connect('localhost', 'root', '', 'user_data');
$id = '10527391670258314752';
$query = "SELECT username FROM user_data WHERE id = '$id'";
$result = mysqli_query($connection, $query);
$record = mysqli_fetch_array($id);
$_SESSION['id'] = $record;
echo $_SESSION['id'];
The output is Array() instead of the name.
That's actually a very good question that has almost no good answers on Stack Overflow.
Basically you need the following steps to perform a SELECT query using mysqli:
create a correct SQL SELECT statement and replace all variables in the query with with question marks (called placeholders or parameters)
Prepare the resulting query
Bind all variables to the previously prepared statement
Execute the statement
get the mysqli result variable from the statement.
fetch your data
The detailed explanation can be found in my article, How to run a SELECT query using Mysqli, as well a helper function to simplify the routine.
Following this plan here is your code
$sql = "SELECT * FROM users WHERE id=?"; // SQL with parameters
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $id);
$Stmt->execute();
$result = $stmt->get_result(); // get the mysqli result
$user = $result->fetch_assoc(); // fetch the data
now you can store the username in the session variable:
$_SESSION['name'] = $user['name'];
I would strongly recommend that you avoid the mysqli extension. You should use some database abstraction library instead of using the mysqli functions directly; the mysqli class is not suited to be used on its own.
If you really want to do it purely with the mysqli class, you have few options.
First, you need to open the connection properly. These 3 lines ensure you have the connection ready:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // enable error reporting
$mysqli = new mysqli('localhost', 'username', 'password', 'dbname');
$mysqli->set_charset('utf8mb4'); // always set the charset
Then you need to prepare a statement, bind the parameter and execute it.
$id = '10527391670258314752';
$stmt = $mysqli->prepare('SELECT username FROM user_data WHERE id=?');
$stmt->bind_param('s', $id);
$stmt->execute();
Once the statement is executed you need to fetch the results. If you have only one variable you could simply use bind_result()
$stmt->bind_result($_SESSION['name']);
$stmt->fetch();
echo $_SESSION['name'];
However, this approach is not recommended and not very flexible. Instead it's better to fetch the whole result set and get an array containing the first row.
$result = $stmt->get_result();
$row = $result->fetch_array();
$_SESSION['name'] = $row['username'];
echo $_SESSION['name'];
As an alternative with PDO the same code would look like this:
session_start();
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=$charset", $user, $pass, [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_EMULATE_PREPARES => false,
]);
$id = '10527391670258314752';
$stmt = $pdo->prepare('SELECT username FROM user_data WHERE id=?');
$stmt->execute([$id]);
$_SESSION['name'] = $stmt->fetchColumn();
echo $_SESSION['name'];
The following statement works perfectly fine under PHP 5.2:
$db = new mysqli($db_host, $db_user, $db_pass, $database);
$sql = $db->prepare('SELECT id, field1, field2, field3 FROM people WHERE email = ? AND pass=?');
$user = strtolower($_POST['user']);
$pass = md5($_POST['pass']);
$sql -> bind_param('ss', $user ,$pass);
$sql -> execute();
$sql -> bind_result($id, $field1, $field2, $field3);
if ($sql -> fetch()) {
...
}
However, after upgrading to PHP 5.4 the fetch() fails and gives the following error:
Attempt to read a row while there is no result set associated with the statement
I couldn't find any hints that something has changed regarding the functions I use and the way I use them. I have seen that there was a change for bind_param using arrays in 5.3, but as I'm not using arrays here, I don't think that I'm affected by this change.
Fatal error: Call to a member function prepare() on a non-object in
/home/melazabi/public_html/assigment/The/include/process.php on line
15
// check if the username exists in the database
// line 15 is the one below:
$statement = $conn->prepare("select * from users where username=? AND password=?");
//prepare statment is to try to stop sql injection
$statement->bindParam(1, $un);
$statement->bindParam (2, $pw);
$statement->execute();
As per what you shown in your comment:
You're using a mysql_* based connection
$conn = mysql_connect('localhost','admin','admin') or die("error2"); mysql_select_db("admin") or die("error");
with a PDO query.
You need to use: (replace with actual DB credentials)
$dbname = 'admin';
$username = 'admin';
$password = 'admin';
$conn = new PDO("mysql:host=localhost;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
The error is telling you the your query failed for any number of reasons.
Your db connection failed, either authentication problem or complete failure to connect.
Your params are not defined correctly.
you can debug this by
print_r($statement->errorInfo());
this will give you what the error returned by sql was.
also make user variables are set. If i were to guess not having seen the rest of your code. you probably want $_POST['un'] and $_POST['pw']
echo $un;
echo $pw;
edit
connect to db:
$conn = new PDO('mysql:host='SERVERADDRESS';dbname=DBNAME;charset=utf8', 'USERNAME', 'PASSWORD');
then your query
$statement = $conn->prepare("select * from users where username=? AND password=?");
//prepare statment is to try to stop sql injection
$statement->bindParam(1, $un);
$statement->bindParam (2, $pw);
$statement->execute();
This is my first run with PDO, not sure how much better it is than using mysqli but its part of a project I have to create.
Here is the code that is causing the message, all I am trying to do is update pieces of data within my db table.
<?php
//PHP Data Objects
try{
//Connect
$dbh = new PDO('mysql:host=localhost; dbname = company; charset=utf-8','root', 'bachi619');
} catch(PDOException $e){
echo $e->getMessage();
}
$id = 4;
$name = "logan";
$department = "Design";
$sth = $dbh->query("UPDATE employees SET department=:department,last_name=:lastname WHERE id=:id");
//bind
$sth->bindParam(':id',$id);
$sth->bindParam(':lastname',$name);
$sth->bindParam(':department',$department);
$sth->execute();
?>
you have to use
$dbh -> prepare("UPDATE employees SET department=:department,last_name=:lastname WHERE id=:id");
Use prepare for PDO, check this http://in3.php.net/manual/en/pdostatement.bindparam.php
$sth = $dbh->prepare('UPDATE employees SET department=:department,last_name=:lastname WHERE id=:id' );
The dsn should be non spaced
$dbh = new PDO('mysql:host=localhost;dbname=company','root', 'bachi619');
You need to prepare the SQL statement like this
$sth = $dbh->prepare( 'UPDATE employees SET department=:department,last_name=:lastname WHERE id=:id' );
Then bind the parameters
$sth->bindParam(':id',$id);
$sth->bindParam(':lastname',$name);
$sth->bindParam(':department',$department);
and finally execute the query
$sth->execute();
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();
}