Serde
Serde copied to clipboard
Order of PostLoad methods is unexpected
According to the documentation, "any PostLoad methods will be invoked with no arguments in lexical order." This is not true:
class MyClass
{
private string $prop1;
private string $prop2;
#[PostLoad()]
protected function a()
{
throw new \Exception('A');
}
#[PostLoad()]
protected function b()
{
throw new \Exception('B');
}
}
This will result in Exception "A", but if the methods get swapped, the result is Exception "B". It looks like the actual order is determined by the result of ReflectionClass::getMethods() (tested on PHP 8.3.9), where the order is not officially documented and may change any time.
Sometimes it is desirable to have multiple PostLoad methods executed in a particular order, or at least have limited control so that we can guarantee that a particular method is invoked before another. Having order depend on the order of declaration would already be bad because the order of declaration generally should not matter. Guaranteeing a particular order may become impossible when some PostLoad methods come from a trait or parent class.
The idea of lexical ordering, even if it worked, is also ugly: that would force us to name methods accordingly, possibly breaking code when a method is renamed, or resulting in names like aaa_first() and zzz_last().
Would it be possible to add an optional "priority" parameter to the PostLoad attribute? That would give developers enough control over the invocation order, while not restricting how methods should be named or organized.
If this is not possible, the result of ReflectionClass::getMethods() should be sorted do give some predictability and match the documentation.