self resolves where the code is written and static resolves where it was called from, and a factory on a base class needs the second.
abstract class Model
{
public static function make(array $a): static
{
return new static($a); // self would return Model
}
}
Order::make([]); // an Order, with static
// a Model, with self — and a fatal,
// since Model is abstract
The rule is that static follows the call, which is why it is called late static binding — the resolution happens at runtime rather than at compile time. The cost is that a base class using new static has an unwritten requirement about every subclass’s constructor signature, and there is no way to declare it. Making the constructor private and the factory the only entry point at least contains the surprise.