For loading classes I use PSR-4 autoload. In my index.php I use FastRoute component. In that index.php I create $db connection and pass it to the controllers.
call_user_func_array([new $class($db), $method], $vars);
In the controllers I receive it and pass it to the models and use it there.
I know that is bad approach. DB connection that was created in index.php how can I use it in my models not pass it through controllers etc and without singleton instance of a connection? How can I use DI or DIC to set up db connection in index.php and get in all models?
index.php:
<?php
require_once 'vendor/autoload.php';
$db = new DbConnection(new DbConfig($config));
$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r) {
$r->addRoute('GET', '/users', 'UserController/actionGetAllUsers');
$r->addRoute('GET', '/users/{id:\d+}', 'UserController/actionGetUserById');
});
// Fetch method and URI from somewhere
$httpMethod = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];
// Strip query string (?foo=bar) and decode URI
if (false !== $pos = strpos($uri, '?')) {
$uri = substr($uri, 0, $pos);
}
$uri = rawurldecode($uri);
switch ($routeInfo[0]) {
case FastRoute\Dispatcher::NOT_FOUND:
// ... 404 Not Found
break;
case FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
$allowedMethods = $routeInfo[1];
// ... 405 Method Not Allowed
break;
case FastRoute\Dispatcher::FOUND:
$handler = $routeInfo[1];
$vars = $routeInfo[2];
list($class, $method) = explode("/", $handler, 2);
$module = strtolower(str_replace('Controller', '', $class));
$class = 'Vendorname\\' . $module . '\\controllers\\' . $class;
$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
call_user_func_array([new $class($db), $method], $vars);
break;
}
controller:
class UserController extends BaseApiController
{
protected $db;
public function __construct($db)
{
$this->db = $db;
parent::__construct();
}
public function actionGetAllUsers()
{
$model = new User($this->db);
echo json_encode($model->getAllUsers());
}
model:
class User
{
protected $db;
public function __construct($db)
{
$this->db = $db;
}
public function getAllUsers()
{
$stmt = $this->db->prepare('SELECT * FROM user');
$stmt->execute();
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
}
First of all, you have to understand, that "Dependency Injection" and "Dependency Injection Container" are two different things:
DI is a technique, that you use to separate two classes in OOP.
DIC is a piece of software, that assembles object graphs
It seems, that you are already, that you way of passing of DB connection is bad. The exact technical reason can be described as violation of LoD. Basically, your $db variable is crossing two layer boundaries.
But, the solution for this is not: "just add DI container". That won't solve the problem. Instead, you should improve the design of the model layer. You might do a quick read here, but I will give a bit shorter version here:
separate your persistence logic from your domain logic
controller should depend on service, which would be how controllers (that exist in UI layer) interact with the business logic.
the simplest way yo separate business logic is in three parts: datamappers (handle persistence logic), domain objects (for business rules) and services (interaction between domain objects and persistence objects)
The DB should be a dependency for a datamapper, that is specifically made for handling user instances (more here). That mapper should be either a direct dependency of your "account management service" (think of a good name) or be constructed using a factory inside that service (and this factory then would be the dependency of the service.
P.S. As for "which DIC to choose", I personally go with Symfony's standalone container, but that's purely personal preference.
Related
This is my class that I'm using to connect to my MySQL database.
As you can see I'm using the Singleton Pattern but almost every post says it is a very bad pattern. What is the best approach to create a database connection class? Is there a better pattern?
class DB extends PDO {
function __construct() {
try {
parent::__construct('mysql:host=' . 'localhost' . ';dbname=' . 'kida', 'root', 'root', array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'");
parent::setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo $e->getMessage();
}
}
public static function get_instance() {
static $instance = false;
if(!$instance) $instance = new self;
return $instance; //returns pdo object.
}
}
Using the singleton-pattern (or antipattern) is considered bad practice because it makes testing your code very hard and the depencies very convoluted until the project becomes hard to manage at some point. You can only have one fixed instance of your object per php-process. When writing automated unit-tests for your code you need to be able to replace the object the code you want to test uses with a test-double that behaves in a prdictable manner. When the code you want to test uses a singleton, then you cannot replace that with a test double.
The best way (to my knowlege) to organize the interaction between objects (like your Database-Object and other objects using the database) would be to reverse the direction of the depencies. That means that your code is not requesting the object it needs from an external source (in most cases a global one like the static 'get_instance' method from your code) but instead gets its depency-object (the one it needs) served from outside before it needs it. Normally you would use a Depency-Injection Manager/Container like this one from the symfony project to compose your objects.
Objects that use the database-object would get it injected upon construction. It can be injected either by a setter method or in the constructor. In most cases (not all) is it better to inject the depency (your db-object) in the constructor because that way the object that uses the db-object will never be in an invalid state.
Example:
interface DatabaseInterface
{
function query($statement, array $parameters = array());
}
interface UserLoaderInterface
{
public function loadUser($userId);
}
class DB extends PDO implements DatabaseInterface
{
function __construct(
$dsn = 'mysql:host=localhost;dbname=kida',
$username = 'root',
$password = 'root',
) {
try {
parent::__construct($dsn, $username, $password, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'");
parent::setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo $e->getMessage();
}
}
function query($statement, array $parameters = array())
{
# ...
}
}
class SomeFileBasedDB implements DatabaseInterface
{
function __construct($filepath)
{
# ...
}
function query($statement, array $parameters = array())
{
# ...
}
}
class UserLoader implements UserLoaderInterface
{
protected $db;
public function __construct(DatabaseInterface $db)
{
$this->db = $db;
}
public function loadUser($userId)
{
$row = $this->db->query("SELECT name, email FROM users WHERE id=?", [$userId]);
$user = new User();
$user->setName($row[0]);
$user->setEmail($row[1]);
return $user;
}
}
# the following would be replaced by whatever DI software you use,
# but a simple array can show the concept.
# load this from a config file
$parameters = array();
$parameters['dsn'] = "mysql:host=my_db_server.com;dbname=kida_production";
$parameters['db_user'] = "mydbuser";
$parameters['db_pass'] = "mydbpassword";
$parameters['file_db_path'] = "/some/path/to/file.db";
# this will be set up in a seperate file to define how the objects are composed
# (in symfony, these are called 'services' and this would be defined in a 'services.xml' file)
$container = array();
$container['db'] = new DB($parameters['dsn'], $parameters['db_user'], $parameters['db_pass']);
$container['fileDb'] = new SomeFileBasedDB($parameters['file_db_path']);
# the same class (UserLoader) can now load it's users from different sources without having to know about it.
$container['userLoader'] = new UserLoader($container['db']);
# or: $container['userLoader'] = new UserLoader($container['fileDb']);
# you can easily change the behaviour of your objects by wrapping them into proxy objects.
# (In symfony this is called 'decorator-pattern')
$container['userLoader'] = new SomeUserLoaderProxy($container['userLoader'], $container['db']);
# here you can choose which user-loader is used by the user-controller
$container['userController'] = new UserController($container['fileUserLoader'], $container['viewRenderer']);
Notice how the different classes no not know about each other. There are no direct depencies between them. This is done by not require the actual class in the constructor, but instead require the interface that provides the methods it needs.
That way you can always write replacements for your classes and just replace them in the depency-injection container. You do not have to check the whole codebase because the replacement just has to implement the same interface that is used by all other classes. You know that everything will continue to work because every component using the old class only knows about the interface and calls only methods known by the interface.
P.S.: Please excuse my constant references to the symfony project, it is just what i am most used to. Other project's like Drupal, Propel or Zend probably also have concepts like this.
I started to read symfony book and try to implement on my own a really basic mvc framework for learning purpose. I use some components of symfony.
By now i have an index.php file like this
<?php
require_once 'vendor/autoload.php';
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
$request = Request::createFromGlobals();
$uri = $request->getPathInfo();
$frontController = new FrontController($uri);
Then i have a frontController.php file that have a basic routing
<?php
class FrontController
{
private $uri;
public function __construct($uri)
{
$this->uri = $uri;
$this->setRoute();
}
private function setRoute()
{
$request = explode("/", trim($_SERVER['REQUEST_URI']));
$controller = !empty($request[1])
? ucfirst($request[1]) . "Controller"
: "IndexController";
$action = !empty($request[2])
? $request[2] . "Action"
: "indexAction";
$parameters = !empty($request[3])
? intval($request[3])
: null;
$response = call_user_func(array($controller, $action), $parameters);
$this->sendResponse($response);
}
private function sendResponse($response)
{
$response->send();
}
}
Then i have a series of controller (i.e. ordersController.php)
<?php
use Symfony\Component\HttpFoundation\Response;
class OrdersController
{
public function ordersAction()
{
//take data from model
$order = new OrdersModel;
$orders = $order->get_all_orders();
$html = self::render_template('templates/list.php', array('orders' => $orders));
return new Response($html);
}
public function render_template($path, array $args = null)
{
if(!empty($args))
extract($args);
ob_start();
require $path;
$html = ob_get_clean();
return $html;
}
}
Now, although i know that what i have done can be improved , i would like to inject the right model when i instantiate a controller class in the FrontController class without instantiate the model instance in the method where i use that.
How can i achieve this?
And if you have some suggests to give me, please do that because i want to improve my skills.
What are you looking for is a Dependency Injection Container (DIC). It's not only about injecting "models" (actually I hate this word because of ORMs confusion), but rather about injecting any kind of services. DIC incapsulates a service instantiation logic. Then, you can use the DIC inside your FrontController to get required services and pass it to the controller. Also, the DIC introduces some kind of indirection. You don't have to know about actual service implementations, but only about its names.
The simplest DIC implementation for PHP is Pimple. It's very small project, I strictly recommend to look at its source code. Mentioned in the comments Silex uses Pimple under the hood.
To conclude, you have to do only two things:
Register a service in the DIC.
Inject this service (or a few services) to the controller.
Basic example of registering a service is:
$container['orders'] = function($c) {
return new OrdersModel();
};
Usually, FrontController has an access to such $container object as a member or FrontController can be a container by itself. Pretty often such object is called Application. Registering of all existing services have to be done before a dispatching code. Since registering a service doesn't require service instantiation (registering a service is just creation of a closure) you can freely register hundreds of such services without an extra load.
Now, you need to somehow specify controller's dependencies. One way to do it - using static field in the controller class.
class OrdersController {
public static $dependencies = ['orders', 'otherService'];
private $ordersModel;
private $otherService;
public function __construct($ordersModel, $otherService) {
$this->ordersModel = $ordersModel;
$this->otherService = $otherService;
}
}
And then you have to read list of dependencies of each controller before instantiation in the FrontController:
...
$ctrlClass = !empty($request[1])
? ucfirst($request[1]) . "Controller"
: "IndexController";
$services = [];
foreach ($ctrlClass::dependencies as $serviceName) {
$services[] = $this->container[$serviceName];
}
// Here could be better way - PHP is not my native lang.
$reflection = new ReflectionClass($classname);
$controller = $reflection->newInstanceArgs($services);
...
That is, by the end you'll get a controller instance with all required dependencies inside. Such code very easy to test.
UPD: Also, a service A can require a service B as internal dependency. Such dependency easy to satisfy in the Pimple approach:
$container['serviceA'] = function($c) {
return new ServiceA($c['serviceB']);
};
$container['serviceB'] = function($c) {
return new ServiceB();
};
In such case if your controller requires ServiceA it indirectly depends on ServiceB too. However, you don't have to resolve such indirect dependency manually.
UPD2: Further reading:
Dependency Injection with Pimple
Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler
I have read a lot in the past few days about domain objects, data mappers, and a bunch of other stuff I had no idea about.
I have decided to try and implement this in a bit of code I am writing (partly for learning purposes, and partly because I want to create a REALLY simplified framework to build a few projects quickly...with code that I can easily understand and modify).
After reading this and this, I was planning on creating a SINGLE data mapper, with a connection to the DB inside of it, and then use a factory to pass the data mapper into every domain object (well, the ones that would need it). I include some sample code below
class data_mapper {
private $dbh;
function __construct()
{
$this->dbh = new PDO(DB_STRING, DB_USER, DB_PASS);
}
public function createUser($data) ...
public function updateUser($user_id, $data) ...
public function createCategory($data) ...
}
class user {
private $data_mapper;
public $user_id;
public $data;
function __construct($dm)
{
$this->data_mapper = $dm;
}
function someFunction() {
/* some code */
$this->data_mapper->updateUser($user_id, $data);
/* some more code */
}
}
class factory {
private $data_mapper = null;
function __construct($dm)
{
$this->data_mapper = $dm;
}
public function create($name)
{
return new $name($this->data_mapper);
}
}
/* USAGE */
$dm = new data_mapper();
$factory = new factory($dm);
$user = $factory->create('user');
I am left with two questions:
A lot of recent examples I've looked at create a different data_mapper for each model. Should I be doing this? And if I do, wouldn't that make the factory much more complex (i.e. I would need to create single PDO object and pass that into each data mapper, and then pass the right data mapper into each model)?
If my above code exposes some flaw in the understanding of models, data mappers or anything else, please enlighten me (not really a question, i know)...
As far as I can tell, "data mapper" pattern implemented in modern frameworks in the form of prototype Model class, from which all application models are inherited.
In this prototype model you can implement CRUD methods and thus your models will possess it.
Speaking of passing pdo around, local scholars will tell you that you should pass PDO object as constructor parameter. But if you'll take a look at any modern framework - they are using some sort of singleton that contains a PDO instance
So, you want a REALLY simplified PHP framework. Data mappers sound like over-engineering.
Over the years i made a few KISS frameworks in PHP, this is what i did:
Use templates (aka view) such as Smarty. Great for outsourcing your webdesign.
Make a folder named pages (aka controller). Pages are called by index.php only.
Make a folder named models. Only models talk with your DB.
Make a index.php (aka router). Has a ?page=dog parameter.
Strict MCV (aka MVC) terminology is not the holy grail, the above is a nice implementation for a simple website/app/CMS.
The parts
/pages/page_dog.inc.php
A page loads the model(s) he needs, manipulates and shows it:
<?php if(!defined('YOURFRAMEWORK')){die('External access denied');}
// Page init
require './models/model_dog.inc.php';
$id = $_GET['id']; // todo fix injection attacks
$ModelDog = new ModelDog($DB);
// Page main
$ModelDog->Load($id);
echo $ModelDog->item['breed'];
For listings (a page where user selected the $id) you may not want seperate models representing each result. Make a lister class instead, much like the model but returning multiple items in one array. Its tempting to DRY and make the ListerDog class use the ModelDog but there is no readability gain just performance pain.
/index.php (aka router) calls a page (via require_once()) after auth and init ($DB):
<?php
define('YOURFRAMEWORK', 1); // disable "External access denied" error.
require_once('config.inc.php'); // todo have this hold the $config[] array.
$DB = #new mysqli( // or your derative, so you can log each query() call.
$config['db']['host'],
$config['db']['user'],
$config['db']['pasw'],
$config['db']['database']
);
if ($DB->connect_error) { die('db error: ' . mysqli_connect_errno()); }
// Load page requested by user. For now, its dog hardcoded.
require_once('./pages/page_dog.inc.php');
$DB->close;
/models/model_dog.inc.php (aka model) talks to the DB for you, processes and sanitizes data. I also use this put form processing functions.
<?php if(!defined('YOURFRAMEWORK')){die('External access denied');}
class ModelDog extends BaseModel {
private $tablename = 'dogs';
/**
* Load last (or specific) item.
* #param integer $id
* #return boolean Returns false when failed.
*/
public function Load($id=null) {
$query = "SELECT * FROM `".$this->tablename."` WHERE `id`='".$this->DB->Sanitize($id)."';";
// TODO .. $this->item =
}
public function ItemDefaults() {
return array(
'id' => 0,
'breed' => 'unknown',
'height' => 0
);
}
// TODO ..
}
/models/basemodel.inc.php extend every model class from something common like:
abstract class BaseModel
{
protected $item = array(); // Here is all the data!
protected $DB = null;
public function __construct($aQDB) {
parent::__construct();
$this->DB = $aDB;
$this->Reset();
}
public function Reset() {
$this->item = ItemDefaults();
}
public function Item() { return $item; }
// As seen in dog
abstract public function Load($id);
abstract public function ItemDefaults();
// But descendants (models) must also implement:
abstract public function Save($id = NULL);
abstract public function Delete($id);
// You may want to add Validate() and other internal things here.
}
All of the above is a bare-minimum version of what i build myself when i need another tiny framework. You gain more in proper subclassing than making more classes doing more things. A website is a simple thing in essence, until one overcomplicates it..
The gist / TLDR;
If you really want a REALLY simplified PHP framework, dont read to much. Just write code and you'll discover what it needs to make you work better.
Using pimple as my DI container, I have been bravely refactoring small classes to rely on DI injection, eliminating the hard-coded dependencies I could see would be easily removed.
My methodology for this task is very simple, but I have no clue if it is proper as I have very little experience with DI and Unit-testing aside from what I learned here in past month.
I created a class, ContainerFactory that subclasses pimple, and in that subclass have created methods that simply returns container for specific object.
The constructor calls the proper creator method depending on type:
function __construct($type=null, $mode = null){
if(isset($type)){
switch ($type) {
case 'DataFactory':
$this->buildDataFactoryContainer($mode);
break;
case 'DbConnect':
$this->buildDbConnectContainer($mode);
break;
default:
return false;
}
}
}
The method signature for container object creation is as follows:
public function buildDataFactoryContainer($mode=null)
The idea being that I can set $mode to test when calling this container, and have it load test values instead of actual runtime settings. I wanted to avoid writing separate container classes for testing, and this is an easy way I thought to not have test related code all over.
I could instead have subclassed ContainerFactory ie: ContainerFactoryTesting extends ContainerFactory and override in that instead of mixing test code with app code and cluttering method signatures with $mode=null, but that is not the point of this post. Moving on, to create a container for a particular object, I simply do this:
// returns container with DataFactory dependencies, holds $db and $logger objects.
$dataFactoryContainer = new ContainerFactory('DataFactory');
// returns container with test settings.
$dataFactoryTestContainer = new ContainerFactory('DataFactory','test');
// returns container with DbConnect dependencies, holds dbconfig and $logger objects.
$dbConnectContainer = new ContainerFactory('DbConnect');
I just ran into an issue that makes me suspect that the strategy I am building upon is flawed.
Looking at the above, DataFactory contains $db object that holds database connections.
I am now refactoring out this dbclass to remove its dependencies on a $registry object,
but how will I create $dataFactoryContainer, when I add $db object that needs $dbConnectContainer?
For example, in datafactory container I add a dbconnect instance, but IT will now need a container passed to it ...
I realise my English is not that great and hope I have explained well enough for a fellow SO'er to understand.
My question is two-fold, how do you guys handle creating objects for dependencies that themselves contain dependencies, in a simple manner?
And .. how do you separate container configuration for creation of objects for testing purposes?
As always, any comment or link to relevant post appreciated.
You should not create separate containers for everything, but instead use a single container. You can create a container "Extension" which basically just sets services on your container.
Here is an extensive example of my suggested setup. When you have a single container, recursively resolving dependencies is trivial. As you can see, the security.authentication_provider depends on db, which depends on db.config.
Due to the laziness of closures it's easy to define services and then define their configuration later. Additionally it's also easy to override them, as you can see with the TestExtension.
It would be possible to split your service definitions into multiple separate extensions to make them more reusable. That is pretty much what the Silex microframework does (it uses pimple).
I hope this answers your questions.
ExtensionInterface
class ExtensionInterface
{
function register(Pimple $container);
}
AppExtension
class AppExtension
{
public function register(Pimple $container)
{
$container['mailer'] = $container->share(function ($container) {
return new Mailer($container['mailer.config']);
});
$container['db'] = $container->share(function ($container) {
return new DatabaseConnection($container['db.config']);
});
$container['security.authentication_provider'] = $container->share(function ($container) {
return new DatabaseAuthenticationProvider($container['db']);
});
}
}
ConfigExtension
class ConfigExtension
{
private $config;
public function __construct($configFile)
{
$this->config = json_decode(file_get_contents($configFile), true);
}
public function register(Pimple $container)
{
foreach ($this->config as $name => $value) {
$container[$name] = $container->protect($value);
}
}
}
config.json
{
"mailer.config": {
"username": "something",
"password": "secret",
"method": "smtp"
},
"db.config": {
"username": "root",
"password": "secret"
}
}
TestExtension
class TestExtension
{
public function register(Pimple $container)
{
$container['mailer'] = function () {
return new MockMailer();
};
}
}
ContainerFactory
class ContainerFactory
{
public function create($configDir)
{
$container = new Pimple();
$extension = new AppExtension();
$extension->register($container);
$extension = new ConfigExtension($configDir.'/config.json');
$extension->register($container);
return $container;
}
}
Application
$factory = new ContainerFactory();
$container = $factory->create();
Test Bootstrap
$factory = new ContainerFactory();
$container = $factory->create();
$extension = new TestExtension();
$extension->register($container);
public function getHelperInstance()
{
$user = new Helper();
$user->set($result['data']);
return $user;
}
I am calling getHelper() class multiple times and if $user is not empty than am calling getHelperInstance(), now in my case getHelperInstance() always creates a new instance of Helper() class and so every time I call getHelperInstance() function am creating a new instance of Helper() so is there any way where can I can just create one instance of Helper() and use it multiple times instead of creating a new instance everytime. Any suggestions !!!
public function getHelper()
{
$user = array();
if (!empty($user))
{
$user = $this->getHelperInstance();
}
return $user;
}
Here is what Erich Gamma, one of the Singleton pattern's inventors, has to say about it:
"I'm in favor of dropping Singleton. Its use is almost always a design smell"
So, instead of a Singleton, I suggest to use Dependency Injection.
Create the Helper instance before you create what is $this. Then set the helper instance to the $this instance from the outside, either through a setter method or through the constructor.
As an alternative, create a Helper broker that knows how to instantiate helpers by name and pass that to the $this instance:
class HelperBroker
{
protected $helpers = array();
public function getHelper($name)
{
// check if we have a helper of this name already
if(!array_key_exists($name, $this->helpers)) {
// create helper and store for later subsequent calls
$this->helpers[$name] = new $name;
}
return $this->helpers[$name];
}
}
This way you can lazy load helpers as needed and will never get a second instance, without having to use Singleton. Pass an instance of the broker to every class that needs to use helpers.
Example with a single helper
$helper = new Helper;
$someClass = new Something($helper);
and
class Something
{
protected $helper;
public function __construct($helper)
{
$this->helper = $helper;
}
public function useHelper()
{
$return = $this->helper->doSomethingHelpful();
}
}
Inside $something you can now store and access the helper instance directly. You don't need to instantiate anything. In fact, $something doesn't even have to bother about how a helper is instantiated, because we give $something everything it might need upfront.
Now, if you want to use more than one helper in $someClass, you'd use the same principle:
$helper1 = new Helper;
$helper2 = new OtherHelper;
$something = new Something($helper1, $helper2);
This list will get rather long the more dependencies you insert upfront. We might not want to instantiate all helpers all the time as well. That's where the HelperBroker comes into play. Instead of passing every helper as a ready instance to the $something, we inject an object that knows how to create helpers and also keeps track of them.
$broker = new HelperBroker;
$something = new Something($broker);
and
class Something
{
protected $helperBroker;
public function __construct($broker)
{
$this->helperBroker = $broker;
}
public function doSomethingHelpful()
{
$return = $this->getHelper('foo')->doSomethingHelpful();
}
public function doSomethingElse()
{
$return = $this->getHelper('bar')->doSomethingElse();
}
}
Now $something can get the helpers it needs, when it needs them from the broker. In addition, any class that needs to access helpers does now no longer need to bother about how to create the helper, because this logic is encapsulated inside the broker.
$broker = new HelperBroker;
$something = new Something($broker);
$other = new Other($broker);
The broker also makes sure that you only have one helper instance, because when a helper was instantiated, it is stored inside the broker and returned on subsequent calls. This solves your initial problem, that you don't want to reinstance any helpers. It also doesn't force your helpers to know anything about how to manage themselves in the global state, like the Singleton does. Instead you helpers can concentrate on their responsibility: helping. That's clean, simple and reusable.
It sounds like you are interested in the singleton pattern. If you are using PHP5+, you should be able to take advantage of PHP's OOP stuff.
Here's an article on how to implement a singleton in php4. (But I would strongly suggest updating to php5 if that is an option at all)
class Singleton {
function Singleton() {
// Perform object initialization here.
}
function &getInstance() {
static $instance = null;
if (null === $instance) {
$instance = new Singleton();
}
return $instance;
}
}
PHP 4 Singleton Pattern
FYI, if you have any control over which PHP version you use you really should migrate to PHP 5.