One of the things that often confuses people new to object-oriented PHP is what are called “PHP static methods” and “static properties”. They’re often confusing, because you simply aren’t used to the syntax, which is a PHP double-colon (::
) where you might expect an arrow (->
). But, I’m getting ahead of myself.
Our goal here is to fully explain what PHP static methods and properties are and when you should use them. You can use them in WordPress. You’ll probably sometimes see static methods used in WordPress. We’ll talk about the upsides and downsides of that, and then take a short diversion into the popular PHP framework called Laravel, as it adds one final wrinkle to the whole story. Let’s get to our take on what PHP static methods are and how they work in WordPress.
What’s a PHP Static Class? How does it relate to OOP in PHP?
A “static class” isn’t really a thing in PHP, it turns out. Technically speaking, a class is never marked as static. Rather, methods and properties on a PHP class can be marked as static. But again, I’m getting ahead of you. First let’s make sure we’re all on the same page about OOPHP, properties, and methods.
Quick Summary of PHP OOP (+ Examples)
In short, OOP (Object-Oriented PHP) is a programming model that grew up because of the way that humans inherently understand the world through objects. When I look around the room, I see that I am sitting on a “chair,” not a mess of behaviors and properties.
That said, when we apply this “object-thinking” to programming, we still come to understand and see chunks. This is where most people are used to understanding PHP methods and properties. In brief, methods and properties are functions and variables that are stored on specific objects. Again, if this is all brand new to you, probably go and read our tutorial on making sense of basic PHP OOP before continuing. Here’s the best one we’ve got:w
PHP Static Methods in Depth: What They Are & How they Work in WordPress
What’s a Static Method in PHP?
We can actually call a static method without needing to create an object.
A method in PHP is considered static when its declaration has the literal keywork static
.
A static method looks as follows:
class Dog {
// Here are non-static properties and methods
public $color;
private $volume;
public function bark() {
text_to_speech("arf", $this->volume);
}
// Here's the static method
public static function areDogsGood() {
// Yes, dogs are good
return true;
}
}
// Static methods can be called without creating an object!
$areGood = Dog::areDogsGood(); // $areGood is true
Now, what does that static
mean? By being marked as static, we understand that this method is not an object- or instance-method—a method associated with any individual instance of the class—but rather a global method, associated with the class itself. So we actually can call a static method without needing to create an object. This is both really powerful and really weird.
We understand PHP classes as typically declaring the blueprint for objects. Then, our object are created when there is a call to new
, or they are __construct
ed. With PHP static methods, you’re actually doing something different.
Instead, you’re creating what is essentially a function (or method) that you can invoke or access from functionally anywhere. They are nominally on the “object” or “class”, but that class serves as little more than a “namespace” or “container” for the function that you’re declaring.
What’s a PHP Static Property? (And Why Not to Use Them for the Most Part)
Properties are usually specific to each instance of a PHP object. But static properties are different, again. This is because static properties aren’t really on instances of objects, but instead more-or-less living on the class
.
As such, use of static properties is generally discouraged. There are a small number of times they make sense, but doing things like storing object properties–like the color or size of a dog–on a static property doesn’t work the way you might expect.
The way a static property of a Dog
class would work is that it applies to all member of the Dog
class, including other instances. So if you set a static property on $fido
, an instance of Dog
to ‘brown’, all other dogs would also instantly become ‘brown’. This is the reason use of static properties is generally discouraged.
How to Call Static Methods in PHP from Outside
As mentioned, static methods are more approximately functions in the global PHP namespace than object methods. So, you call them similarly. Here’s where that PHP double-colon syntax comes in. To call a function, you’re probably used to seeing:
function_name($args);
Similarly, to call a static method, I’d call:
StaticClass::method_name($args);
In a case (say a WordPress action registration) where you often call a function with the string that matches its name, passing in a string with a double-colon works fine. That is, these two lines are the same:
add_action( 'wp_head', 'function_name' );
add_action( 'wp_head', 'StaticClass::method_name' );
One of the ways that static methods differ from global functions, however, is that the array-callable syntax of PHP also gets used for them. So these three calls are also equivalent as far as the PHP runtime is concerned:
add_action( 'wp_head', 'StaticClass::method_name' );
add_action(
'wp_head',
array(
'StaticClass',
'method_name'
)
);
add_action( 'wp_head', [ 'StaticClass', 'method_name' ] );
Each of these work for PHP. Call static methods by simply passing in the name on them, either to the array, or with the double colon. Both work fine for static methods.
(For those who don’t know, the short array syntax []
was introduced to PHP in 5.4. I prefer it, but for full compatibility with the WordPress ecosystem, you may not be able to use it.)
How to Refer to Static Properties and Methods from Inside a PHP Class
If you’ve done a lot of PHP OOP, you’re probably pretty familiar with $this
. Inside of a PHP class, you can access properties or methods on the same class by using the this
keyword. You might expect to access static properties and methods the same. You can not.
Mostly in an effort to make clearer to readers the distinctions I’ve drawn above about the differing behaviors of static methods and properties, you’ll refer to them internally using the class name MyClass
, self
, (or if you’re at 5.3 or above static
) keyword. So rather than $this->property
, you’d call self::$property
. And instead of $this->objectMethod()
you’ll call MyClass::staticMethod()
. (Practically speaking, self::
and MyClass::
will behave identically almost all the time. Assuming your class is named MyClass
. 😝) Again, this seemingly strange choice makes sense when we remember that:
- Static methods and properties behave very differently from their instance-based object alternatives.
- PHP wants to make very sure you realize that
static
things behave differently.
In general, you should understand that self
in PHP refers to a class
, where $this
refers to the current instance. As instance properties are on the object (not the class, where they’ve merely received them from) you refer to them with $this
. Because static properties are on the class
, you must access and refer to them using self
.
As mentioned briefly, PHP 5.2 (which you still might need to support in WordPress) doesn’t have the static
class reference, so you’ll see self
most often. There’s some nuance about the difference between self
and static
, but as I’m about to tell you not to use either much, I’m not going to explain. The PHP.net documentation explains late static binding pretty well.
When to Use Static Methods in PHP
In general, you’ll find that PHP static methods (and properties) are discouraged. There’s a small number of use cases where I do think they’re reasonable to use, so let’s cover that first.
The Case in Favor of PHP Static Methods and Properties
The reason to use PHP static properties and methods is that something is really static. “Static”, if you’re not familiar, is often used in English to mean “unchanging.” Sometimes, objects in a system would be truly static in this way.
An example I cite a lot is a unit converter. If you had an application where you often needed to convert, say inches to feet or centimeters, it would make sense to do that with a static object in PHP. That way, calling the methods wouldn’t need new
ing an object, a process that only barely makes conceptual sense anyway.
Instead, you’d just call the function as, say, Converter::fromInchesToFeet(23)
and get your answer. (As a reminder, the function of that double colon in PHP is calling the method on the static class.) It’s a little quicker and more concise.
And the scale factors involved—from feet to inches, inches to centimeters, etc–are also constant over time and place. So you wouldn’t really intend that they change, unless you want all of your conversions everywhere to change in sync. So it may make sense to define that static $inchesPerFoot = 12
, and then refer to it within our class as self::$inchesPerFoot
.
Why People Dislike Static Methods
In general, the PHP community (and most programmers) strongly critique the use of static methods and properties. The primary reason: they’re what people call “global state.” While the full meaning of that term is too big for this specific article, the core idea is that they’re things that everything in the system can use, and might use, and so it’s hard to control what’s happening.
When you new
an object and make a true “instance” of it, you keep methods and properties localized. static
methods and properties can cause “spooky action at a distance” where changes in one place affects others, without a clear sense of why or how being available. Programming and programmers are largely enabled by certainty, so they dislike this. Also, history and experience has generally lead people to the opinion that global state often gets out of hand as an application gets older and more diversely used.
There a small number of cases that I think static methods make sense. But in general you’ll love object-oriented PHP more if you stick closely to the instance/object based form and miss out on statics.
Laravel Looks like Static Methods…
One wrinkle to mention, briefly, is that that double colon in PHP (
::
) is used in the popular MVC framework called Laravel. This has been a source of confusion, internet fights, and annoyance for years. Mostly the fighting has receded (or I pay less attention to it), but for people seeing Laravel code for the first time, the way it looks like it involves lots of static methods can often cause alarm. (For reasons mentioned in the prior section.)
What’s actually happening in Laravel is that the “missing method” is called when an instance of the object that looks like it’s being called statically in the framework. So it’s not actually the case that these are “static method calls”, even though a quick look at the code looks exactly like it is. So you’ll see User::all()
, which looks like a static call. But under the hood Laravel is actually calling an object method to get all the users from the database.
This is an example of framework magic. Framework magic is a topic that I (and many others) have strong and emotional opinions about. So I’ll spare you, and just keep this informational. The Laravel PHP framework has things (which they call “facades”) that look like static calls to PHP methods. They are not. We’ll leave it right there.
Get Out There & (Maybe) Use PHP Static Methods
It’s very important that you understand PHP static methods to be fully productive as a PHP developer. Whether you’re doing it in Laravel, WordPress, or some other PHP web framework, you’ll meet them and it’s super useful to understand what the heck is going on.
That said, I wouldn’t really recommend that you use static methods in PHP. And I definitely don’t recommend that you use static properties, unless you’re fully certain that you understand and want their pretty confusing behavior. Just know that the double-colon in PHP (::
) is almost always (except in Laravel 🙃) for accessing static properties and methods in PHP, and you’ll do fine. Best of luck and happy hacking!
I usually use static on WordPress, but the other thing that I use is namespaces, that ensures for use of those static clases need to “use” them o access through is full name PluginName\Includes\StaticClass, so I’m fine with static
I stumbled upon this while reading your namespaces article. One of my favorite ways to use static methods is when I’m making a WordPress plugin. I see some plugins add hooks using the __construct() but I like initializing my hooks with a static method so that adding hooks are intentional and not accidental via new Class().
…
public static initialize() {
$class = new self();
$class->action_hooks();
}
private function action_hooks() {
add_action( ‘init’, array( $this, ‘foobar’ ) );
}
…
SomeClass::initialize();