Thomas Decaux
Thomas Decaux

Reputation: 22671

Is good to use static variable inside a PHP class method

I am doing a class "Container" to hold all my model/service instances, the class is a singleton.

Consider the following code portion (from a CodeIgniter project):

public function getReviewModel()
{
    static $loaded = false;

    if (!$loaded)
    {
        $this->load->model('review_model');

        $loaded = true;
    }

    return $this->review_model;
}

I am wondering if is still ok to use static inside method like this or should I use only class property (I mean about performance and coding standard) ?

Upvotes: 2

Views: 4001

Answers (2)

kuroi neko
kuroi neko

Reputation: 8661

In your example, nothing prevents the programmer to instanciate the class more than once (with dire results), so it is rather a confusing bit of code.

Static variables have their uses, be them local to a function or defined at class level.
Especially in PHP scripts, when the output is often a single piece of data that can conveniently be handled as a class defining only static properties and methods.
That would be a true, foolproof singleton class.

Since mistaking a static variable for a dynamic one is a common pitfall, I tend to favor static class variables to avoid the confusion (i.e. the self::$... syntax makes them stand out clearly).

Upvotes: 2

Elias Van Ootegem
Elias Van Ootegem

Reputation: 76405

General consensus as far as statics are concerned in PHP is: Avoid, if at all possible. And yes, 99% of the time, it is possible to avoid statics.
Singletons should be avoided 100% of the time. For reasons you can find here and virtually everywhere else on the web. Singletons are like communism: sounds like a nice idea, but when put in to practice, it turns out there's one or two things you didn't anticipate.
A Singletons' main purpouse is to retain state, but PHP itself is stateless, so come the next request, the singleton needs to be re-initialized anyway.

If I write getters like yours, I tend to create them in a lazy-load kind of way:

class Example
{
    private $reviewModel = null;//create property
    public function getReviewModel()
    {
        if ($this->reviewModel === null)
        {//load once the method is called, the first time
            $this->reviewModel = $this->load->model('review_model');
        }
        return $this->reviewModel;
    }
}

This basically does the same thing, without using statics. Because I'm using a property, I still retain the instance, so if the getReviewModel method is called again, the load->model call is skipped, just as it would be using a static.
However, since you're asking about performance as well as coding standards: statics are marginally slower than instance properties: Each instance has a HashTable containing for its properties, and a pointer to its definition. Statics reside in the latter, because they are shared by all instances, therefore a static property requires extra lookup work:

instance -> HashTable -> property
instance -> definition -> HashTable -> property

This isn't the full story, check answer + links here, but basically: the route to a static propery is longer.

As for coding standards: They exist, though still unofficial, most major players subscribe to them, and so should you: PHP-FIG
Things like $this->_protectedProperty; don't comply with the PSR-2 standard, for example, which states, quite unequivocally:

Property names SHOULD NOT be prefixed with a single underscore to indicate protected or private visibility.

Upvotes: 1

Related Questions