DEV Community

spO0q 🐒
spO0q 🐒

Posted on • Edited on

Understanding PHP static

It remains a contentious topic. Let's try to understand why.

Static variables in procedural functions

You may already have seen the following code:

function testStatic() {
    static $x = 0;
    $x++;
    return $x;
}
Enter fullscreen mode Exit fullscreen mode

Here, the keyword static allows incrementing $x every time we call testStatic():

testStatic();
testStatic();
testStatic();
echo testStatic();
Enter fullscreen mode Exit fullscreen mode

displays "4". Unlike other local variables, static variables keep their values after the function scope.

This allows for interesting usages such as memoization. People use this technique to store the results of previous expensive operations to optimize their script.

Static in PHP classes

Every time you use the keyword static in a PHP class, you are setting class-related things. You access them without instantiating the class :

class MyClass {
    public static $myStaticVar;
    public static function myStaticFunction() {}
}

MyClass::myStaticFunction();
MyClass::$myStaticVar;
Enter fullscreen mode Exit fullscreen mode

In other words, you don't tie your variables and your functions to a particular object.

But how is it different from procedural programming? Why bother with classes anyway?

Static methods versus procedural functions

You often need some helpers in your code. Most of the time, these utils are PHP static classes :

$title = TextUtils::normalizeTitle($title);
Enter fullscreen mode Exit fullscreen mode

But is it so different than :

$title = normalizeTitle($title);
Enter fullscreen mode Exit fullscreen mode

According to a significant part of the PHP world, it might be the same thing. Static methods would be namespaced functions. Nothing more.

Namespaces have been available since PHP 5.3. Technically, there is no difference between a simple function and a static method in this case:

$title1 = \TheNamespace\TextUtils::normalizeTitle($title);
$title2 = \TheNamespace\normalizeTitle($title);
Enter fullscreen mode Exit fullscreen mode

So if everything in your class is static, you may use procedural functions and namespaces instead. But is it always like that?

Static versus Object-oriented programming (OOP)

You don't need instantiating a class to access its static methods. As a result, all instances of your class share the same static methods.

In a PHP class, you get the instance with the reserved keyword $this. Static methods cannot access it.

Let's look at the following example:

<?php
class Order {
    public $price;

    public function __construct($price) {
        $this->price = self::formatPrice($price);
    }

    protected static function formatPrice($price) { 
        return round($price, 3);
    }
}

$order = new Order('73.1111');
echo $order->price;
Enter fullscreen mode Exit fullscreen mode

formatPrice() does not need $this. It does not change from one instance to another. It's static. All instances share it.

Pros and cons

A lot of developers prefer using non-static methods than static methods. Some of them think static methods break the encapsulation and some even say static methods are code smells.

Don't get me wrong, I'm not saying they are deluded and static is the truth. My point is that there are myths about this topic. For example:

static code is insecure

Rather, setting non-mutable elements in your application seems more secure.

If you have crazy amounts of data, it's probably a bad idea to use static. If you need stateful mechanisms, that is to say, isolated instances with their logic, it seems a bad idea too.

Wrap up

Static is probably not bad, it might be misused. It's just that, all other things being equal, you cannot use it for anything and everything.

I like OOP, it's a fantastic paradigm but I wonder if everything needs an object. I guess no. I would love to have your opinion on this.

Top comments (1)

Collapse
 
rindraraininoro profile image
Raininoro Rindra

Good article !
I recently used a static local variable in a recursive function to get the depth of the recursion.
github.com/bolo21/translate-array-...