php mysqli class - php

My basic problem is I am having trouble accessing a class from within another class. Here is what I have set up so far:
My DB class:
class db {
public static $mysqli;
public function __construct(){}
static function con(){
if(!self::$mysqli){
self::$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
}
return self::$mysqli;
}
}
This works all fine and dandy when I just call it from a function like such:
function defineSettings(){
if ($query = db::con()->prepare(...my query...)) {
$query->execute();
$query->bind_result($1, $2, $3);
$query->fetch();
$query->close();
}
db::con()->close();
}
However, I am having trouble accessing this db->con() method from within another class' method. I have tried extending it to a new class, but maybe I am doing it wrong. An example of how to use this from a new class would be much appreciated! Thanks!

Not 100% sure if I understood your question, but the class below should show how you can get the db object from the Db class, and then use it in another function
class Example2 {
private $db;
public function test() {
if (!$this->db) {
$this->db = db::con();
}
//Do your stuff
}
public function test2() {
$this->db->close();
}
}

Related

PDO query in extended class

Below is the db connection class, but I am going to improve it by extending the PDO class itself:
<?php
class db{
private static $instance = NULL;
public function __construct() {
}
public static function getInstance() {
if (!self::$instance)
{
self::$instance = new PDO("mysql:host=localhost;dbname=dbmvc", 'root', '');;
self::$instance-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
return self::$instance;
}
private function __clone(){
}
}
?>
extended class:
<?php
class Model extends db{
final public function fetchInfo()
{
global $pdo, $db;
$query = $db->prepare("SELECT name FROM table");
$query->execute();
$result = $query -> fetchAll();
foreach( $result as $row )
{
echo $row['name'];
}
}
}
?>
But I have errors when I call this method:
$model=new Model();
$model->fetchInfo();
error is:
Call to a member function prepare() on a non-object in C:\xampp\htdocs\mvc\model\model.class.php on line 11
I am new to PDO, and I trying to figure it out but I can't find solution anywhere, can anyone help. Tnx!
This issue has nothing to do with PDO per se, but with object-oriented programming.
You declare global $db which you should be using self::$db or else making a distinct instance variable.
You didn't initialize $db before you called a method on it. You should set it to self::getInstance().
You declare a reference to a variable global $pdo which you never define and never use. This is just sloppy coding.
A model is not a database instance. You should prefer composition over inheritance in this case.
If you would like to see a very nice example of objects such as these I recommend reviewing this Database Class from the PHP-Login script by panique on GitHub. As well as this Model class from the same set of scripts. I hope this helps :D

MySQLI in classes and in functions

My question is rather simple and after checking a few bits and bobs on here I feel its best to ask a new question.
Lets say I have 2 classes
class FirstClass {
function test() {
return "info";
}
}
class SecondClass {
function test() {
return "info";
}
}
Then I have my mysqli object
$mysqli = new mysqli(host, user, password, db);
What do i need to do to be able to use the mysqli object inside the functions inside the classes.
This is my 2 thoughts so far although I haven't placed it on a site for testing yet.
class FirstClass {
global $mysqli;
function test() {
$mysqli->query("some query");
return "info";
}
}
or
class FirstClass {
function test() {
global $mysqli;
$mysqli->query("some query");
return "info";
}
}
I am pretty sure I can setup a construct if need be but I just need to know which way is the best way/only way to share the mysqli object.
Thanks
EDIT:
So I have done a hell of a load of learning and now have a lot more experience with passing info in and out.
Here is a latest working example type that I use.
namespace Page;
use mysqli;
class edit extends details{
protected $db;
//this function is actually in the details class but there is no point in demoing 2 classes
function __construct(mysqli $con){
$this->db = $con;
}
}
To expand what Kneel told you in comments and to counter the other answer
class foo {
function __construct($mysqli){
$this->mysqli = $mysqli;
}
function test() {
return $this->mysqli->query("some query");
}
}
is what it have to be.
You should create a mysqli instance somewhere outside the class and then pass it in coustructor.
You could use __construct() to initialize your MYSQLi. You can then access it around your class with $this.
class FirstClass {
public function __construct(){
$this->mysqli = new mysqli("host", "user", "password", "db");
}
function test() {
$this->mysqli->query("some query");
return "info";
}
}
If you wanted to use it in your second class too, you could construct it in the same way or extend your first class.
class SecondClass extends FirstClass {
public function __construct(){
parent::__construct();
}
function test() {
return "info";
}
}

Working with extended classes in PHP

I have 2 classes looking like this:
class db {
protected $db;
function __construct() {
$this->connect();
}
protected function connect() {
$this->db = new MySQLi(db_host, db_user, db_pass, db_name) or die($this->db->error);
$this->db->set_charset('utf8');
}
}
and
class sample extends db {
protected $js_base_dir;
public function __construct($js_base_dir = js_dir) {
$this->js_base_dir = $js_base_dir . "/";
}
....
I want to use $this->db inside second class, but __construct in sample class overrides first classes construct function. How to get $this-> db inside second class? Am I doung something wrong? if yes what's proper way?
You can call parent class method, using parrent::methodName(). Similarly, you can use this to invoke parent's constructor method as well as
parent::__construct();
Usage:
public function __construct($js_base_dir = js_dir) {
parent::_construct();
$this->js_base_dir = $js_base_dir . "/";
}
Apart from the manual read this article for extended explanation.
Try this:
public function __construct($js_base_dir = js_dir) {
parent::__construct();
$this->js_base_dir = $js_base_dir . "/";
}

Using db connection everywhere inside PHP application

I have db class which looks like that
class db {
protected $db;
public function __construct() {
$this->connect();
}
protected function connect() {
$this->db = new MySQLi(db_host, db_user, db_pass, db_name) or die($this->db->error);
$this->db->set_charset('utf8');
}
}
Every class inside my PHP app extends this db class
Like
class registration extends db {
var $validation;
function __construct() {
parent::__construct();
$this->validation = new validation();
...
And validation looks like that
class validation extends db {
var $ajax, $common;
function __construct() {
parent::__construct();
...
Getting error message "Too many connections". I feel that, this is not right approach: I'm every time reconnecting to db. So what's right way in your opinion? Is that possible to define('db', ...) 1 time and use everywhere inside app?
registration and validation are classes the use db but are not a sub-class of it.
Your code should look like:
$db = new DB();
$db->connect();
$registration = new Registration($db);
class Registration {
private $db;
public function __construct(DB $db) {
$this->db = $db;
...
You pass a reference to an instance of $db to all classes that require it.
The reason you're opening too many connections is probably because currently each class makes it's own connection to your database, and that is not what you want to do, or need to do.
You want to use composition here instead. Also might consider investigating Singleton pattern.
To elaborate, using composition, each class in your library will have an instance of the db class rather than be an instance of the db class.
Singleton will make the db class enforce only one instance of the class is ever created which is useful for shared resources like database connections. Have a look at this link for further reading on the topic.
http://php.net/manual/en/language.oop5.patterns.php
EDIT: Adding some code
Turning the db class into a Singleton
<?php
class db
{
static private $_oInstance = null;
protected $db;
private function __construct()
{
$this->connect();
}
static public function getInstance()
{
if(self::$_oInstance === null)
self::$_oInstance = new db();
return self::$_oInstance();
}
protected function connect()
{
$this->db = new MySQLi(db_host, db_user, db_pass, db_name) or die($this->db->error);
$this->db->set_charset('utf8');
}
}
Revising the rest of your classes to compose the db instance rather than extend the db class
class registration
{
private $_oDb;
public $validation;
function __construct()
{
parent::__construct();
$this->_oDb = db::getInstance();
$this->validation = new validation();
}
// ...
}

Use of included class in another class

I'm trying to use a database class (ADOdb for PHP) but I don't know how to use it in another class.
Example:
<?php
include_once("adodb.inc.php");
$conn = NewADOConnection('mysql');
class Contacts {
public function getData(){
$conn->Connect(...);
//do something
}
}
?>
I think the problem is that I can not call $conn because its defined outside the class.
Notice: Undefined variable: conn
Fatal error: Call to a member function Connect() on a non-object
Maybe I'm doing it the wrong way, but I really don't know how to fix this.
Can somebody please help me out? Thanks a lot!
Why not simply do like this ?!
<?php
include_once("adodb.inc.php");
$conn = NewADOConnection('mysql');
$conn->Connect(...);
class Contacts {
protected $_connection;
public function __construct($conn)
{
$this->_connection = $conn;
}
public function getData(){
//do something
}
}
$contacts = new Contacts($conn);
$foobar = new FooBar($conn);
?>
It makes sense to establish connection outside the class, and then pass in already workable object. And of-course to share the same connection object among all the classes which require it.
P.S i would really reallly recommend to drop ADODB and start learning PDO.
You have a number of choices:
Use the global reserve word:
<?php
include_once("adodb.inc.php");
$conn = NewADOConnection('mysql');
class Contacts {
public function getData(){
global $conn;
$conn->Connect(...);
//do something
}
}
?>
Or pass $conn to your object on creation
$contacts = new Contacts($conn);
class Contacts {
protected $conn;
public function __construct($conn){
$this->conn = $conn;
}
public function getData(){
$this->conn->Connect(...);
//do something
}
}
?>
Or you could yous a Singleton data connection object. But that is considered a anti-pattern so I would inject your dependency as in option 2.
you need to reference the global variable:
<?php
include_once("adodb.inc.php");
$conn = NewADOConnection('mysql');
class Contacts {
public function getData(){
global $conn;
$conn->Connect(...);
//do something
}
}
?>
That said, you would probably be better off using dependency injection like this:
<?php
class Contacts {
private $db;
public function setDB($conn) {
$this->db = $conn;
}
public function getData(){
if (!$this->db) {
throw new Exception();
}
$conn = $this->db;
$conn->Connect(...);
//do something
}
}
?>
And then include your adodb include and instantiation in an initialization section.
Edit: Please see this article on Dependency Injection as getting into the habit of using this (and not globals) may save a lot of headaches down the road.
$conn is out of your variable scope. Use the following to make it work:
class Contacts {
public function getData(){
global $conn;
$conn->Connect(...);
//do something
}
}
Another way to do it is to have a reference to the variable inside your object:
class Contacts {
private $ref;
public function __construct($conn)
{
$this->ref = $conn;
}
public function getData(){
$ref->Connect(...);
//do something
}
}
$contacts = new Contacts($conn);

Categories