`self::` vs. `static::` in PHP: A Deep Dive into Late Static Binding
Content
## Introduction
In PHP Object-Oriented Programming (OOP), `self` and `static` are two common keywords used to access static members within a class. However, their differing behaviors in inheritance scenarios often cause confusion for developers and can lead to hard-to-trace bugs if misused. This article, using a classic example from a `wiki.lib00.com` project, will break down their differences and help you fully grasp PHP's **Late Static Binding** mechanism.
---
## The Core Difference at a Glance
Simply put, the difference lies in the timing of the "binding":
* `self::$property`: **Static Binding**. `self` always refers to the class where the code is **defined**. This relationship is determined at compile time.
* `static::$property`: **Late Static Binding**. `static` refers to the class that was actually **called at runtime**. This relationship is determined dynamically when the code is executed.
---
## The Code Example That Explains Everything
The best way to understand late static binding is through a practical example. Let's imagine we're building a simple ORM (Object-Relational Mapping) base model for the `lib00` platform. Each model needs a `$table` property to specify its corresponding database table name.
```php
<?php
namespace WikiLib00\Framework;
abstract class BaseModel {
// Define a default table name in the parent class
protected static string $table = 'base_models';
// Get the table name using `self`
public static function getSelfTable(): string {
// `self` always refers to BaseModel because it's defined here
return self::$table;
}
// Get the table name using `static`
public static function getStaticTable(): string {
// `static` refers to the class called at runtime (e.g., UserModel or ProductModel)
return static::$table;
}
}
class UserModel extends BaseModel {
// Override the parent's static property in the child class
protected static string $table = 'users';
}
class ProductModel extends BaseModel {
// Override the parent's static property in the child class
protected static string $table = 'products';
}
// --- Check the results ---
// Calling from UserModel
echo 'UserModel::getSelfTable(): ' . UserModel::getSelfTable(); // Outputs: base_models
echo "\n";
echo 'UserModel::getStaticTable(): ' . UserModel::getStaticTable(); // Outputs: users
echo "\n\n";
// Calling from ProductModel
echo 'ProductModel::getSelfTable(): ' . ProductModel::getSelfTable(); // Outputs: base_models
echo "\n";
echo 'ProductModel::getStaticTable(): ' . ProductModel::getStaticTable(); // Outputs: products
```
---
## Analyzing the Output
* **`UserModel::getSelfTable()`** returns `'base_models'`. Because the `getSelfTable()` method is defined in `BaseModel`, the `self` keyword is "locked" to the `BaseModel` class. No matter which child class calls it, it will only return the `$table` property defined in `BaseModel`.
* **`UserModel::getStaticTable()`** returns `'users'`. The `static` keyword enables late static binding. It doesn't lock to a class immediately. Instead, it waits until runtime to see who actually **called** the `getStaticTable()` method. In this case, the caller is `UserModel`, so `static` resolves to `UserModel` and returns its `$table` property.
---
## When to Use `self` vs. `static`?
Once you understand the difference, making the choice becomes simple:
* **Use `self`**: When you explicitly need to refer to a constant or static member defined in the **current class itself**, and you do not want it to be changed by the inheritance chain. For example, a fixed version number or a configuration item defined in a base class.
* **Use `static`**: When you are designing **extensible base classes or frameworks** where methods in the parent class need to flexibly use static members overridden in child classes. Table names in an ORM, or class names in a Factory pattern, are classic use cases for `static`. This approach makes the code more flexible and adheres to the Open/Closed Principle.
---
## Conclusion
The `static::` keyword is the key to PHP's Late Static Binding, significantly enhancing code flexibility and reusability. A key recommendation from the author `DP` is to prefer `static` for referencing static members when writing inheritable classes. This will allow you to build more powerful and adaptable systems.
Related Contents
MySQL TIMESTAMP vs. DATETIME: The Ultimate Showdown on Time Zones, UTC, and Storage
Duration: 00:00 | DP | 2025-12-02 08:31:40The Ultimate 'Connection Refused' Guide: A PHP PDO & Docker Debugging Saga of a Forgotten Port
Duration: 00:00 | DP | 2025-12-03 09:03:20The Ultimate PHP Guide: How to Correctly Handle and Store Markdown Line Breaks from a Textarea
Duration: 00:00 | DP | 2025-11-20 08:08:00Stop Manual Debugging: A Practical Guide to Automated Testing in PHP MVC & CRUD Applications
Duration: 00:00 | DP | 2025-11-16 16:32:33Mastering PHP Switch: How to Handle Multiple Conditions for a Single Case
Duration: 00:00 | DP | 2025-11-17 09:35:40PHP String Magic: Why `{static::$table}` Fails and 3 Ways to Fix It (Plus Security Tips)
Duration: 00:00 | DP | 2025-11-18 11:10:21Recommended
The Ultimate Nginx Guide: How to Elegantly Redirect Multi-Domain HTTP/HTTPS Traffic to a Single Subdomain
00:00 | 5This article provides an in-depth guide on how to ...
PHP CLI Magic: 3 Ways to Run Your Web Scripts from the Command Line with Parameters
00:00 | 14In development, it's common to adapt PHP scripts w...
Say Goodbye to Clutter: Master Sublime Text Code Folding with These Essential Shortcuts
00:00 | 6When working with large code files, code folding i...
The Magic of PHP Enums: Elegantly Convert an Enum to a Key-Value Array with One Line of Code
00:00 | 5How do you dynamically get all statuses of a model...