__constructor mysqli variable options I like the fact that I can create a class and have the connection details in one file if I need to update them and then pass them to the method I create in the class that defines my specific use of mysqli. I was thinking also that I may give an option to pass the connection details if I need to use a different db in one page. Is this a good idea. Any adverse problems?

Basic Example (Note the values defined in __constructor)

public function __construct($host = 'localhost', $user = 'myuser', $pass = 'mypass', $db = 'mydb') {
    // Connect to Database
    $this-&gt;mydb = new mysqli($host, $user, $pass, $db);
}
Note: this post gets extremely side tracked, but the two ideas are pretty closely related, so hopefully my rambling ends up being helpful.

new in a constructor is an anti-pattern. It immediately creates very high coupling, and it murders any form of coding to interface.

Rather than passing what you need to construct the object, you should pass the actual object. This idea (or at least, an idea very closely related to it) is called dependency injection.

This is all a bit abstract, so I'll give an example. Imagine that you have a simple database-backed logger. I'm more familiar with PDO than MySQLi, so I'll use it.

class DbLogger
{
    private $_db;

    const WARNING = 1;
    const ERROR = 2;

    public function __construct()
    {
        $this-&gt;_db = new PDO("sqlite:log.sqlite", null, null, array(
            PDO::ATTR_ERRMODE =&gt; PDO::ERRMODE_EXCEPTION
        ));
    }

    public function log($message, $severity)
    {
        $stmt = $this-&gt;_db-&gt;prepare("INSERT INTO log (message, serverity) VALUES (?, ?)");
        $stmt-&gt;execute(array($message, $severity));
    }

}


Seems simple enough, right? And quite easy to use. No matter where you are in code, you can just do $log = new DbLogger(); $log-&gt;log('...'); and you're done.

There's a major problem though. What if you want to use a different database? What if you want a users_log.sqlite and a financials_log.sqlite? Well, simple... You could just pass the name of the log to the constructor.

And yes, that would work, but how manageable is it? Do you really want to find all the places that the name is used every time you want to change it?

Consider if instead of creating the PDO instance, the constructor accepted it. This allows an important difference to happen: DbLogger no longer has to care about how to create a PDO object; it only has to care about using it. Now if you want to use two different databases, you just construct two different loggers based on two different PDO objects. "But," you might say, "don't I then have to pass around the details of my log database?"

Nope. Instead of passing around the details, you just pass around the object.

Any object that needs a logger, you just construct it with a logger. Or, if only a certain method needs logging, you only have to pass that method the logger. It's a bit hard to get used to this pattern, but once you've done it a bit, the way the object graph fits together becomes a lot more clear.

Basically, the idea is to never create your own dependencies. That creates extreme coupling and makes providing alternate implementations impossible. To steal an example from a Google code talk, imagine that you have a bit of code that's responsible for charging a credit card. Now, imagine that you want to test that code. So, you go, you add three items, and you go to run the transaction. Oops, you just actually charged yourself. So... how do you fake it? Do you comment out the actual request and just echo out the variables? Sure, that works once, but how do you make sure you don't accidentally break the code later? You need the test to be rerunnable. You need it to be able to go through the normal process, but instead of actually running the credit card, you need it to just pretend. This is a perfect example of why dependency injection is necessary. If you instead pass in a credit card charging object, a real implementation can be used during production, but for tests, you can just use a mock that just verifies what's passed to it.

Anyway, I'm rambling a bit, so here's a real example:

interface Logger
{
    const INFO = 1;
    const WARNING = 2;
    const ERROR = 3;
    public function log($message, $severity);
}

class NullLogger implements Logger
{
    public function log($message, $severity)
    { }
}

class DbLogger implements Logger
{
    private $_db;
    public function __construct(PDO $db)
    {
        $this-&gt;_db = $db;
    }

    public function log($message, $severity)
    {
        $this-&gt;_db-&gt;prepare("...");
        $this-&gt;_db-&gt;execute(...);
    }

}

class FileLogger implements Logger
{
    private $_fh;

    public function __construct($file)
    {
        if (!is_resource($file) &amp;&amp; is_string($file)) {
            $file = fopen($file, 'a');
        }
        if (!is_resource($file)) {
            throw new InvalidArgumentException("A valid file handle or path must be provided: " . $file);
        }
        $this-&gt;_fh = $file;
    }

    public function log($message, $severity = self::WARNING)
    {
        fputs($this-&gt;_fh, "...");
    }

}


Now, imagine you have some class that needs a logger. It no longer is tied specifically to a specified DbLogger. In fact, it's no longer tied to a DbLogger at all. All the object has to care about is that it has an object on which it can call log. It's not tied to a specific logger. If we need to change the logger, we just pass it a different logger on construction. No magic to it. No need to edit a bunch of files. Just one config.php (or config.ini/config.json/etc) has to be changed. All we need is a very top layer that knows how to kick off the chain of object creation ("a User needs a DBAL which needs a DatabaseConnection which needs a PDO" for example) and this can all be done with fairly little effort (and lots of different approaches/tools exist to do that).



Hopefully this answer has been at least semi-useful. It's super rambling, and it's not exactly what you were asking about, but I'm guessing that dependency injection and coding to interface are not two things that you're familiar with. It's a bit odd in a situation with database connections since they're so low level (relatively). There's not exactly a RDBMS interface that MySQLi and other connection classes extend. This makes the interface thing a pretty unrelated topic. When the question is extended to a higher level concept though, hopefully it makes sense.

Anyway, please let me know if you have any questions as I fear that this explanation is pretty bad.