user2294256
user2294256

Reputation: 1049

trying to understand late static bindings in php

<?php
class Record {

    protected static $tableName = 'base';

    public static function getTableName() {
        echo self::$tableName;
    }
}
class User extends Record {
    protected static $tableName = 'users';
}
User::getTableName(); 

It shows: base

Question:

I know I can change the problem by changing this line echo self::$tableName; to echo static::$tableName;, it is called 'late static bindings', I read the doc here, but still not quite understand it. So could you give me some explanation on:

a. why this line of code echo self::$tableName; shows: base?

b. why this line of code echo static::$tableName; shows: users?

Upvotes: 10

Views: 2216

Answers (4)

Petter Kjelkenes
Petter Kjelkenes

Reputation: 1625

The example below will give a minimum example of late static binding:

class A {
    static public $name = "A";

    static public function getName () {
        return self::$name;
    }

    static public function getNameLateStaticBinding () {
        return static::$name;
    }
}


class B extends A {
    static public $name = "B";
}



// Output: A
echo A::getName(), "\n";

// Output: A
echo B::getName(), "\n";

// Output: B
echo B::getNameLateStaticBinding() , "\n";

B::getName() outputs the $name variable from A since self is computed from the absolute current class you defined self in. To solve such cases, use static.

Upvotes: 2

Orangepill
Orangepill

Reputation: 24645

self references the defining class scope.

static references calling classes scope.

self::$tableName references the class where it was defined. ie Record

static::$tableName references the class that it was invoked upon. ie User

Upvotes: 4

deceze
deceze

Reputation: 522025

self is "bound" at compile time, statically. That means when the code is compiled, it is decided what self refers to. static is resolved at run time, i.e. when the code is executed. That's late static binding. And that's the difference.

With self, it is decided at compile time (when the code is "read"), that self refers to Record. Later on the code for User is parsed, but self::$tableName in Record already refers to Record::$tableName and cannot be changed anymore.

When you use static, the reference is not resolved immediately. It is only resolved when you call User::getTableName(), at which point you're in the context of User, so static::$tableName is resolved to User::$tableName.

In other words: self always refers to the class that it has been written in, no two ways about it. What static refers to depends on what context it's used in; in practice that means it may refer to child classes if the class it occurs in is being extended. That makes it work like $this, only for static contexts.

Upvotes: 29

Rory Liu
Rory Liu

Reputation: 11

suggest you read about 'Object Inheritance' http://www.php.net/manual/en/language.oop5.inheritance.php

Upvotes: -1

Related Questions