Static vs. Self: Unraveling Late Static Bindings in PHP
Jul 26, 2025 am 09:50 AMWhen a static method is called using self in inheritance, it always points to the class that defines the method, rather than the actually called class, resulting in the inability to call the subclass overridden method as expected; while static uses late static binding, which can correctly parse to the actually called class at runtime. 1. Self is an early binding, pointing to the class where the code is located; 2. static is a late binding, pointing to the runtime calling class; 3. Use static to implement static factory methods and automatically return subclass instances; 4. static supports correct parsing of inherited attributes in the method chain; 5. LSB is only suitable for static methods and attributes, not for constants; 6. Static should be used first in inheritable classes to improve flexibility and scalability, which is widely recommended in modern PHP.
When working with inheritance in PHP, you've probably encountered self
and wondered why sometimes it doesn't behave the way you'd expect — especially when calling static methods from child classes. This is where Late Static Bindings (LSB) come into play, and the difference between self
and static
becomes cruel.
The Problem with self
self
in PHP refers to the class where the method is defined , not necessarily the one that's calling it. This means it's early bound — resolved at compile time, not runtime.
Consider this example:
class ParentClass { public static function who() { echo "ParentClass\n"; } public static function callWho() { self::who(); } } class ChildClass extends ParentClass { public static function who() { echo "ChildClass\n"; } } ChildClass::callWho(); // Outputs: "ParentClass"
Even though we're calling callWho()
on ChildClass
, it outputs ParentClass
. Why? Because self::who()
inside ParentClass
always refer to ParentClass::who()
, regardless of the calling context.
This behavior is often not what you want when designing excessive class hierarchies.
Enter static
: Late Static Bindings
PHP 5.3 introduced Late Static Bindings , allowing static
to refer to the class that was called at runtime — not where the method is defined.
Let's tweak the example using static
instead of self
:
class ParentClass { public static function who() { echo "ParentClass\n"; } public static function callWho() { static::who(); // Note: static instead of self } } class ChildClass extends ParentClass { public static function who() { echo "ChildClass\n"; } } ChildClass::callWho(); // Outputs: "ChildClass"
Now it prints ChildClass
. That's because static::who()
is resolved at runtime based on the actual class used in the call — this is late binding .
? Rule of thumb:
self
→ refers to the current class (where the code is written)static
→ refers to the called class (which may be a child)
Practical Use Cases for static
1. Static Factory Methods
You can create a base factory method that returns instances of the correct child class:
class Model { public static function create() { return new static(); // Returns instance of called class } } class User extends Model { // Inherits create(), but returns User instance } $user = User::create(); // Actually a User object var_dump($user instanceof User); // true
Without static
, you'd have to override create()
in every child class.
2. Method Chaining with Inheritance
class QueryBuilder { protected static $table; public static function all() { echo "Selecting from " . static::$table . "\n"; } } class User extends QueryBuilder { protected static $table = 'users'; } User::all(); // Outputs: "Selecting from users"
Again, static::$table
resolves to User::$table
, not QueryBuilder::$table
.
Caveats and Limitations
- LSB only works with static method and property calls.
- It doesn't apply to constants (
self::CONST
vsstatic::CONST
still refer to the class where it's defined). - Be cautious when using
static
in final classes — no inheritance, soself
andstatic
behave the same. - Performance difference is negligible; prioritize clarity and correct behavior.
Summary
Keyword | Binding Time | Refers To |
---|---|---|
self
|
Early (compile time) | Class where method is defined |
static
|
Late (runtime) | Actual class called |
Use static
when you want inherited methods to respect the calling class's implementation — especially in abstract bases, factories, or fluent interfaces.
In modern PHP, favor static
over self
when working with static methods in inheritable classes. It makes your code more flexible and intuitive.
Basically: if you're building something means to be extended, static
is probably the right choice.
The above is the detailed content of Static vs. Self: Unraveling Late Static Bindings in PHP. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Yes,PHPsyntaxiseasy,especiallyforbeginners,becauseitisapproachable,integrateswellwithHTML,andrequiresminimalsetup.Itssyntaxisstraightforward,allowingdirectembeddingintoHTMLwithtags,using$forvariables,semicolonsforstatements,andfamiliarC-stylestructur

PHP8attributesreplaceDocBlocksformetadatabyprovidingtype-safe,nativelysupportedannotations.1.Attributesaredefinedusing#[Attribute]andcantargetclasses,methods,properties,etc.2.Theyenablecompile-timevalidation,IDEsupport,andbetterperformancebyeliminati

PHP8.0'snamedargumentsandconstructorpropertypromotionimprovecodeclarityandreduceboilerplate:1.Namedargumentsletyoupassparametersbyname,enhancingreadabilityandallowingflexibleorder;2.Constructorpropertypromotionautomaticallycreatesandassignsproperties

PHP's array deconstruction and expansion operators can improve code readability and flexibility through concise syntax. 1. Array deconstruction supports extracting values from indexes and associative arrays, such as [$first,$second]=$colors, which can be assigned separately; elements can be skipped through empty placeholders, such as [,,$third]=$colors; associative array deconstruction requires the => matching key, such as ['name'=>$name]=$user, which supports renaming variables and setting default values to deal with missing keys. 2. Expand operator (...) can expand and merge arrays, such as [...$colors,'blue'], which supports majority combination and associative array overwrite, but subsequent keys will overwrite the former and do not replenish.

PHP's variable functions and parameter unpacking is implemented through the splat operator (...). 1. Variable functions use...$params to collect multiple parameters as arrays, which must be at the end of the parameter list and can coexist with the required parameters; 2. Parameter unpacking uses...$array to expand the array into independent parameters and pass it into the function, suitable for numerical index arrays; 3. The two can be used in combination, such as passing parameters in the wrapper function; 4. PHP8 supports matching named parameters when unpacking associative arrays, and it is necessary to ensure that the key name is consistent with the parameter name; 5. Pay attention to avoid using unpacking for non-traversable data, prevent fatal errors, and pay attention to the limit of parameter quantity. These features improve code flexibility and readability, reducing func_get_args() and so on

Arrow functions are suitable for scenarios with single expressions, simple callbacks and improved readability; 2. Anonymous functions are suitable for scenarios with multi-line logic, complex control flow, referencing external variables and using yield generators; therefore, you should choose according to specific needs: simple scenarios prioritize arrow functions to improve code simplicity, while complex scenarios use anonymous functions to obtain complete functional support.

When a static method is called using self in inheritance, it always points to the class that defines the method, rather than the actually called class, resulting in the inability to call the subclass overridden method as expected; while static uses late static binding, which can correctly parse to the actually called class at runtime. 1. Self is an early binding, pointing to the class where the code is located; 2. static is a late binding, pointing to the runtime calling class; 3. Use static to implement static factory methods and automatically return subclass instances; 4. static supports correct resolution of inherited attributes in the method chain; 5. LSB is only suitable for static methods and attributes, not for constants; 6. Static should be used first in inheritable classes to improve flexibility and scalability, which is in modern PH

Theternaryoperator(?:)isusedforsimpleif-elselogic,returningoneoftwovaluesbasedonacondition;2.Thenullcoalescingoperator(??)returnstheleftoperandifitisnotnullorundefined,otherwisetherightoperand,makingitidealforsettingdefaultswithoutbeingaffectedbyfals
