Using class database connection in other class - php

I have a class with a connection to a database
$db = new db();
class db {
public $server = 'localhost';
public $user = '';
public $passwd = '******';
public $db = '';
public $dbCon;
function __construct() {
$this->dbCon = mysqli_connect($this->server, $this->user, $this->passwd, $this->db);
}
function __destruct() {
mysqli_close($this->dbCon);
}
}
Now i want to make an other class and using the connection like this:
class Categories (
function GetCategory($cat) {
$myQuery = "SELECT * FROM test GROUP BY $cat";
$results = mysqli_query($this->dbCon, $myQuery);
return $results;
}
)
How can i use the connection in a other class?
Can somebody help me out whit this?

Make the $dbCon in your db class a static variable, so you can access it from category's using db::$dbcon as the connection variable. You could also make a static function returning the static dbcon variable, usefull tot check if it is actually a link and not null.
This is just one solution of many possibilities, but probably the easiest to implement because it isn't likely you need more connections to a db, so a static is perfect for it.
A static is nothing more then a variable living in the namespace it is defined in, you don't need to initialize the class in order to access it. It's value is shared across all instances of the object, so creating multiple DB class instances allows you tot just return a static if it was set in a previous DB class instance.
class db{
static $link;
static function connect(){
if(self::$link = mysqli_connect(....)){
return self::$link;
} else {
die('could not connect to db');
}
}
static function getcon(){
return isset(self::$link) ? self::$link : self::connect();
}
}
class Categories{
function GetCategory($cat){
$myQuery = "SELECT * FROM test GROUP BY $cat";
return mysqli_query(db::getcon(), $myQuery);
}
}

Create an object of the db class in the categories class. Then use that object to query the db accordingly. Also make sure you use a static variable in the db class. SO that the connection variable is created once and will be used all along the application.
Your db class may look like this
class db {
public $server = 'localhost';
public $user = '';
public $passwd = '******';
public $db = '';
public static $dbCon;
function __construct() {
$this->dbCon = mysqli_connect($this->server, $this->user, $this->passwd, $this->db);
}
function __destruct() {
mysqli_close($this->dbCon);
}
}
Your categories class may look like this
class Categories {
$connection=db::$dbCon;
if(!$connection){
$db=new db();
$connection=db::$dbCon;
}
function GetCategory($cat) {
$myQuery = "SELECT * FROM test GROUP BY $cat";
$results = mysqli_query($this->connection, $myQuery);
return $results;
}
}

Related

PHP extending MySQL master class TWICE

Below is the solution to my question. I didn't have my class written wrong. I accidentally used a "die" function inside my master DB class that made all my queries fail. I was tracking down the wrong problem.
I hope you guys find this class example useful. It's clean, and very useful for wrapping SQL calls in a single location for multiple databases. By allowing the extension, you can track your calls much easier my var name.
class A extends DB {
protected $connection;
function __construct()
{
$this->db_host = "server.com:3327";
$this->db_name = "db_name_one";
$this->db_username = "root";
$this->db_password = 'pw';
// .. equals all the setup vars
parent::__construct();
}
}
class B extends DB {
function __construct()
{
$this->db_host = "server.com:3327";
$this->db_name = "db_name_two";
$this->db_username = "root";
$this->db_password = 'pw';
// .. equals all the setup vars
parent::__construct();
}
}
class DB {
function __construct()
{
$this->connect()
}
public function connect()
if (!$connection = # mysql_connect ($this->db_host,$this->db_username,$this->db_password,$this->second_flag))
die ('I cannot connect to the database because: ' . mysql_error());
if (!mysql_selectdb($this->db_name,$connection))
$this->showerror();
return $connection;
}
public function executeSQL($query)
{
$results = mysql_query($query,$this->connection);
if (!$results) {
die(...);
}
return $results;
}
}
$db1 = new A();
$db2 = new B();
$db1->executeSQL("select * from table");
I don't know if there's a legitimate reason to extend the DB class here. Unless those extending classes add something to the DB (e.g. they adapt it to a different database), then they have nothing to do with being a DB as such. Just because they use a DB doesn't mean they should extend one.
The simplest thing to do is: make one class that handles your database interaction. When you make a new instance of that class, it establishes a new connection to the database. This way you can have as many independent connections as you want. You then simply pass those instances to whoever needs them:
class DB {
protected $connection;
public function __construct() {
$this->connection = mysql_connect(..);
if (!$this->connection) {
throw new Exception(..);
}
}
..
}
class A {
protected $db;
public function __construct(DB $db) {
$this->db = $db;
}
..
}
$db = new DB;
$a = new A($db);

PHP DBconnection Class connection to use in another

