Fatal error: Call to undefined method Database::prepare() - php

I have created a separate class for database and users.
Database.php
class Database{
private $db;
public function __construct(){
/*** mysql hostname ***/
$hostname = 'localhost';
/*** mysql username ***/
$username = 'username_web';
/*** mysql password ***/
$password = 'password_web';
try {
$this->db = new PDO("mysql:host=$hostname;dbname=kamadhenu_web", $username, $password);
/*** echo a message saying we have connected ***/
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
/*** Query Function ***/
public function query($sql)
{
return $this->db->query($sql);
}
}
Users.php
class Users{
private $db;
public function __construct($database) {
$this->db = $database;
}
public function login($username, $password)
{
$query=$this->db->prepare("SELECT `password`, `id` FROM `users` WHERE `username` = ?");
$query->bindValue(1, $username);
try{
$query->execute();
$data = $query->fetch();
$stored_password = $data['password'];
$id = $data['id'];
#hashing the supplied password and comparing it with the stored hashed password.
if($stored_password === sha1($password)){
return $id;
}else{
return false;
}
}catch(PDOException $e){
die($e->getMessage());
}
}
}
Here is my Login page with username and password.
login.php
include('database.php');
include('users.php');
$dbh= new Database();
$users= new Users($dbh);
if (isset($_POST['submit']))
{
$username= $_POST['username'];
$password= $_POST['password'];
$login = $users->login($username, $password);
if ($login === false) {
$errors[] = 'Sorry, that username/password is invalid';
}
else {
// username/password is correct and the login method of the $users object returns the user's id, which is stored in $login.
$_SESSION['id'] = $login; // The user's id is now set into the user's session in the form of $_SESSION['id']
#Redirect the user to home.php.
header('Location: list-updates.php');
exit();
}
}
When I execute I get an error:
Call to undefined method Database::prepare()

You create $dbh when you instantiate Database(), but instantiating the Database only returns an instance of your Database class, not your db connection. You should have a getDb to get your connection from database object:
$dbClass = new Database();
$dbh = $dbClass->getDb(); // here you get the connection
$users= new Users($dbh); // here you give to Users() the $dbh, that isn't your
// connection.. it's just Database class
Database construct only return an instance of your Database class, not your db connection
class Database{
private $db;
public function __construct(){
try {
$this->db = new PDO("mysql:host=$hostname;dbname=kamadhenu_web", $username, $password);
/*** echo a message saying we have connected ***/
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
public function getDb() {
if ($this->db instanceof PDO) {
return $this->db;
}
}
}

add the method "getmyDB" to database file
class Database
{
/* Properties */
private $conn;
private $dsn = 'mysql:dbname=test;host=127.0.0.1';
private $user = 'root';
private $password = '';
/* Creates database connection */
public
function __construct()
{
try
{
$this->conn = new PDO($this->dsn, $this->user, $this->password);
}
catch(PDOException $e)
{
print "Error!: " . $e->getMessage() . "";
die();
}
return $this->conn;
}
public function getmyDB()
{
if ($this->conn instanceof PDO)
{
return $this->conn;
}
}
}
and call it when you create the constructor in the file user.php
include "database.php";
class User
{
/* Properties */
private $conn;
/* Get database access */
public
function __construct()
{
$this->conn = new Database();
$this->conn = $this->conn->getmyDB();
}
/* Login a user */
public
function login()
{
$stmt = $this->conn->prepare("SELECT username, usermail FROM user");
if ($stmt->execute())
{
while ($rows = $stmt->fetch())
{
$fetch[] = $rows;
}
return $fetch;
}
else
{
return false;
}
}
}
and finally add test.php file
include "user.php";
$user = new User();
$list = $user->login();
foreach($list as $test)
{
echo $test["username"];
}

Your Database class does not extend PDO neither it does implement prepare method.
In order to access your PDO object, you must make it public and access like:
From User class:
$this->db->db->prepare();
The best way would be to extend the PDO class.

Related

OOP - Mysqi Connection: Uncaught Error: Call to undefined method DBConnection::prepare()

I'm a newbie at PHP OOP and I have a problem with my code and i keep getting an error:
Fatal error: Uncaught Error: Call to undefined method DBConnection::prepare() in E:\xampp\htdocs\includes\user_functions.php:35 Stack trace: #0 E:\xampp\htdocs\includes\process_login.php(12): User::login('admin', 'aa17a9b71574929...', Object(DBConnection)) #1 {main} thrown in E:\xampp\htdocs\includes\user_functions.php on line 35
The error is in the prepare statement and i can't seem to figure out what i'm doing wrong. I can't seem to get my head around. I Assume it has something to do with the construct object
I have already created a class for my connection, which i call upon in my login script. Once i am in the script, i call the login function. It seems to accept the connection, but the issue arises, when i call the prepare() function.
Here is my login script:
<?php
include_once ('db_connect.php'); //Here i define my connection
include_once ('user_functions.php'); //In this file my functions
$mysqli = new DBConnection(); //i create a new object of the connection
User::sec_session_start(); // This is the script in my user_functions.php
if (isset($_POST['email'], $_POST['p'])) {
$email = $_POST['email'];
$password = $_POST['p'];
if (User::login($email, $password, $mysqli) == true) {
header('Location: ../index.php');
} else {
header('Location: ../error.php?error=1');
}
} else {
echo 'Invalid Request';
}
?>
Here is my db_connect.php
<?php
include_once ('psl-config.php'); // Da functions.php nicht included ist
class DBConnection {
protected $mysqli;
protected $db_host = HOST;
protected $db_username = USER;
protected $db_password = PASSWORD;
protected $db_name = DATABASE;
public function __construct() {
$this->mysqli= new mysqli($this->db_host, $this->db_username, $this->db_password, $this->db_name)
or die($this->mysqli->error);
return $this->mysqli;
}
//$mysqli = new mysqli(HOST, USER, PASSWORD, DATABASE); //This method worked previously, when not done with OOP
public function real_escape_string($str) {
return $this->mysqli->real_escape_string();
}
function __destruct() {
$this->mysqli->close();
}
}
?>
Here is my user_functions.php
<?php
require_once ('db_connect.php');
class User {
public function __construct($mysqli) {
return $this->mysqli=$mysqli;
}
function login($email, $password, $mysqli) {
if ($stmt = $mysqli->prepare("SELECT user_id, username, password, salt //This is where the error occurs
FROM users
WHERE email = ? OR username = ?
LIMIT 1")) {
$stmt->bind_param('ss', $email, $email);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($user_id, $username, $db_password);
$stmt->fetch();
if ($db_password == $password) {
$user_browser = $_SERVER['HTTP_USER_AGENT'];
$user_id = preg_replace("/[^0-9]+/", "", $user_id);
$_SESSION['user_id'] = $user_id;
$username = preg_replace("/[^a-zA-Z0-9_\-]+/",
"",
$username);
$_SESSION['username'] = $username;
$_SESSION['login_string'] = hash('sha512',
$password . $user_browser);
return true;
} else {
return false;
}
}
}
}
?>
Because you've got DBConnection instance in your $mysqli variable, not $this->mysqli from __construct() call. Try to make separate method in your DBConnection class, that returns $this->mysqli. Something like this:
...
public function __construct() {
$this->mysqli= new mysqli($this->db_host, $this->db_username, $this->db_password, $this->db_name)
or die($this->mysqli->error);
}
public function getConnection()
{
return $this->mysqli;
}
...
And make $mysqli like this:
$mysqli = (new DBConnection())->getConnection();
return $this->mysqli; this does not work. Have a look at this: https://3v4l.org/OZjEl
You could add a method getConnection or try to extend the MySQLi class.
Try this.
<?php
class DBConnection{
private $db;
public function __construct(){
try {
$this->db = new PDO("mysql:host=$hostname;dbname=$dbname", $username, $password);
echo "Connection Successful";
}catch(PDOException $e){
echo $e->getMessage();
}
}
public function getConnection() {
if ($this->db instanceof PDO) {
return $this->db;
}
}
}
?>
And then create instance of class and get conn object
$db_instance = new DBConnection();
$conn = $db_instance->getConnection();

Passing db object to php class oop style does not work

Simple classes using oop php, trying to pass db object (from db class) to another class ( category class ) so i can get the content from db .
db class db.php
class db {
//put your code here
private $hostname = "127.0.0.1";
private $dbname = "php_oop_crud";
private $username = "root";
private $password = "";
public $conn;
public $status = 0;
public function getConnection() {
$this->conn = null;
try {
$this->conn = new PDO("mysql:host:$this->hostname;dbname=$this->dbname", $this->username, $this->password);
// this return null if unsccessfull
$this->status = $this->conn->getAttribute(PDO::ATTR_CONNECTION_STATUS);
if ($this->status) {
echo "connected to db : " . $this->status;
return $this->conn;
}
} catch (PDOException $ex) {
echo "Can't connect to db " . $this->status;
error_log("Ayman :: {{$ex->getMessage()}} - {{$ex->getFile()}} - {{$ex->getLine()}}");
return $this->conn;
}
}
}
pass db object to category class in index.php
// Create db connection pass it to product and category objects
$databaseConn = new db();
$db = $databaseConn->getConnection();
// create object and send database object to class
// now we need to call the function who crearte tha actual connection getConnection();
$category= new category($db);
$category->read();
category class category.php
<?php
class category {
//put your code here
private $databaseConn;
private $tabel_name = 'categories';
public $id;
public $name;
public function __construct($db) {
$this->databaseConn = $db;
}
public function read() {
$sql = 'SELECT * FROM categories';
$query = $this->databaseConn->prepare($sql);
$isok = $query->execute();
$row= $query->rowCount();
echo "row : " . $row;
var_dump($row);
echo "isok : " . $isok;
var_dump($isok);
if ($isok) {
echo "the red process is done and ok <br/> category table";
} else {
echo "Cant get category ";
var_dump($isok);
}
}
}
Now the var_dump($row) and var_dump($isok); are always false , mean while I can connect successfully to db
Credit for #ishegg , be careful when you construct your PDO .
// this will NOT work
$this->conn = new PDO("mysql:host:$this->hostname;dbname=$this->dbname", $this->username, $this->password);
// this will Work
$this->conn = new PDO("mysql:host=".$this->hostname.";dbname=".$this->dbname, $this->username, $this->password);

How can I access a parent's variable from a child's function in PHP?

This is my code :
<?php
class DB {
public $config = array('DBUSER'=>'root',
'DBPASS'=>'',
'DBHOST'=>'localhost',
'DBNAME'=> 'ninjacks');
function get_connection() {
try {
$db = new PDO('mysql:host='.$this->config['DBHOST'].'; dbname='.$this->config['DBNAME'].'; charset=utf8'
, $this->config['DBUSER'], $this->config['DBPASS']);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $ex) {
echo 'An Error occured! '.$ex->getMessage(); //user friendly message
return false;
}
return $db;
}
}
?>
<?php
require_once('database.php');
class Base {
protected $conn;
protected $db;
function __construct() {
$this->db = new DB();
$this->conn = $this->db->get_connection();
}
}
?>
<?php
include_once('base.php');
class Session extends Base{
function __construct() {
parent::__construct();
}
public function connexion($email, $password){
$sql = "SELECT email, password
FROM users
WHERE actif = '1' AND hash = NULL AND email = :email AND password = :password";
$sth = $this->db->prepare($sql);
$sth->execute(array(':email' => $email, ':password' => md5($password)));
$count = $sth->rowCount();
if($count > 0)
return true;
else
return false;
}
}
?>
In my connexion function, I always receive this error when using $this->db->prepare(); :
Using $this when not in object context
I read a lot of forums before posting here, and I have also tried 2 hours.
The reason its not working is because $this->db->prepare() doesnt exist as $this->db is an instance of your DB class which does not have a prepare() method. Instead you need to call it this way $this->conn->prepare()

OOP using php and mysqli to return data from database

I have a Database php file and a user php file. The Database is where I make my connection to the database.
<?php
/*
* Mysqli database class - only one connection
*/
class Database{
private $_connection;
private static $_instance; //The single instance
private $_host = 'localhost';
private $_username = 'root';
private $_password = '';
private $_database = 'blogwebsite';
public static function getInstance(){
if(!self::$_instance){ // If no instance make one
self::$_instance = new self();
}
return self::$_instance;
}
/*
* Constructor
*/
public function __construct(){
$this->_connection = new mysqli($this->_host, $this->_username,
$this->_password, $this->_database);
// Error handling
if(mysqli_connect_error()){
trigger_error("Failed to connect to MySQL: " .
mysqli_connect_errno(), E_USER_ERROR);
}else{
echo "You are connected to " . $this->_database;
}
}
// Magic method clone is empty to prevent duplication of connection
public function __clone(){ }
// Get mysqli connection
public function getConnection(){
return $this->_connection;
}
}
?>
This is the user page and I am including the Database page. I get an error that is saying ' Undefined variable: mysqli' AND 'Call to a member function prepare() on a non-object'.
<?php
include('class.database.php');
class api{
public function __construct(){
$db = Database::getInstance();
$mysqli = $db->getConnection();
}
public function getUsername($username){
$statement = $mysqli->prepare("SELECT username FROM users");
$statement->bind_param('s', $username);
$statement->execute();
$statement->bind_result($username);
$statement->fetch();
$statement->close();
return $username;
}
}
$username = new api();
echo $username->getUsername($username);
?>
Can anyone please help with any assistance. Thank you verry much.
You don't have a 'mysqli' variable in class 'api'. Also, you should call getConnection() after getting the Database instance.
class api{
private $mysqli;
public function __construct(){
$db = Database::getInstance()->getConnection();
$this->mysqli = $db->getConnection();
}
public function getUsername($username){
$statement = $this->mysqli->prepare("SELECT username FROM users");
$statement->bind_param('s', $username);
$statement->execute();
$statement->bind_result($username);
$statement->fetch();
$statement->close();
return $username;
}
}
You need to create a local variable $mysql :
class api{
protected $mysql; // <-- Here
public function __construct(){
$db = Database::getInstance();
$this->mysqli = $db->getConnection();
}
public function getUsername($username){
$statement = $this->mysqli->prepare("SELECT username FROM users");
$statement->bind_param('s', $username); // <-- what this for ?
$statement->execute();
$statement->bind_result($username);
$statement->fetch();
$statement->close();
return $username;
}
}
$username = new api();
echo $username->getUsername($username);

QLSTATE[HY000] [1045] Access denied for user

Anyone know what this means? not a very experience programmer.
SQLSTATE[HY000] [1045] Access denied for user ''#'..*.' (using password: NO)SELECT * FROM **_Students
code in StudentDataSet
require_once ('Models/StudentData.php');
require_once ('Models/Database.php');
class StudentsDataSet {
protected $_dbHandle, $_dbInstance;
public function __construct()
{
$this-> _dbInstance = Database::getInstance();
$this-> _dbHandle = $this-> _dbInstance-> getdbConnection();
}
public function fetchAllStudents() {
$sqlQuery = 'SELECT * FROM MUD193_Students'; // put your students table name
echo $sqlQuery; //helpful for debugging to see what SQL query has been created
$statement = $this->_dbHandle->prepare($sqlQuery); // prepare PDO statement
$statement->execute(); // execute the PDO statement
$dataSet = [];
while ($row = $statement->fetch()) {
$dataSet[] = new StudentData($row); }
return $dataSet; }
Code in StudentData
<?php
class StudentDataClass {
private $_id, $_firstName, $_lastName, $_international, $_courseID;
public function __construct($dbRow) {
$this->_id = $dbRow['id'];
$this->_firstName = $dbRow['first_name'];
$this->_lastName = $dbRow['last_name'];
if ($dbRow['international'])
$this->_international = 'yes';
else
$this->_international = 'no'; $this->_courseID = $dbRow['courseID'];
}
public function getStudentID() {
return $this->_id;
}
}
Code in Databse
<?php
class Database {
protected static $_dbInstance = null;
protected $_dbHandle;
public static function getInstance() {
$username = '****';
$password = '****';
$host = '*******';
$dbName = '****';
if (self::$_dbInstance === null) {
self::$_dbInstance = new self($username, $password, $host, $dbName);
}
return self::$_dbInstance;
}
private function __construct($username, $password, $host, $database) {
try {
$this->_dbHandle = new PDO("mysql:host=$host; dbname=
$database; $username, $password");
} // creates database handle with connection info
catch (PDOException $e) { // catch any failure to connect to database
echo $e->getMessage();
}
}
public function getdbConnection() {
return $this->_dbHandle; // returns the database handle to be used elsewhere
}
public function __destruct() {
$this->_dbHandle = null; // destroys the destroys the database handle
}
}
This is a Access denied error. You should check your database username and password with which you login
Define your;
Database Name
Database Username
Database User Password
Probably script could not reach variables that you defined.
If you give more information like which language you are using to connect database, we can help you better.

Categories