tags:

views:

37

answers:

3

I have a Java background. So please bear with me.

In a Java application, one way to perform one time initialization is to have an "Initializer Servlet" whose init() method can have one time initialization code. Another more general purpose mechanism is to have a Singleton that initializes on first use - and this mechanism will work in various languages / platforms. What I need to know is how to do it for my PHP webapp.

Should I use the Singleton Pattern? Is there another / better / PHP specific way? Essentially I want have a "Registry" - a single instance of it - which I can then use to create instances of other objects (themselves Singleton or not depends on situation at hand).

The ultimate goal is - I need certain things initialized BEFORE any web request is served by my PHP web application - something an "Initializer Servlet" in Java guarantees me. Maybe there is an "Initializer PHP Page" or something like that?

Thanks in advance

A: 

The source PHP, in the regular sense, does not generate an executable program. It is a scripting language. However, you are able to create a singleton.

Daniel A. White
+1  A: 

PHP's nature will not allow you to have a initialization like servlets. In PHP everything will be inside a web request. As you mentioned, the Registry design pattern can help you to have a place to put your objects, however, they will be recreated on every request.

Fernando
Err, now I'm a little confused. Are you saying even the Singleton pattern will not work for my Registry? Are you saying the "scope" of the Singleton is restricted to the thread of Control prpocessing my web request. If that is so, I'm not sure how various PHP frameworks out there are achieving Dependency Injection, unless of course the entire object heirarchy is being built on each web request. I want to use PHP but this would be a deal breaker for me and I hope I'm misinterpreting your comments.
Arby
Usually, the entire object heirarchy IS built on each request. The way it is done in the CakePHP project is quite easy to follow, perhaps it will provide some insight.
sleepynate
Unless something has changed in the last few years (about 3 years without working with php), I can tell you this: the entire object hierachy will be buit on each request.
Fernando
A: 

I do not have a Java background, but a singleton that on construction initiates and returns (or holds as static) other singletons/factories is a common pattern. Because the only defined "entry point" of a PHP application is the file that gets passed to the parser, many PHP applications go to great lengths to redirect to a "bootstrap" script, which prepares the environment and instantiates any singleton and static objects needed by the application. This is then included at the entry point to assure it is available to the entire application.

<?php // this file is bootstrap.php
// ... 
class MySingleton {
    private static $instance;

    private function __construct() {
        $this->myFactory1 = new MyFactory1();
        $this->myFactory2 = new MyFactory2();
        $this->myOtherSingleton = MyOtherSingleton::get();
    }

    public static function get() {
        if (!isset(self::$instance)) {
            $c = __CLASS__;
            self::$instance = new $c;
        }
        return self::$instance;
    }

    public function __clone() {
        trigger_error('Clone is not allowed.', E_USER_ERROR);
    }
}

// Before we leave, we'll get an instance!
$myBootstrapUtility = MySingleton::get();
// end of bootstrap.php ?>

one would then make sure to require_once('bootstrap.php'); before the rest of application logic.

Of course the actual details are entirely up to you, but this is certainly not an uncommon way of doing what you're after.

sleepynate
A-ha! Thanks much for your reply. Just one question.If I use require_once('bootstrap.php') it works differently than include('bootstrap.php') ACROSS all my php scripts? If the answer is yes, then it would mean the first time any user of my website were to hit index.php, my Singleton would be initialized and never again.Regardless, if a definitive answer does not exist to my question (you did say folks go to great length but didn't mention those lengths) then I dunno how various Frameworks like Zend, Symfony, etc claim to do "DI Once".
Arby
Usually, if it is a web application, making sure of the entry point is achieved with something such as `.htaccess`. `require_once` assures that the appropriate bootstrap is loaded, and loaded only once, so that other includes of the same file do not overwrite and reinstantiate your objects. Both ways are acceptable, but the common methodology tends toward `.htaccess`. A definitive answer perhaps does not exist, as it is a different language with a different ideology, but this is one of the ways something similar is achieved (which is far beyond the original goals of PHP).
sleepynate
Check out http://book.cakephp.org/view/21/A-Typical-CakePHP-Request, http://github.com/cakephp/cakephp/blob/master/cake/bootstrap.php, and the place where they actually handle sending the user to the right place after all the object-hierarchy building... the slightly more massive http://github.com/cakephp/cakephp/blob/master/cake/dispatcher.php (Noting the use of the App Registry)
sleepynate
Many thanks for the reference. I read a little bit of the documentation. I am a big fan of keeping things simple which is why I gravitated toward PHP for my personal work while I am forced to use Java at work. Zend, Symfony etc. seemed so complicated, I decided to roll out my own framework - hence the original question. But now as I look at CakePHP, it's simplicity is appealing.Thanks again.
Arby