I have one DB class in which I am calling mysqli connect in constructor, I want to use this connection in another class. How I can do that, Do i have to reinitialize class first inside the class II ?? Or do I have to Inherit DB Class to class 2 ??
appreciate any guidance.
Thanks in advance,
Sambhav
Below are Rough outline of both the classes.
CLASS I - DB Class
class Db {
private $dbHost = "";
private $dbUser = "";
private $dbPass = "";
private $dbDatabase = "";
function __construct() {
$mysqli = new mysqli($this->dbHost, $this->dbUser, $this->dbPass, $this->dbDatabase);
if ($mysqli->connect_errno) {
echo "Error in connecting to database" . $mysqli->connect_error;
}
//echo "connected to database";
}
}
class II - The Class trying to use db connection
class MyClass {
private $details = array();
public function getDetails() {
$query = "SELECT `user` FROM `db`.`table`";
$result = $mysqli->query($query);
while ($row == $result->fetch_assoc()) {
//.........
}
return $details;
}
}
You can use a protected property within the class that is trying to use Db, for example;
class MyClass {
protected $objDb;
public function connectToDb() {
$this->objDb = new Db();
}
Then, within your getDetails method, use $this-> to "access" the Db class.
$result = $this->objDb->query($query);
And usage;
$objMyClass = new MyClass();
$objMyClass->connectToDb();
$objMyClass->getDetails();
Alternatively, you could put connectToDb method within your __construct()
Here is the full code: http://harrydenley.com/stackoverflow-25112589/ (Tested on my server and all works. I had to make a few changes, which you can see in the post)

How to use $db instead of $GLOBALS['db'] in my classes?

I need to use $GLOBALS['db'] in my classes ($db is defined in my index.php), but I don't want to use $GLOBALS['db'] when I have to call it.
I wrote this code at the beginning of my classes :
class ClassName
{
var $db;
public function __construct()
{
$this->db = $GLOBALS['db'];
}
public function test()
{
$val = $this->db->oneValue('SELECT first_name FROM users LIMIT 0, 1');
echo $val->first_name;
}
}
But I'm not enjoying this; I prefer to use directly $db in my code. Is there a solution to be able to call $GLOBALS['db'] by $db?
Simples, just inject in the constructor or a setter method: (I'm assuming $db is an object here, not an array of connection parameters etc)
class ClassName
{
protected $db;
public function __construct($db)
{
$this->setConnection($db);
//Any other constructor things you want to happen...
}
/*
* This is just here for convenience, this could be protected if you only want to set
* the db connection via the constructor
*/
public function setConnection($db)
{
$this->db = $db;
}
public function test()
{
$val = $this->db->oneValue('SELECT first_name FROM users LIMIT 0, 1');
echo $val->first_name;
}
}
As mentioned in some comments above, this is a form of dependency injection which will give you more ability to re-use code inside your project (A Good Thing TM).
I prefer using singleton pattern for databases.
this is the DB class i am using for my app.
class Database {
protected static $_dbh;
const HOST = 'localhost';
const DATABASE = 'dbname';
const USERNAME = 'username';
const PASSWORD = 'password';
private function __construct() { }
public static function getInstance() {
if(!isset($_dbh)) {
try {
#Connection String.
self::$_dbh = new PDO('mysql:host='.self::HOST.';dbname='.self::DATABASE,self::USERNAME,self::PASSWORD);
self::$_dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
#Print Errors.
echo $e->getMessage();
}
}
return self::$_dbh;
}
}
as i am using singleton pattern the connection will be re-used. you can now use the connection everywhere in your app by calling static connection method i.e
class ClassName
{
protected static $_dbh;
public function __construct() {
self::$_dbh = Database::getInstance();
}
public function test() {
$sth = self::$_dbh->query('SELECT first_name FROM users LIMIT 0, 1');
$row = $sth->fetchAll(PDO::FETCH_ASSOC);
echo $row['first_name'];
}
}

Nested class in php 5

I want to use a class inside other class.
This is my first class:
class mydb {
public function connect($host="localhost",$user,$pass,$data,$persistency=False) {
$this->host = $host;
$this->user = $user;
$this->pass = $pass;
$this->data = $data;
$this->persistency = $persistency;
$this->link=#mysql_connect($this->host,$this->user,$this->pass)or die(mysql_error());
If(($this->link) AND ($this->data)) {
If(#mysql_select_db($this->data,$this->link) or die(mysql_error())) {
return True;
}
}
return False;
}
public function query($query="",$sup="") {
If($sup) {
$query=#mysql_query($query,$this->link)or die("<br /><br />".mysql_error()."<br /><br />");
} Else {
$query=#mysql_query($query,$this->link) or die("<br /><br />".mysql_error()."<br /><br />");
}
return($query);
}
}
This is my second class:
class articles {
function getpath($id) {
$sql=$db->query("select id,name from articles where id='$id'");
$row=mysql_fetch_array($sql);
return $row['name'];
}
}
I receive this error: ( Fatal error: Call to a member function query() )
You didn't create $db anywhere.
You need to create reference to the mydb class in the articles class. Assuming you create an instance of the mydb class and stored it in the variable $db, this is what you would do.
class articles {
public static $db = null;
...
self::$db->query(...);
}
articles::$db = $db;
The variable doesn't have to be static, it could be a regular class variable. You would then reference it like
$this->db->query(...);
As has been mentioned, you need an instance of the mydb class made available to articles.
Here's a simple example (an anti-pattern, perhaps):
class articles {
private $db = null; // add a class property to hold your database object
// each time we create an articles object, we'll connect to the database
public function __construct() {
$this->db = new mydb(); // add your connection params
}
public function getpath($id) {
// now we can reference the object via the class property $this->db
$sql = $this->db->query("select id,name from articles where id='$id'");
$row = mysql_fetch_array($sql);
return $row['name'];
}
// the rest of your code goes here
}
If you don't want to have to constantly create new mydb instances you can do something slightly different:
Dependency Injection
class articles {
private $db = null;
// Here we'll use an existing mydb object and pass it into our new articles
public function __construct(mydb $db) {
$this->db = $db;
}
// the rest of your code goes here
}
$db = new mydb(); // create mydb
$db->connect(); // add your params
$articles = new articles($db); // create articles using mydb from above
Singleton
class mydb {
// This is static, which is special
private static $instance = null;
public static function setInstance(mydb $db) {
self::$instance = $db;
}
public static function getInstance(mydb $db) {
return self::$instance;
}
// the rest of your code goes here
}
$db = new mydb(); // Create a mydb object
$db->connect(); // add your params
mydb::setInstance($db); // store the mydb object in the mydb class
// Later when you want to query we use the stored object:
// (and this will now work everywhere in the program--
// we don't need $db anymore)
mydb::getInstance()->query();
Analysis
Generally, you don't want to open or maintain many connections to your database. It's faster to use the same connection everywhere. Sometimes this is not appropriate, though.
The singleton is a cheap form of a Service Locator.. I.e. you create a resource (or "service") and then you have a means to locate that resource without passing a variable around with you. Singletons are a basic fix, but there are better ways to architect your applications.
You might want to read about two relevant design patterns: Service Locator and Dependency Injection. Both are described here: http://martinfowler.com/articles/injection.html

Start work with PHP OOP

I now learn PHP OOP and I want to get yours tips. I create DB connection class, is this okay?
How use "Database" class in another class? Always use "extends"?
Thanks
<?php
//Config
$db_user = 'root';
$db_pass = '';
$db_host = 'localhost';
$db_name = 'test';
class Database
{
private $Database;
private static $instance;
public static function instance()
{
if ( !self::$instance )
self::$instance = new Database();
return self::$instance;
}
public function connect($host, $user, $password, $name)
{
$this->db_link = mysql_connect($host, $user, $password);
mysql_set_charset('utf8');
mysql_select_db($name, $this->db_link);
}
public function query($query)
{
$sql = mysql_query($query);
$row = mysql_fetch_array($sql);
return $row;
}
}
class Book extends Database
{
public function getData2()
{
$sql = $this->query('SELECT * FROM users WHERE price = "7"');
return $sql['name'];
}
}
$db = Database::instance();
$db->connect($db_host, $db_user, $db_pass, $db_name);
$b = new Book();
$res = $b->getData2();
print_r($res);
?>
You can extends the database class but it is not what I suggest.
You could also use the keyword global inside the function where you actually need database to let the function get the database instance from outside; but still some people get nervous about global keyword.
You could pass the instance of the database class as argument of constructor of the class where you need database, in this way you will be able to call db methods with a simple chain: $this->db->connect();
As björn states, a book is not a database, wouldn't recommend extend.
One approach would be to on object initialization of book, pass the reference to the db-layer/object..
$myDb = new dbLayer($settings);
$myBook = new book($myDb);
$a = $myBook->getAllData($someParameter);
in the constructor of book you save the reference to the dblayer...
class book {
var $dbTier;
__constructor($db) {
$this->dbTier = $db;
...
regards,
//t
You can do something like this, this should be easy to understand
class User{
private $db;
public function __construct($db){
$this->db = $db;
}
}
The $db in the constructor parameter would be your database connection and required fom another file. All any how you get to it but not in the class.
require 'file from where you have your database';
$user = new User($db);
Anytime you like to user the database to make a query, you just reference it like below
$this->db->query();
You would not use extends here ideally unless Book is a subclass of Database. You would do something like:
class Book
{
var $db;
function __construct() {
$this->db = Database::instance();
}
}
Then the book class would use the instance of the database object and you can always access it with $this->db inside Book.

Categories