Since the explanations on the question you linked to are quite extensive, I will not go an redefine it for you again. Instead, I will try to show you via an example of injection.
class Logger {
private $__logger;
public function __construct($logger) {
$class = $logger . "Logger";
$this->$__logger = new $class();
}
public function write($message) {
$this->$__logger->write($message);
}
}
So, above you have a class Logger
that you may be using to log information somewhere. We don't really care how it does it, we just know it does.
Now, we have a couple of different logging possibilities...
class DBLogger {
public function write($message) {
// Connect to the database and
// INSERT $message
}
}
class FileLogger {
public function write($message) {
// open a file and
// fwrite $message
}
}
class EMailLogger {
public function write($message) {
// open an smtp connection and
// send $message
}
}
Now, when we use our logger, we do it by doing any of the following:
$logger = new Logger("DB");
$logger = new Logger("EMail");
$logger = new Logger("File");
We always interact with $logger
in the same way (ie. we call write($message)
). The wrapper instance Logger
wraps the actual logging class and calls its methods on our behalf.
A more common use of the above type of code would be when using configuration files to determine what your logger is. For example, consider the case where you want to have your logging sent to a file. You might have a config that looks like this:
$logging = array(
'type' => 'file',
'types' => array(
'file' => array(
'path' => '/var/log'
'name' => 'app_errors.log'
),
'email' => array(
'to' => 'webmaster@domain.com',
'from' => 'error_logger@domain.com',
'subject' => 'Major fail sauce'
),
'db' => array(
'table' => 'errors',
'field' => 'error_message'
)
)
);
And your adapted classes might look like:
class FileLogger {
public function __construct() {
// we assume the following line returns the config above.
$this->config = Config::get_config("logger");
}
public function write($message) {
$fh = fopen($this->config->path . '/' . $this->config->file);
fwrite($fh, $message . "\n");
fclose($fh);
}
}
We would do the same for the other adapted
classes. Then, with a little modification to the main Wrapper Logger
, we could create the correct wrapped instance by using the configuration data and base it on the type
that is defined in the config. Once you have something like that in place, switching over to logging via email is as easy as changing the type
in the config.