The whole point of wrapping a core PHP database driver is to provide your custom interface for handling database requests. Making the mysqli
property public completely defies the purpose and you wouldn't really need your custom class in the first place.
The best approach would be to create a DatabaseInterface
, have class or classes implement it, classes, which, preferably in their constructor, take a core PHP database driver (be it mysqli or PDO) and use the DatabaseInterface
as parameters for classes which require database interaction.
This way you provide your own abstraction, over which you have full control, and are also not limited to single implementation.
More details and implementation example
In PHP you have generally two recommended options for database connection.
The problem is PDO
and mysqli
provide different interface to querying, creating transactions, so if you used for example mysqli
in your application directly and then wanted to switch to PDO
, you would have to refactor every single database call in your app.
Use interfaces for abstraction
You create an interface, which will represent your very own interface for database calls. Here is a very simple example how some of its methods may look.
interface MyDatabase
{
public function beginTransaction();
public function commitTransaction();
public function doQuery($sql);
}
Right now you want to use mysqli
, so you create a new class, MyMySQLiDriver
, which will implement the MyDatabase
interface and either take a mysqli
object in its constructor as a parameter, or you can use the procedural-programming mysqli_*
functions.
class MyMySQLiDriver implements MyDatabase
{
protected $mysqli;
public function __construct($mysqli)
{
$this->mysqli = $mysqli;
}
public function beginTransaction() { /* use $this->mysqli here */ }
public function commitTransaction() { /* use $this->mysqli here */ }
public function doQuery($sql) { /* use $this->mysqli here */ }
}
Anywhere else in your code, if you want to use a database, you are going to pass an object of MyDatabase
(the interface) type as a parameter and use its methods.
function IAmUsingTheDatabase(MyDatabase $db)
{
$db->beginTransaction();
$db->doQuery("SELECT * ...");
$db->commitTransaction();
}
Note that the IAmUsingTheDatabase
has no idea whether you are using PDO
, mysqli
or anything else. It wants to use the database and it uses the interface you provided.
As I have said in the comments under this post, if, in the future, you don't want to use the MyMySQLiDriver
anymore, you create a new class, be it MyPDODriver
or anything else, which will again implement MyDatabase
interface.
Where to go from here
You can study more on this topic under Inversion of Control (this is directly tied to Dependency injection and benefits greatly from the Strategy pattern).