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.
- using `PDO`
- using `mysqli`
The problem is `PDO` and `mysqli` provide different interface to querying, creating transactions, so if use 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 ut `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][1] (this is directly tied to [Dependency injection][2] and benefits greatly from the [Strategy pattern][3]).
[1]: https://en.wikipedia.org/wiki/Inversion_of_control
[2]: https://en.wikipedia.org/wiki/Dependency_injection
[3]: https://en.wikipedia.org/wiki/Strategy_pattern