Смотрите. Есть такая простая иерархия классов:
class A
{
public static $text = 'class A';
public function selfTest()
{
echo self::$text;
}
public function staticTest()
{
echo static::$text;
}
}
class B extends A
{
public static $text = 'class B';
}
Мы создаем экземпляк субкласа и вызываем методы, определенные в предке.
$obj = new B();
$obj->selfTest(); // выведет "class A"
$obj->staticTest(); // выведет "class B"
self всегда указывает на тот класс, в котором он написал. Здесь метод описан в классе A, и self указывает на класс A, хоть и вызывается из класса B.
Значение static вычисляется при вызове. И static указывает на класс объекта в котором произошел вызов. В нашем случае он указывает на B, хотя сам код описан в классе A.
Зачем это надо? Для того, что бы можно было переопределять статичные члены вашего класса в наследниках и вы могли обращаться к новым значениям из методов, описанных в предке.
С обычными не статичными членами это и так работает, потому что они собираются, когда вы создаете объект класса. Что бы это работало для статичных методов, надо использовать static