可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am new to OOP PHP, and I've been working with procedural API since I've started Web Development so I'm having a hard time migrating to OOP.
so let's say I have this four .php
file and structures below.
connection.db.php
<?php
define("DB_HOST", "127.0.0.1");
define("DB_USER", "root");
define("DB_PASS", "");
define("DB_NAME", "sample_db");
$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
echo (!$db->connect_error) ? NULL : die("<pre>Unable to connect to the MySQL Server -> $db->connect_error</pre>");
?>
sampleclass.class.php
<?php
public $db;
class MySQLqueries {
public function samplefunction($queryString) {
$sqlQry = mysqli->query($queryString);
return ($sqlQry) ? "<pre>Query Executed Successfully</pre>" : die("<pre>An error occured -> $db->error</pre>");
}
}
?>
includes.inc.php
<?php
error_reporting(0);
date_default_timezone_set("Asia/Manila");
require 'connection.db.php';
require 'sampleclass.class.php';
?>
index.php
<?php
require 'includes.inc.php';
$todo = new MySQLqueries;
echo $todo->samplefunction("SELECT `sample_column` FROM `sample_table` WHERE `sample_column` = 'sample_value';");
?>
As you may or may have not noticed, my problem is how to use the $db
from connection.db.php
in the samplefunction
of sampleclass.class.php
You may ask me, why not create a __construct()
method in sampleclass.class.php and just move the "$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);" there ?. well if I'm to do this, all other classes will have to have it's own constructor
and $db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
declared there right?
With $db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
on the connection.db.php
I assume that I can reuse it versatile-ly.
You see I've declared a public $db;
in sampleclass.class.php
but I don't know what's next. If someone can help me dearly, then I would be a lot grateful.
PS: I've already consulted Dr. Google Ph.D. regarding this matter, and I only got tons of articles or video tutorials showing how to use and do OOP PHP-MySQLi Programming but without using classes and methods.
回答1:
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
.
回答2:
As you're alread using objects, you probably should also go to a OOP (Object Oriented Programing) implementation.
So, you may put your $db
variable as a static variable in the sampleclass.class.php file, as in:
class MysqlConn
{
public static $db;
}
Like that you instantiate the mysqli object using this code:
MysqlConn::$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
Even better, you could create a method to instantiate the $db connection, initialize the variables in that class:
<?php
class MysqlConn
{
protected
static $DB_HOST = "127.0.0.1",
static $DB_USER = "root",
static $DB_PASS = "",
static $DB_NAME = "sample_db";
protected static $db;
public static function getDB()
{
if (!isset(self::$db) {
self::$db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if ($db->connect_error) {
die("<pre>Unable to connect to the MySQL Server -> $db->connect_error</pre>");
}
}
return self::$db;
}
}
MysqlConn::getDB();
In index.php, you may get the db instance with the following code, not reconnecting every time:
$db = MysqlConn::getDB();
回答3:
my problem is how to use the $db from connection.db.php in the
samplefunction of sampleclass.class.php
You can use global in your case just incluce or require connection.db.php
then use global
in php.
Something like this might help you
require_once 'connection.db.php';
class MySQLqueries {
public function samplefunction($queryString) {
global $db;
//You can now use $db variable as you want
print_r($db);
$sqlQry = mysqli->query($queryString);
return ($sqlQry) ? "<pre>Query Executed Successfully</pre>" : die("<pre>An error occured -> $db->error</pre>");
}
}