On Sun, Mar 14, 2021 at 6:02 PM Gert de Pagter <gert...@gmail.com> wrote:
> Hey Internals, > > Recently i've been working on an older code base, where we have a lot > of classes with all > static methods. We've been moving to injecting the classes, and > calling the methods as if they > were not static. > > I wanted to add interfaces to these classes, with non static methods, > so we can pretend in our implementation they are not static, and allow > us to easier switch to non static methods in the future. > I've encountered this issue working with legacy codebase. I recommend having two versions of the class, the old with static methods and the new with non-static methods. Logic would stay only in one of them, having the other as a wrapper. Migrating from static to non-static would change the injection as well as the calling style. > > This is (currently) not allowed by the language: https://3v4l.org/WKdvM > Is there any chance of this being possible in future versions of PHP? > This would only allow 'normal' methods to become static. Making static > methods non static would break Liskov substitution principle in PHP as > you may not be able to call the method in the same way. This means you > can't have a 'normal' method become static in an inherited class, and > then become 'normal' again in another inherited class. This works the > same way with co/contra-variance in return/parameter types: > (https://3v4l.org/j1SO9) > The issue exists also for class extended, not only for interface implemented. Even if in general, static and non-static method have different rules for inheritance and they must stay in general separated, this idea is not completely bad in PHP where the concept of late static binding that happens when one calls $object->staticMethod(); could allow such a thing to have a sense of existence for upgrading from non-static methods to a static method in the inheritance chain. As my experience with C is not vast, I'm not sure how the inheritance chain for static and non-static methods is represented internally to allow such change. Also the calling place logic would maybe need changes to seamlessly use polymorphism logic or late static binding depending on how the method is defined in the class of the object called, if that isn't already done in some way. As I want to learn more here, I will try looking it up to understand it. But overall, it sounds like it can be avoided by choosing a separate chain of inheritance approach. Composition over inheritance. Regards, Alex