13

I am learning php and there are still alot of unclear areas for me in the language. I wonder when and why would we use private static properties inside the class. From what I understood private properties may only be accessed by the class where it was defined. So, the private part is clear, but the static is still unclear. In the docs it says:

Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static cannot be accessed with an instantiated class object (though a static method can).

Does that mean that I can access static properties without instantiation of the class. So, for example:

class Foo{

    static $bar;

    public function __construct($bar){
        $this->bar = $bar;
    }

So, I can access the $bar property of the class like so?

Foo::$bar

But, if I do this, it wouldn't work?

$foo = new Foo();
$foo::$bar

And, then if do make a property private static for which reason would we do that, since I thought we make them static in order to access them outside of their class and making them private would make that impossible. I would be very grateful if someone could clear this up to me.

Leff
  • 1,968
  • 24
  • 97
  • 201
  • and how do you access static property? – Leff Mar 30 '17 at 09:56
  • If you need a property to be only accessible within the class but also accessible from a static context within the class (e.g. from within a static function) then you'd make it a `private static $variable` – apokryfos Mar 30 '17 at 09:56
  • Class::$aStaticProp; //by class name – Rotimi Mar 30 '17 at 09:57
  • Possible duplicate of [How do I access static member of a class?](http://stackoverflow.com/questions/3818333/how-do-i-access-static-member-of-a-class) – apokryfos Mar 30 '17 at 09:57
  • You do not need to instantiate the class to access the static prop – Rotimi Mar 30 '17 at 09:57
  • @apokryfos static context is unclear to me, I would be grateful if you could show that with some code example – Leff Mar 30 '17 at 09:59
  • @PhpDev how is ```Class::$aStaticProp;``` different from what I showed ```Foo::$bar```? – Leff Mar 30 '17 at 10:00
  • 2
    @Leff In PHP and many other languages, a class exists in 2 forms. It exists as a blueprint that is used to make objects, and it also exists as a singleton object on its own. That singleton object is the classes "static context" which is (ignoring language specific optimizations) is always created and available for a program. – apokryfos Mar 30 '17 at 10:12
  • private static is only accessible within the class `self::$bar` and public static is a shared variable for outside the class like `Foo::$bar` – Timmetje Mar 30 '17 at 10:12

2 Answers2

30

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++;
    }
}
IMSoP
  • 89,526
  • 13
  • 117
  • 169
  • 7
    Very nice example of private static usage :) – Timmetje Mar 30 '17 at 10:17
  • 1
    Thank you for this great example! Makes things clearer! – Leff Mar 30 '17 at 10:38
  • What is the difference if one uses private $counter which increases each time the class is instantiated? – Salam.MSaif Sep 09 '17 at 06:52
  • 2
    @Salam.Msaif If $counter is not static, it *won't* increase each time the class is instantiated, because each instance gets its own variable and doesn't know anything about the others. – IMSoP Sep 09 '17 at 10:38
  • What about `private static $bar = new Bar();`? Could you use it the same, to use for example only one instance of database for all `Foo()`s? – s3c Nov 28 '21 at 21:52
  • @s3c You can't use `new` in that position, but that's nothing to do with whether it's `private`, `static`, both, or neither. Other than that, assigning an object is no different from assigning any other value - if you write `private static $bar;` and then `self::$bar = new Bar();`, the object will be shared between all instances, just like any other value would be. – IMSoP Nov 28 '21 at 21:55
  • Right. Or put `public static function connect() { self::$bar ??= new Bar(); }` and call that before all other instances, am I wrong? What about just using `(new Db)->query(...)` in every method that need database? That's surely wrong for creating too many connections, agree? – s3c Nov 28 '21 at 22:02
  • @s3c I'm sure you've noticed by now that this website isn't intended to work like a forum, and isn't a good place to discuss opinions about the "right" and "wrong" way to do things. You seem to have correctly understood what `private static` means, and that's all that's relevant to this answer. – IMSoP Nov 28 '21 at 22:05
  • Agreed. My bad. – s3c Nov 28 '21 at 22:14
4

Static context within a PHP class (but outside of a function) is context which exists statically, that is without the need for a backing instance of an object.

Example:

class A {
     public $a = 1;
     public static $b = 2;

     public function instanceFunction() {
           A::$a; //Wrong way
           $this->a //Right way
           A::$b; //Works
           self::$b; // Also works
           static::$b; // Also also works
     }
     public static function staticFunction() {
           A::$a; //Does not work
           $this->a //Error $this within static context 
           A::$b; //Works
           self::$b; // Also works
           static::$b; // Also also works
     }

}

A::$a; // Error $a is not static so it needs an instance of an object
A::$b; // Works
$Aobject=new A();
$Aobject->a; //Works 
$Aobject->b // Does not work 

Using self means "refer to the class I've written this in" e.g. in this case it's always A. Using static means "refer to the class I've called this from" which applies if static inheritance is involved which PHP does manage to pull off.

apokryfos
  • 38,771
  • 9
  • 70
  • 114
  • And ```private static``` would only be accessible within the class by writing ```self::$bar``` ? – Leff Mar 30 '17 at 10:15
  • @Leff only within the class, but it doesn't matter if it's `self` or `static` or `A` that is used. – apokryfos Mar 30 '17 at 10:18