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);
Related
I am using PHP to establish a connection to a MYSQL database using PDO. I keep getting this error:
Uncaught Error: Call to a member function query() on null
I am pretty new to this approach but why am I getting a null from the query?
This is the code calling the classes:
<?php
$data = new Data;
echo $data->connect();
$view = new View;
echo $view->getData();
?>
This is the query class with the problem I suspect:
<?php
class View extends Data {
public function getData() {
$sql = 'SELECT * FROM equipment';
$stm = $this->connect()->query($sql);
while ($row = $stm->fetch()) {
echo $row['manuName'] . '<br>';
}
}
}
?>
This is the connection class:
<?php
class Data {
private $dbHost = DB_HOST;
private $dbUser = DB_USER;
private $dbPass = DB_PASS;
private $dbName = DB_NAME;
private $dbHandler;
private $error;
public function connect() {
$con = 'mysql:host=' . $this->dbHost . ';dbname=' . $this->dbName;
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
try {
$this->dbHandler = new PDO($con, $this->dbUser, $this->dbPass, $options);
} catch (PDOException $e) {
$this->error = $e->getMessage();
echo $this->error;
}
}
}
I am not seeing my error. If anyone can see why I cannot pull the data.
Thank you
As u_mulder said in the comments,
your connect method will not return anything.
I updated it as below and made some change on your getData() method:
public function connect() {
$con = 'mysql:host=' . $this->dbHost . ';dbname=' . $this->dbName;
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
try {
//$this->dbHandler = new PDO($con, $this->dbUser, $this->dbPass, $options);
return new PDO("mysql:host=".$this->dbHost.";dbname=".$this->dbName,$this->dbUser,$this->dbPass);
} catch (PDOException $e) {
$this->error = $e->getMessage();
echo $this->error;
}
}
}
class View extends Data {
public function getData($table){
try {
$sql="SELECT * FROM $table";
$q = $this->connect()->query($sql) or die("failed!");
while($r = $q->fetch(PDO::FETCH_ASSOC)){ $data[]=$r; }
return $data;
}
catch(PDOException $e)
{
echo 'Query failed'.$e->getMessage();
}
}
}
$view = new View;
$result = $view->getData('equipment');
print_r($result);
Although I prefer remove connect method and add a constructor in your Data class as below:
public $this->conn;
public function __construct(){
$this->conn = new PDO("mysql:host=".$this->dbHost.";dbname=".$this->dbName,$this->dbUser,$this->dbPass);
}
and then change my getData as below:
$q = $this->conn->query($sql) or die("failed!");
Because as ADyson said in the comments :
you shouldn't really be connecting again every time you run a query..
Thanks again Ali, ADyson & u_mulder,
If I understand what all comments are saying, this code should factor in your advice. Can you please tell me if this is a better approach if you have the time.
Data Class:
<?php
class Data {
private $dbHost = DB_HOST;
private $dbUser = DB_USER;
private $dbPass = DB_PASS;
private $dbName = DB_NAME;
private $error;
public $this->conn;
public function __construct(){
$this->conn = new PDO("mysql:host=".$this->dbHost.";dbname=".$this->dbName,$this->dbUser,$this->dbPass);
}
try {
return new PDO("mysql:host=".$this->dbHost.";dbname=".$this->dbName,$this->dbUser,$this->dbPass);
} catch (PDOException $e) {
$this->error = $e->getMessage();
echo $this->error;
}
}
}
View Class:
<?php
class View extends Data {
public function getData($table){
try {
$sql="SELECT * FROM $table";
$q = $this->conn->query($sql) or die("failed!");
while($r = $q->fetch(PDO::FETCH_ASSOC)){ $data[]=$r; }
return $data;
}
catch(PDOException $e)
{
echo 'Query failed'.$e->getMessage();
}
}
}
Output:
<?php
$view = new View;
$result = $view->getData('equipment');
print_r($result);
?>
This code is still giving errors:
unexpected '->' (T_OBJECT_OPERATOR), expecting ',' or ';'
I wanna get data on table and write a class. But this class doesn't work because pdo doesn't access. How can I get table data with this class?
$db = new PDO("mysql:host=localhost;dbname=xxx;charset=utf8", "xxx", "xxx");
class uye extends PDO{
var $id;
var $kadi;
function cek($id){
$query = $db->query("SELECT * FROM btc WHERE id='{$id}'", PDO::FETCH_ASSOC);
if ( $query->rowCount() ) {
foreach( $query as $row ){
$this->id=$row["id"];
$this->kadi=$row["kadi"];
}
}
}
}
$bilgiler=new uye;
$bilgiler->cek(1);
echo $bilgiler->kadi;
So I'm running this off of fetching all data as I dont know where you're getting $id from.
I generally break my code up into files and folders as I found this easier to work with and others to work on.
// database connection file (dbc.php)
class Database
{
private $host = "127.0.0.1";
private $db = "";
private $user = "";
private $password = "";
public $conn;
public function dbConnect()
{
$this->conn = null;
try
{
$this->conn = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->db, $this->user, $this->password);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $exception)
{
echo "Connection error: " . $exception->getMessage();
}
return $this->conn;
}
}
I then make a common file, this is where you can store all of your frequently used functions or your static functions
// Common file (common.php)
require_once('dbc.php');
class DBCommon
{
private $conn;
public function __construct()
{
$database = new Database();
$db = $database->dbConnect();
$this->conn = $db;
}
public function run($sql)
{
$stmt = $this->conn->prepare($sql);
return $stmt;
}
}
So to explain this a little more, you will see a function of run() this is just to save the tedious $this->conn->prepare on every query.. Now you can run $this->run()
The next would be your class file.. this is where your logic goes:
// your class file... (class.btc.php)
require_once "common.php";
class BTC extends DBCommon
{
public function getQuery()
{
$stmt = $this->run("SELECT * FROM `btc`");
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_OBJ))
{
$rows[] = $row;
}
return $rows;
}
}
Self explanatory..
And then your calling method.. Lets say index.php
// File you're calling your class from (index.php)
require_once "class.btc.php";
$fetch = new BTC();
$returnData = $fetch->getQuery();
foreach ($returnData as $data)
{
echo
"<p>$data->something</p>
<p>$data->somethingElse</p>";
}
It seems a little long winded I know, but the time you'll save overall will help!
I am new to php OOP. I have a question regarding my situation.
db.php
class db{
protected $db_host;
protected $db_name;
protected $db_user_name;
protected $db_pass;
public function __construct() {
$this->db_host="localhost";
$this->db_name="bs";
$this->db_user_name="root";
$this->db_pass="";
}
public function conn(){
try {
$conn = new PDO("mysql:host=$this->db_host;dbname=$this->db_name", $this->db_user_name="root", $this->db_pass);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $conn;
}
catch(PDOException $e)
{
echo $sql . "<br>" . $e->getMessage();
}
}
}
item.php
require "../../includes/db.php";
class item{
public $user_uid;
public $last_id;
public $display_item;
public $iid;
protected $item_id;
protected $item_name;
protected $item_price;
protected $item_quantity;
public function add_item($uid,$item_id,$item_n,$item_p,$item_q){
$db = new db();
$conn=$db->conn();
$this->user_uid=$uid;
$this->item_id=$item_id;
$this->item_name=$item_n;
$this->item_price=$item_p;
$this->item_quantity=$item_q;
try {
$sql = "INSERT item(uid,item_id,item_name,item_price,item_quantity)
VALUES('$this->user_uid','$this->item_id','$this->item_name','$this->item_price','$this->item_quantity')";
$conn->exec($sql);
$this->last_id=$conn->lastInsertId();
}
catch(PDOException $e){
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
}
public function display_item($uid){
$db = new db();
$conn=$db->conn();
$this->user_uid=$uid;
try{
$sql="SELECT * FROM item where uid='$this->user_uid'";
$statement=$conn->query($sql);
while($row=$statement->fetch()){
$this->iid[]=$row['iid'];
$this->display_item[]=[$row['item_id'],$row['item_name'],$row['item_price'],$row['item_quantity']];
}
}
catch(PDOException $e){
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
}
}
as you can see from item.php , i have to call
$db = new db();
$conn=$db->conn();
in add_item() and display_item() .
So that means every method that I have to access to database connection, i have to do that. Is there a easier way to do that by not creating $db = new db() in other class by modifying my codes?
OR
Did i miss out some functions that PHP can do that?
My desired way of doing it
require "../../includes/db.php";
$db = new db();
$conn=$db->conn();
class item{
...
...
public function add_item($uid,$item_id,$item_n,$item_p,$item_q){
try {
$sql = "INSERT item(uid,item_id,item_name,item_price,item_quantity)
VALUES('$this->user_uid','$this->item_id','$this->item_name','$this->item_price','$this->item_quantity')";
$conn->exec($sql);
}
public function display_item($uid){
....
try{
$sql="SELECT * FROM item where uid='$this->user_uid'";
$statement=$conn->query($sql);
so that i only declare 1 time()
$db = new db();
$conn=$db->conn();
in class item() and use it for the rest of methods.
Just add the connection in the constructor. Add the necessary property as well:
class db
{
protected $db_host;
protected $db_name;
protected $db_user_name;
protected $db_pass;
protected $db_conn; // add me here
Then inside the constructor, use the credentials there to connect. So that when you create the object, its already connected, you'll just use the property connection for your executing queries and stuff:
public function __construct()
{
$this->db_host = "localhost";
$this->db_name = "bs";
$this->db_user_name = "root";
$this->db_pass = "";
// connect
try {
$this->db_conn = new PDO("mysql:host=$this->db_host;dbname=$this->db_name", $this->db_user_name="root", $this->db_pass);
$this->db_conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->db_conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
catch(PDOException $e) {
echo $sql . "<br>" . $e->getMessage();
exit;
}
}
Then, extend the db class in item. You can now use db's db_conn property inside item class.
class item extends db
{
public $user_uid;
public $last_id;
public $display_item;
public $iid;
protected $item_id;
protected $item_name;
protected $item_price;
protected $item_quantity;
public function display_item($uid)
{
try {
$stmt = $this->db_conn->prepare('SELECT * FROM item WHERE uid = :uid');
$stmt->bindValue(':uid', $uid);
$stmt->execute();
foreach($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
$this->iid[] = $row['iid'];
$this->display_item[] = [$row['item_id'], $row['item_name'], $row['item_price'], $row['item_quantity']];
}
} catch(PDOException $e) {
echo $e->getMessage();
exit;
}
}
}
Sidenote: I've added prepared statements on top
today i tried to convert my code to PHP/MySQLi OOP code.
class Database
{
private $host;
private $user;
private $password;
private $db;
private $mysqli;
function __construct()
{
$this->host = "*****";
$this->user = "*****";
$this->password = "******";
$this->db = "*****";
$this->mysqli = new mysqli($this->host, $this->user, $this->password, $this->db);
if (mysqli_connect_errno()):
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
endif;
}
}
This is a script for the query's:
include_once("WD_Config/database.php");
class Adressen_Db
{
function __construct()
{
$this->database = new Database();
}
public function selecteer()
{
$query = "SELECT * FROM wd_adressen WHERE verborgen = 0 ORDER BY naam ASC";
$result = $this->database->mysqli->query($query);
return $result;
}
}
And this is how i call it.
$adressen = new Adressen_Db;
$adressen_result = $adressen->selecteer();
echo "<p>";
while ($row = $adressen_result->fetch_assoc()):
echo "<a href='http://maps.google.com/?q=".$row['voladres']."' target='_blank'>".$row['naam']."</a> woonachtig op <i>".$row['voladres']."</i><br>";
endwhile;
echo "</p>";
I alway get a "Call to a member function query() on a non-object". Doesn't matter what i trie ...
Can somebody tell me why that is?
Thanks!
The $mysqli variable in class Database is declared private.
You can access it only through setters and getters.
I think while you definitely need to have $mysqli as public so it can be accessed in the other method, there might be something else, as the error would be something like
trying to access private property in database class
or something like that, whereas your script throws a non-object call error
I think your new Adressen_Db; lacks the parenthesis:
$adressen = new Adressen_Db();
You can replace your code with this:
Config.php
<?php
define("DB_HOST", "localhost");
define("DB_USER", "root");
define("DB_PASS", "");
define("DB_NAME", "your_database_name");
Now include this file in your database file
require_once 'config.php';
Class Database {
public $host = DB_HOST;
public $user = DB_USER;
public $pass = DB_PASS;
public $dbname = DB_NAME;
public $link;
public $error;
public function __construct() {
$this->getConnection();
}
private function getConnection() {
$this->link = new mysqli($this->host, $this->user, $this->pass, $this->dbname);
if (!$this->link) {
$this->error = "Connection failed" . $this->link->connect_error;
return false;
}
}
// for only select query
public function select($query) {
$result = $this->link->query($query) or
die($this->link->error . __LINE__);
if ($result->num_rows > 0) {
return $result;
} else {
return false;
}
}
// for insert, delete and update
public function myquery($query) {
$myquery = $this->link->query($query) or
die($this->link->error . __LINE__);
if ($myquery) {
return $myquery;
} else {
return false;
}
}
}
Now, make your queries like this:
<?php
require_once './lib/Database.php';
?>
<?php
class Admin {
private $db;
public function __construct() {
$this->db = new Database();
}
public function getData(){
$query = "SELECT * FROM admin";
$result = $this->db->select($query);
if($result != false){
while($row = $result->fetch_assoc()){
// do your thing
}
}
}
public function insert(){
$query = "INSERT INTO admin(admin_name) VALUES('$admin_name')";
$result = $this->db->myquery($query);
if($result){
$msg = "User has been added successfully.";
return $msg;
} else {
$msg = "Error while adding user. Please try again.";
return $msg;
}
}
}
Do this.
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.