self:: resolves to the class where the code was written. That is almost never what a base class wants when it constructs an instance on behalf of a subclass, and the resulting bug is quiet: everything works until someone extends the class.
abstract class Model
{
public static function make(array $attributes)
{
return new static($attributes); // not `new self`
}
}
Order::make([...]); // an Order, not a Model
static:: resolves at call time to the class the call was made on. The same distinction applies to constants and static properties, which is why a subclass overriding a const sees no effect if the base class reads it with self::. When in doubt in a class designed to be extended, static:: is the safer default.