What is the difference between self::$bar and static::$bar in PHP?
When you use self
to refer to a class member, you're referring to the class within which you use the keyword. In this case, your Foo
class defines a protected static property called $bar
. When you use self
in the Foo
class to refer to the property, you're referencing the same class.
Therefore if you tried to use self::$bar
elsewhere in your Foo
class but you had a Bar
class with a different value for the property, it would use Foo::$bar
instead of Bar::$bar
, which may not be what you intend:
class Foo
{
protected static $bar = 1234;
}
class Bar extends Foo
{
protected static $bar = 4321;
}
When you call a method via static
, you're invoking a feature called late static bindings (introduced in PHP 5.3).
In the above scenario, using self
will result in Foo::$bar
(1234).
And using static
will result in Bar::$bar
(4321) because with static
, the interpreter takes into account the redeclaration within the Bar
class during runtime.
// self
var_dump(Foo::$bar);
// (int) 1234
// static
var_dump(Bar::$bar);
// (int) 4321
You typically use late static bindings for methods or even the class itself, rather than properties, as you don't often redeclare properties in subclasses; an example of using the static
keyword for invoking a late-bound constructor can be found in this related question: New self vs. new static
However, that doesn't preclude using static
with properties as well.
New self vs. new static
will I get the same results?
Not really. I don't know of a workaround for PHP 5.2, though.
What is the difference between
new self
andnew static
?
self
refers to the same class in which the new
keyword is actually written.
static
, in PHP 5.3's late static bindings, refers to whatever class in the hierarchy you called the method on.
In the following example, B
inherits both methods from A
. The self
invocation is bound to A
because it's defined in A
's implementation of the first method, whereas static
is bound to the called class (also see get_called_class()
).
class A {
public static function get_self() {
return new self();
}
public static function get_static() {
return new static();
}
}
class B extends A {}
echo get_class(B::get_self()); // A
echo get_class(B::get_static()); // B
echo get_class(A::get_self()); // A
echo get_class(A::get_static()); // A
When should I use 'self' over '$this'?
Short Answer
Use
$this
to refer to the current
object. Useself
to refer to the
current class. In other words, use
$this->member
for non-static members,
useself::$member
for static members.
Full Answer
Here is an example of correct usage of $this
and self
for non-static and static member variables:
<?php
class X {
private $non_static_member = 1;
private static $static_member = 2;
function __construct() {
echo $this->non_static_member . ' '
. self::$static_member;
}
}
new X();
?>
Here is an example of incorrect usage of $this
and self
for non-static and static member variables:
<?php
class X {
private $non_static_member = 1;
private static $static_member = 2;
function __construct() {
echo self::$non_static_member . ' '
. $this->static_member;
}
}
new X();
?>
Here is an example of polymorphism with $this
for member functions:
<?php
class X {
function foo() {
echo 'X::foo()';
}
function bar() {
$this->foo();
}
}
class Y extends X {
function foo() {
echo 'Y::foo()';
}
}
$x = new Y();
$x->bar();
?>
Here is an example of suppressing polymorphic behaviour by using self
for member functions:
<?php
class X {
function foo() {
echo 'X::foo()';
}
function bar() {
self::foo();
}
}
class Y extends X {
function foo() {
echo 'Y::foo()';
}
}
$x = new Y();
$x->bar();
?>
The idea is that
$this->foo()
calls thefoo()
member function of whatever is the exact type of the current object. If the object is oftype X
, it thus callsX::foo()
. If the object is oftype Y
, it callsY::foo()
. But with self::foo(),X::foo()
is always called.
From http://www.phpbuilder.com/board/showthread.php?t=10354489:
By http://board.phpbuilder.com/member.php?145249-laserlight
Why self::function() and $self- variable or self::$variable even though there is $this- function() and $this- variable (PHP)?
You're right, self is for static self-references while $this is for instantiated ones. self and $this might appear to work everywhere but consider this:
class A
{
public static function foo()
{
$this->bar();
}
public static function bar()
{
echo 'foobar!';
}
}
A::foo(); // Fatal error: Using $this when not in object context
This results in a fatal error because foo() was called statically. It's best to take some time and use them appropriately rather than always using one or the other.
PHP - when to use private static properties in the class
When you declare a normal property, there is a different value of that property for every instance you create of that class (each object you create with new Foo
). For a static property, there is one copy of that variable for the whole class.
This is separate from the visibility of that variable - a public static property exists once per class, and can be accessed from everywhere; a private static property exists once per class, but can only be accessed from inside that class's definition.
As a simple example, you could have a counter that gave each instance of the class a unique number. You don't need code outside the class to see or change this counter, so you mark it private, but it needs to be shared amongst all instances, so you mark it static.
class Foo {
// Static counter; shared with every instance
private static $nextID=0;
// Normal instance property: each instance will have its own value
private $myID;
public function __construct() {
// Set the ID for this instance to the next ID
$this->myID = self::$nextID;
// Increment the shared counter
self::$nextID++;
}
}
PHP function pass by reference self::$menus
You are passing it in as a recursive call here:
self::addChild($item_id, $title, $url, $parent_id, $value);
Which might be better as:
static::addChild($item_id, $title, $url, $parent_id, $value);
So just use static::$menus
instead of $array
if nothing was passed in:
public static function addChild($item_id, $title, $url, $parent_id, &$array=null)
{
if($array === null) {
$array = &static::$menus;
}
// other code
}
Or this might be better since you actually need an array:
if(!is_array($array)) {
$array = &static::$menus;
}
Then for the main calls (not recursive) just omit the $array parameter.
- What is the difference between self::$bar and static::$bar in PHP?
- PHP Manual - Late Static Bindings
PHP 5: const vs static
In the context of a class, static variables are on the class scope (not the object) scope, but unlike a const, their values can be changed.
class ClassName {
static $my_var = 10; /* defaults to public unless otherwise specified */
const MY_CONST = 5;
}
echo ClassName::$my_var; // returns 10
echo ClassName::MY_CONST; // returns 5
ClassName::$my_var = 20; // now equals 20
ClassName::MY_CONST = 20; // error! won't work.
Public, protected, and private are irrelevant in terms of consts (which are always public); they are only useful for class variables, including static variable.
- public static variables can be accessed anywhere via ClassName::$variable.
- protected static variables can be accessed by the defining class or extending classes via ClassName::$variable.
- private static variables can be accessed only by the defining class via ClassName::$variable.
Edit: It is important to note that PHP 7.1.0 introduced support for specifying the visibility of class constants.
Static counter of subclass instances in PHP
A lot depends on where you define the count and how you access it. If you have 1 count in the base class, then there is only 1 count. If you have a count in each class, then you need to be aware of how to access the right value. Using self
or static
is discussed more What is the difference between self::$bar and static::$bar in PHP?
class Vehicle
{
protected static $_count=0;
public static function getCount() {
return static::$_count;
}
public function __construct($type, $year)
{
// Access the count in the current class (Bike or Car).
static::$_count++;
// Access the count in this class
self::$_count++;
}
}
class Bike extends Vehicle
{
protected static $_count=0;
}
class Car extends Vehicle
{
protected static $_count=0;
}
This has both, and in the constructor, it increments them both. This means there is a total of all vehicles and of each type...
echo "Vehicle::getCount()=".Vehicle::getCount().PHP_EOL;
echo "Car::getCount()=".Car::getCount().PHP_EOL;
echo "Bike::getCount()=".Bike::getCount().PHP_EOL;
$a = new Car("a", 1);
echo "Vehicle::getCount()=".Vehicle::getCount().PHP_EOL;
echo "Car::getCount()=".Car::getCount().PHP_EOL;
echo "Bike::getCount()=".Bike::getCount().PHP_EOL;
$a = new Bike("a", 1);
echo "Vehicle::getCount()=".Vehicle::getCount().PHP_EOL;
echo "Car::getCount()=".Car::getCount().PHP_EOL;
echo "Bike::getCount()=".Bike::getCount().PHP_EOL;
gives (not very clear though)...
Vehicle::getCount()=0
Car::getCount()=0
Bike::getCount()=0
Vehicle::getCount()=1
Car::getCount()=1
Bike::getCount()=0
Vehicle::getCount()=2
Car::getCount()=1
Bike::getCount()=1
PHP - Using static attributes and methods
You can use self::method();
operator to call it's own methods and attributes..
Constructor
private function __construct()
{
// Your class variables initialization stuff here
}
Related Topics
Remove .PHP Extension (Explicitly Written) for Friendly Url
Using MySQLi from Another Class in PHP
Dependency Hell - How Does One Pass Dependencies to Deeply Nested Objects
Yosemite/El Capitan PHP-Gd + Mcrypt Installation
Mechanisms for Tracking Db Schema Changes
Magento - Retrieve Products with a Specific Attribute Value
PHP Read_Exif_Data and Adjust Orientation
How to Use "Dependency Injection" in Simple PHP Functions, and Should I Bother
PHP File Listing Multiple File Extensions
Can't Send Email to Addresses at My Own Domain
How to Zip Folder Without Full Path
PHP and Mod_Fcgid: Ap_Pass_Brigade Failed in Handle_Request_Ipc Function