How to Access MySQLi Connection in Another Class on Another Page

How to access mysqli connection in another class on another page?

Your DBConnection class would need an additional method:

public function getLink()
{
return $this->mysqli;
}

It seems that your original User class was a subclass of DBConnection, because mysqli property on DBConnection is protected and User class has a parent::__construct() call.

It's better to use dependency injection, so your User class will receive its database connection via the constructor:

public function __construct(DBConnection $db)
{
$this->mysqli = $db->getLink();
}

Then from your code you can run:

$db = new DBConnection;
$uObj = new User($db);

Using MySQLi in other classes

I think you have at least 3 ways to do this... (Maybe there are more ways)

databasde.php (with class) needs to be included first for following steps

1: The first one is to extend the dbclass to your class like

class myclass extends database {

public function myclass(){

parent::__construct();
//....
}
}

than you have all functions and vars in your myclass

2: The second way is

require_once(database.php);

class myclass {

private $db;

public function myclass(){ /* the constructor */

$this->db = new database();
}

public function grabResult($table, $where, $field)
{
$result = "SELECT * FROM {$table} WHERE {$where}={$field}";

return $db->mysqli->query($result);
}
}

3: The third way is

class myclass{

private $db;

public function myclass(){
$this->db = false;
}

public function setupDBHandler($dbHwNd){
$this->db = $dbHwNd;
}

public function grabResult($table, $where, $field)
{
if($this->db){
$result = "SELECT * FROM {$table} WHERE {$where}={$field}";
return $db->mysqli->query($result);
}
else{
return "Setup DBHandler first.";
}
}
}

How to use $db from another .php to another .php's class using OOP?

You'd be best to create a DB class or harnessing an already created one to achieve what you're trying to do.

The usual flow for things like this is call Lazy Loading/Dependency Injection. Where you're passing the required objects into the class.

If you choose this path, I suggest that you read up on Dependency Injection, as many things do, it has pros AND cons but is essential in OOP.

As Ben Stated in the comments:

Dependency injection is a key principle in OOP. I'd like to add that
if you are serious about OOP you should also look into autoloaders in
general, PSR-4 and Composer.

A side not on the above mentioned, you'd be best to look at PHPTheRightWay, they list a lot of stuff, including Dependency Injection.

You'll end up creating something like. It'd be better if you followed this example to understand how it works:

Class DB {

function __construct($host, $user, $pass, $db) {
return $this->connect($host, $user, $pass, $db);
}

function connect($host, $user, $pass, $db) {
//..connect and all.
}

//...the rest of your functions/class...
}

You can construct this anyway you please. Or just make the mysqli object accessible, allowing you to call it.

Now we get to the fun stuff. Actually injecting it into your class;

Class Foo {

$private $db;

// your construct method here will ONLY except a `DB` class instance/object as $db.
// Try it with anything else and learn from the errors to understand what I mean.
function __construct(DB $db){
$this->db = $db;
}

}

$db = new DB($host, $user, $pass, $db);
// you can error check it here

$foo = new Foo($db);// inject the $db object.

If you just want to share the resource, you could harness global, but it is strongly discouraged.

include('connection.db.php');

class MySQLqueries {
public function samplefunction($queryString) {
global $db;
$sqlQry = mysqli->query($queryString);

return ($sqlQry) ? "<pre>Query Executed Successfully</pre>" : die("<pre>An error occured -> $db->error</pre>");
}
}

If you chose this path, you'd be best to assign the global instance of $db to an internal class variable, like $this->db.

Cant pass mysqli connection to class

Your main problem is assumptions.

You are assuming that there is no connection passed, judging by indirect consequence.

But a programmer should be always logically correct in their reasoning.

Talking of connection? Verify the very connection. var_dump($con) in the constructor. var_dump($this->con) in the method. If it fails - only now you can blame connection and start for the solution.

If not - there is no reason in looking for another connection passing method. Yet it's time to find the real problem.

If your query fails, you have to ask mysql, what's going on, using $this->con->error, as this function will provide you with a lot more useful information than simple "it fails". The right usage I've explained here: https://stackoverflow.com/a/15447204/285587

build a mysqli db connection class and other classes use it

Your question is not very specific, and I have the feeling you're not really aware what your concrete problems are. You've already accept an answer that gives you some code but puts you in the wrong direction as it does not solve your underlying problem and wastes code.

The first thing you should know if you want to make use and benefit of the object oriented interface of PHP's mysqli extension is, that the Mysqli class represents the database connection (the "link" as it was named for a procedural approach) already:

require('inc/dbc.php');

$dbConnection = new Mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);

That's already it. Sure you might want to use some error handling here:

