call to member function prepare error - php

I am having an issue executing the below code. I get an error: Fatal error: Call to a member function prepare() on null in C:\xampp\htdocs... everytime I run it. It errors out right when it is about to query the database for some reason.
I am creating a function to check a username and password, and if it matches, log the user in and so forth. What I am trying to do is feed the outer function a username and a password, then pass those variables to the inner function (checkUser) to retrieve the user and password. Once I have those in an array, I want to compare to see if they match. If they do, then I want to continue on (I left the rest out for simplicity's sake). I don't know why I am getting the error I am getting, especially since it won't even run the 3rd line in the CheckUser without a fatal error.
This is homework, fyi, cards on the table. Just trying to get past this part. Thanks for any help.
function isValidUser($username, $password){
$checker = checkUser($username, $password);
if ($checker[user_email] == $username && $checker[user_pwd] == $password ) {
return TRUE;
}
}
function checkUser($username, $password) {
global $db;
$st = $db -> prepare('SELECT * FROM user WHERE user_email = ? and user_pwd = ?;');
$st -> bindParam(1, $username);
$st -> bindParam(2, $password);
$st -> execute();
return $st -> fetch(PDO::FETCH_ASSOC);
}

try this instead of global $db
$db = $GLOBALS['db'];

Related

Call to a member function fetch() on a non-object

I'm getting the error:
Call to a member function fetch() on a non-object
The line this refers to is:
$getProjectIdResult = $stmt->fetch();
Now, I think from this error that there must be something wrong with my database query, since the documentation says PDO query returns false on failure. I'm having trouble identifying what is causing the issue.
I've tried wrapping the fetch in a try/catch, with
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
However the catch isn't triggered and I just get the original fatal error so I haven't been able to get a more specific error.
classes.php
class Query extends Connection {
public function getProjectID($surveyID) {
$query_getProjectID = "SELECT projectID FROM test WHERE surveyID = :surveyID";
$query_getProjectID_params = array(
':surveyID' => $surveyID
);
try {
$stmt = $this->db->prepare($query_getProjectID);
$stmt = $stmt->execute($query_getProjectID_params);
}
catch (PDOException $ex) {
die("Failed to get project ID: " . $ex->getMessage());
}
$getProjectIdResult = $stmt->fetch();
$getProjectID = $getProjectIdResult['projectID'];
return $getProjectID;
}
}
test.php
include_once("includes/classes.php");
include_once("includes/functions.php");
// Bind $_GET data
// localhost/panel/test.php?surveyID=3&status=1&respondentID=666
// Expected result: 111
$surveyID = sanitise($_GET['surveyID']);
$status = sanitise($_GET['status']);
$respondentID = sanitise($_GET['respondentID']);
$con = new Connection();
$query = new Query();
$query->getProjectID($surveyID);
$con->closeConnection();
I've ruled out the sanitise function causing an issue by testing with and without it.
I apologise as I know this is probably just another amateur making another amateur mistake judging by how many posts there are by the same title.
When you call
$stmt = $stmt->execute($query_getProjectID_params);
You assign the return-value of execute() to $stmt, overwriting the variable, making it a boolean instead of an object. When you continue, $stmt no longer holds the PDOStatement object, but is now a boolean.
The solution is simply to remove the overwrite of your object, like this (remove $stmt = in front).
$stmt->execute($query_getProjectID_params);
http://php.net/pdostatement.execute

Fatal error: Call to a member function prepare() on boolean in

I red several questioins, but no one helped.
Fatal error: Call to a member function bind_param() on boolean in -> nope.
Fatal error: Call to a member function prepare() on null -> nope.
Fatal error: Call to a member function count() on boolean -> nope.
Fatal error Call to a member function prepare() on null -> nope.
fatal error call to a member function prepare() on resource -> nope.
Error: Call to a member function prepare() on a non-object -> nope. I am done..
I am using PHP5 and mySql with PDO:
Connection and Select works fine, but the Insert didnt want to work.
That's my function:
function AddNewUser($nickname, $email)
{
ini_set('display_errors', 1); //DELETE ME
ini_set('expose_php', 1); //DELETE ME
$pdo = EstablishDBCon();
echo "Subscribe user..<br/>";
$sql = "INSERT INTO db.table (nickname, email, insertdate, updatedate) VALUES (:nickname, :email, :insertdate, :updatedate)";
try {
$stmt = $pdo->prepare($sql); //Error at this line
//id?
$stmt->bindParam(':nickname', $nickname, PDO::PARAM_STR);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
$stmt->bindParam(':insertdate', date("Y-m-d H:i:s"), PDO::PARAM_STR);
$stmt->bindParam(':updatedate', null, PDO::PARAM_NULL);
$stmt->exeute();
CloseDBCon($pdo);
echo "Subscribed!<br/>";
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
}
The DB pattern is:
id (int not null auto_inc) | nickname (varchar not null) | email (varchar not null) | insertdate (datetime) | updatedate (datetime)
I am new to php and I do not understand that type of error.
I marked the line inside the code, where the error is thrown:
$stmt = $pdo->prepare($sql); //Error at this line
Can someone help me?
Thanks in advance!
//EDIT:
Connection aka db_connection.php:
<?php
echo 'Establishing MySQL Connection<br/>';
$pdo = null;
$dsn = 'mysql: host=xx; dbname=xx';
$dbUser = 'xx';
$pw = 'xx';
try {
$pdo = new PDO($dsn, $dbUser, $pw);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo 'Connection established.<br/>';
}
catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
return $pdo;
?>
Here is the EstablishDBCon function:
function EstablishDBCon()
{
$pdo = include_once 'db_connection.php';
return $pdo;
}
The best way to reuse functions is to put it inside of the include file, then include it at the top of each file you'll need it. So inside of your db_connection.php, create your function:
function EstablishDBCon()
{
$pdo = false;
try{
// Put your PDO creation here
} catch (Exception $e) {
// Logging here is a good idea
}
return $pdo;
}
Now you can use that function wherever you need it. Make sure you always make sure $pdo !== false before you use it, to make sure your connection hasn't failed.
The problem is in the function EstablishDBCon(), which expects the include_once statement to return a value as if the contents of the included file are a function.
function EstablishDBCon()
{
$pdo = include_once 'db_connection.php';
return $pdo;
}
But that's not how include_once works here:
if the code from a file has already been included, it will not be included again, and include_once returns TRUE.
That's why you end up with TRUE (a boolean) in your $pdo variable.
In any event, this kind of construction makes your code really hard to follow.
I recommend only using include and friends to combine self-contained PHP functions together, or to embed parts of HTML pages in one another.
Call to a member function on boolean in this case means that $pdo is not an object, it's a boolean. So it's likely that EstablishDBCon() is returning either a true on success or false otherwise, as opposed to a database resource. Double-check the docs on that function. Here's a link to some relevant documentation on PDO that you'll need.

Including parent objects in "require"d files

Overview
I connect to a database in index.php, then import my classes.php file using require_once(). However, when connecting to the database, the database connection is undefined.
Code
index.php
$dbh = new PDO("mysql:host=$hostname;dbname=$dbname",$username,$password);
require_once("inc/classes.php");
/* ..... */
if($_POST["form"]=="login"){
//Retrieve values
$e = $_POST["email"];
$p = $_POST["password"];
//Data validation
if(!filter_var($e, FILTER_VALIDATE_EMAIL)||strlen($e)<3) $errors->addError("email", "Please enter a valid email address.");
if(strlen($p)<1) $errors->addError("password", "Please enter a valid password");
$errors->killErrors();
//Log user in
$user = new User($e);
if(!$user->login($p)) $errors->addError("form", "Incorrect username or password.");
$errors->killErrors();
exit("success");
}
inc/classes.php
class User
{
public $id, $email, $data;
public function __construct($e = null){
if(isLoggedIn()){
$stmt = $dbh->prepare("SELECT * FROM `users` WHERE `id`=? LIMIT 1");
$stmt->execute(array($_SESSION["userid"]));
$this->data = $stmt->fetch(PDO::FETCH_ASSOC);
} else $this->email = $e;
}
public function login($p){
//Perform database query for user
$stmt = $dbh->prepare("SELECT `id`, `password` FROM `users` WHERE `email`=? LIMIT 1");
$stmt->execute(array($this->email));
if($stmt->rowCount()<1) return false;
//Check password is correct
$data = $stmt->fetch(PDO::FETCH_ASSOC);
if(!password_verify($p, $data["password"])) return false;
if(!$this->email) exit("User can only be logged in with an email address, not by User ID");
$this->id = $data["id"];
return $this->validate($this->id) ? true : false;
}
}
Output
Notice: Undefined variable: dbh in /var/www/html/foo/public_html/bar/inc/classes.php on line 80
Fatal error: Call to a member function prepare() on null in /var/www/html/foo/public_html/bar/inc/classes.php on line 80
Line 80 is:
$stmt = $dbh->prepare("SELECT `id`, `password` FROM `users` WHERE `email`=? LIMIT 1");
Question
How can I include the database connection in index.php and have the classes.php file accept that PDO object?
You have to make your connection global:
global $dbh;
Because of scope. Done carefully it is OK to use global variables. Many use it too haphazardly and have a tendency to want to globalize all of their variables. I personally do it within the function inside the class to eliminate ambiguity.
http://php.net/manual/en/language.variables.scope.php - as #JayBlanchard writes, you need to reference the connection handle as a global variable.
However, it's much cleaner to pass dependencies into your object. For instance, when instantiating your User, you can pass in the connection.
$user = new User($dbh, $e);
You can then set a private variable for the connection handle. This way, you can change the name of the variable in index.php, or change the way it's instantiated without your User class blowing up due to a change in a different file.

PDO: Call to a member function fetch() on a non-object

Feeling a little stupid to ask such a question, but this code block is driving me crazy.
function __construct() {
$db = new db();
$this->db = $db->pdo;
}
function getEmployeeDetails() {
$eid = $this->db->quote($this->eid);
try {
$sql = $this->db->query("
SELECT email, cnumber
FROM employees
WHERE EID = $eid
");
$r = $sql->fetch();
$this->email = $r[0];
$this->cnumber = $r[1];
}
catch (PDOException $e) {
throw new Exception("failed");
}
}
It doesn't throw an exception but fails inside the try block - "Call to a member function fetch() on a non-object".
var_dump of the statement object returns 'false'. Why?
I've tried running the query independently, inside MySql. It returns 1 row.
It's hard to tell whether you have done this, but PDO doesn't throw exceptions by default, except on connection failures. You have to specifically add this:
$this->db = $db->pdo;
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Without this, errors that occur during the query will cause ->query() to return false and that's obviously not an object that will have the ->fetch() method. You can also specify this attribute as part of the constructor call.
Also, you could use prepared statements instead of using ->quote():
$stmt = $this->db->prepare("SELECT email, cnumber
FROM employees
WHERE EID = ?");
$stmt->execute(array($this->eid));
$r = $stmt->fetch();

PHP DB connection and password verification

I have three errors
Warning: mysqli_stmt::fetch() expects exactly 0 parameters, 1 given in
/Volumes/shared/Digital/_Websites/_TEST/qpm/classes/mysql.php on line
20
Notice: Trying to get property of non-object in
/Volumes/shared/Digital/_Websites/_TEST/qpm/classes/mysql.php on line
23
Notice: Trying to get property of non-object in
/Volumes/shared/Digital/_Websites/_TEST/qpm/classes/mysql.php on line
23
Here is my code
<?php
require_once 'includes/constants.php';
class mysql{
private $conn;
function __construct(){
$this->conn = $conn = new MySQLi(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME)
or die ('There was an error in the connection');
}
function verify ($un, $pwd){
$username = $un;
$password = $pwd;
if ($sth = $this->conn->prepare("SELECT pass FROM User WHERE username = '".$un."' LIMIT 1")) {
$sth->execute();
$user = $sth->fetch(PDO::FETCH_OBJ);
// Hashing the password with its hash as the salt returns the same hash
if (crypt($password, $user->hash) == $user->hash) {
return true;
} else {
return false; }
}//end of if;
}//end of verify
}//enfd of class
Just trying to get pass and return true if its the same or false if not
Thanks
Like many, many, many other php users, you are confusing 2 totally different APIs - mysqli and PDO.
Please, choose one, namely PDO, and make your code consistent with it.
Here goes the code with all the useless stuff taken out,
yet with proper things, namely prepared statements, added:
function verify ($un, $pwd)
{
$sql = "SELECT pass FROM User WHERE username = ?"
$sth = $this->conn->prepare($sql);
$sth->execute(array($un));
$pass = $sth->fetchColumn();
return (crypt($pwd, $pass) == $pass);
}
but note that this function of verify should not be a method of mysql class

Categories