Fatal error: Uncaught Error: Call to undefined method Database::query() in C:


#1

Hi Guys
I’m having a problem finding the problem in my code that produces the above error, can somebody please advise. Thanks

<?php
// Include database class  `Preformatted text`
include 'classes/db.class.php'; 

// Define configuration  
define("DB_HOST", "localhost");  
define("DB_USER", "root");  
define("DB_PASS", "");  
define("DB_NAME", "codeTest");

$database = new Database();

$database->query('INSERT INTO mytable (FName, LName, Age, Gender) VALUES (:FName, :LName, :Age, :Gender)');

$database->bind(':FName', 'John');  
$database->bind(':LName', 'Smith');  
$database->bind(':Age', '24');  
$database->bind(':Gender', 'male');

$database->execute(); 

echo $database->lastInsertId(); 
?>

#2

Hi @eont and welcome to the SitePoint Forums.

Try this to show the return type:

$database = new Database();
echo gettype( $database );
echo '<br>';
die; // stop further processing

http://php.net/manual/en/function.gettype.php


#3

Hi John
Thanks for your response, I did as you requested and got an output response of “OBJECT”. Can you explain why you have asked me to do this so that I can better understand your reasoning behind it. It’s the first time I’ve started working with prepared statements in OOP and PDO in PHP. I’m using MySQL Ver 8 and PHP 7. I appreciate you help. Thanks


#4

Hi,

I thought the response would have shown a Boolean false indicating that the connection had failed.

I am typing on my mobile at the moment because my desktop harddrive failed and I have to reinstall the system, utilities, etc. onto my new harddrive.

Perhaps another user could suggest more tests and help with a solution.


#5

From the error it looks like there is no function called query in your database class. Please paste the contents of db.class.php


#6

Hi Tom
Will do. Thanks.


#7

Here are the contents of db.class.php.

<?php
class Database{  
private $host = DB_HOST;  
private $user = DB_USER;  
private $pass = DB_PASS;  
private $dbname = DB_NAME;
  
private $dbh;  
private $error;

// Instantiate database.  

public function __construct(){

// Set DSN  
$dsn = 'mysqli:host=' . $this->host .';dbname=' . $this->dbname;  
// Set options  
$options = array(  
PDO::ATTR_PERSISTENT => true,  
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION  
);  
// Create a new PDO instanace  
try{  
$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);  
}  
// Catch any errors  
catch(PDOException $e){  
$this->error = $e->getMessage();  
}  
}  
public function bind($param, $value, $type = null){  
if (is_null($type)) {  
switch (true) {  
case is_int($value):  
$type = PDO::PARAM_INT;  
break;  
case is_bool($value):  
$type = PDO::PARAM_BOOL;  
break;  
case is_null($value):  
$type = PDO::PARAM_NULL;  
break;  
default:  
$type = PDO::PARAM_STR;  
}  
}  
$this->stmt->bindValue($param, $value, $type);  
}
public function execute(){  
return $this->stmt->execute();  
}
 public function resultset(){  
$this->execute();  
return $this->stmt->fetchAll(PDO::FETCH_ASSOC);  
}
public function single(){  
$this->execute();  
return $this->stmt->fetch(PDO::FETCH_ASSOC);  
}
public function rowCount(){  
return $this->stmt->rowCount();  
}  
public function lastInsertId(){  
return $this->dbh->lastInsertId();  
}  
public function beginTransaction(){  
return $this->dbh->beginTransaction();  
}
public function endTransaction(){  
return $this->dbh->commit();  
}  
public function cancelTransaction(){  
return $this->dbh->rollBack();  
}  
public function debugDumpParams(){  
return $this->stmt->debugDumpParams();  
} 
}
?>

#8

So like what @TomB was saying. You’re missing the query method in that class. Just create it and have 1 argument passed down to it. That should fix your problem.

Also, this isn’t right. It should be mysql:host.


#9

Hi spaceshiptrooper

Both you and tom are right, I left out the query function

public function query($query){  
$this->stmt = $this->dbh->prepare($query);  
}  

I have also amended the above to mysql:host. Thanks for everyones input, I’ll let you know if the code works. Thanks again :heart:


#10

I’d also recommend againt reinventing the wheel. Is there any reason for wrapping the PDO class like this? Why not just use the PDO class where you need it?


#11

I actually like the abstraction. If PDO ever becomes obsolete you can just change this single class to use the new API that replaces PDO and be done with it. A lot easier than fixing PDO code all over the place.

What I don’t like is using constants to define where to connect to, and then reading those contents in the class. What if you ever wanted two different database connections. That’s not possible in the current implementation.