if ($dbConnection->connect_error)
{
throw new Exception(
sprintf('(#%d) %s', $dbConnection->connect_errorno,
$dbConnection->connect_error)
);
}

Throwing exception instead of let's say die('message') is done, because you can easily create an exception handler so that you can display a more useful response to the user from within a central place instead of handling each exceptional error-case where it appears (actually at the place where die would be).

You can also log and mail the backtrace so you can fix things more easily. Naturally you do not need to use exceptions, however the rule of thumb is to use die only in scripts you throw away in let's say a week and it does not work well with object oriented design.

As you will need this code anyway in all places where you will need your database connection, you can create your own connection object to bring those parts together as they belong together:

class DatabaseException extends Exception
{
}

class DatabaseConnection extends Mysqli
{
public function __construct($host, $user, $password, $database = "", $port = NULL, $socket = NULL) {

parent::__construct($host, $user, $password, $database, $port, $socket);

$this->throwConnectionExceptionOnConnectionError();
}

private function throwConnectionExceptionOnConnectionError() {

if (!$this->connect_error) return;

$message = sprintf('(%s) %s', $this->connect_errno, $this->connect_error);

throw new DatabaseException($message);
}
}

The usage is actually pretty straight forward and very much the same, only the name of the class varies and it's definition needs to be loaded:

require('inc/dbc.php');
require('inc/database.php');

$dbConnection = new DatabaseConnection(DB_HOST, DB_USER, DB_PASS, DB_NAME);

As written, the connection object already represents your database connection. So every part in your application that needs it, has to ask for it. Let's review your example function:

function getOption($id, $db_link)
{
// $db_link = $this->db_link;
$res = mysqli_query($this->db_link,"SELECT * from config where id='1'");
$row = mysqli_fetch_array($res);
return $row['option'];
}

I renamed the function and I commented the first line, even this might be what you want. Actually, if that function would be part of the DatabaseConnection object, it could work like this:

class DatabaseConnection extends Mysqli
{
...

public function getOption($id) {
$statement = $this->prepare('SELECT `option` FROM config WHERE id=?');
$statement->bind_param('i', $id);
$statement->execute();
$statement->bind_result($option);
$statement->fetch();
$statement->close();
return $option;
}

As this example demonstrates, the database connection is already there. However, this is not advisable. Imagine you not only have options but this and that and such and what not more. You would create one function after the other all in one class. Well for a little application that might even so work right, but imagine more and more. You would get one very large class that is responsible for many things. So it would be bad to do this, even if you can use $this already to prepare the statement.

Also take note that you should prepare statements. This has been answered here numerous times, if you're not used to it, read about it, it's worth the lines. There are better ways to not repeat code (DRY: Don't repeat yourself) while stepping into object oriented (you should even already do this with procedural).

So as to have this all in one class would be a problem, you instead put it in a class of it's own:

class DatabaseModelBase
{
protected $connection;

public function __construct(Connection $connection) {
$this->connection = $connection;
}

protected function prepare($query) {
$connection = $this->connection;
$statement = $connection->prepare($query);
if (!$statement) {
throw new DatabaseException(
sprintf('(%s) %s', $connection->error, $connection->errno)
);
}
return $statement;
}
}

class Option extends DatabaseModelBase
{
public function find($id) {
$statement = $this->prepare('SELECT `option` FROM config WHERE id=?');
$statement->bind_param('i', $id);
$statement->execute();
$statement->bind_result($option);
$statement->fetch();
$statement->close();

return $option;
}
}

This has some extended error handling again, because most often mistakes are made in the SQL query. And as you can see the individual function to fetch some specific data is placed in it's own class. You can use such classes to group the fetching and updating for specific datatypes.

Usage in full:

$dbConnection = new Connection(DB_HOST, DB_USER, DB_PASS, DB_NAME);

$option = new Option($dbConnection);

$optionValue = $option->find(1);

echo $optionValue; # value for option with ID1

The names of the Option object probably is not well, I tried to keep the example lightweight but also offer some separation. For other scenarious you might want to prefer some different kind how to access the db connection, because it is injected into Option via it's constructor, Option does not deal any longer with the details how the database connection is being created.

For example you can make the database connection object more smart only to connect to the database the first time prepare or query is actually used with it. So that requests to your website that do not need a database connection would not needlessly connect to the database.

You find more examples in other questions and you might want to learn about dependency injection. Also you always want to keep things apart from each other, so you have some objects that are only lightly connected to each other.

  • How to successfully rewrite old mysql-php code with deprecated mysql_* functions?
  • Dependency Injection simple implementation


Related Topics



Leave a reply



Submit