Re: When to instantiate a new class

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 6/17/15 3:56 PM, Ramiro Barrantes wrote:
Hello,

This is a very basic question, i just don't know php well enough to know what's best.  I have a screen class and a database class.  The screen class handles everything related to what goes on the screen, but its many functions often need to use the database class to get relevant information.  The question I have is:

How often should I instantiate the database class? Should I do it once with say, the constructor of the screen class? Or with the specific method, or pass it as a variable?

For example:

INSTANTIATING WITHIN EACH FUNCTION
function method($variable) {
    $db = new databaseInterface():
    ...
}

or

PASSING IT AS A VARIABLE FOR EACH FUNCTION
function method($variable,$db) {
    ...
}

or

CREATING IT AS PART OF THE SCREEN CONSTRUCTOR AND ACCESSING IT WITH A "getter"
class screen {
   private $db;
   function construct() {
      $db=new databaseInterface();
   }

   function getDatabaseInstance() {
     return($db);
  }
}

Thanks in advance,
Ramiro

1) The classes you're talking about (the DB connection and the output channel) are called "Services". That is, they're classes that do not contain data per se, only logic. Services should, generally, only have a single instance in your entire application. You may have different instances of the same class with different constructor parameters if they are for different purposes; eg, two different DB connections for two different databases. But those are separate services at that point.

2) Enforcing that there's only a single instance of each service is *not the service's job*. That is, *do not make them singletons*. Ever. Singleton is an anti-pattern that makes testing harder and your code less flexible.

3) The way to wire the objects together is called Dependency Injection, which is really just the fancy-pants way of saying "pass in what you need". In your example:

class Connection {
// ...
}

class Screen {
protected $conn;

public function __construct(Connection $conn) {
$this->conn = $conn;
}

public function doStuff() {
$result = $this->conn->query(...);
// ...
}
}

$conn = new Connection(...);

$screen = new Screen($conn);


4) Your output channel should, in fact, NOT be talking directly to the database in most cases. There should be an intermediary that coordinates that. If it's per-URL, then it's generally called a Controller and should be very very simple. For example:

class Controller {

protected $conn;
protected $screen;

public function __construct(Connection $conn, Screen $screen) {
$this->conn = $conn;
$this->screen = $screen;
}

// Something routes the request to this method; exactly how is
// out of scope at the moment.
public function showUser($userId) {
$result = This->conn->query("SELECT name FROM users WHERE id=:id", [':id' => $user_id];
$name = $result->fetchOne();

$screen->showName($name);
}

Note that taking a dependency injection approach (which you should) does lead quickly to a lot of "wiring" code on your part to inject everything. The answer to that is the scarily-named "dependency injection container". There are many that already exist for PHP. The simplest/easiest to get started with is Pimple:

http://pimple.sensiolabs.org/



--Larry Garfield

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php




[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux