On Thu, Jun 13, 2019 at 10:49 PM Mark Clements (HappyDog) < phpn...@kennel17.co.uk> wrote:
> Hi there, > > I've been reading with interest about the new FFI class that has been > introduced in PHP 7.4 [1]. > > However, I was surprised to see that the class includes bivalent methods, > that is to say methods that can be called both statically and > non-statically. For example, new() [2], which can be called as: > > FFI::new(...) > > or non-statically: > > $objFFI->new(...) > > (Note that the latter is not simply a short-cut to the former, as it > accesses the instance properties.) > > As you can see, this is a very useful design pattern, but it is one that is > currently disallowed in userland code: > > * If you declare a method as static, you can call it in both ways, but in > neither case can you access the instance properties or any other instance > functionality ($this is undefined). > * If you don't declare the method as static, and call it statically, you > get > a deprecation notice: > > Deprecated: Non-static method MyClass::MyMethod() should not be called > statically in file.php on line X > > This FFI class is therefore introducing an inconsistency in the language. > My understanding is that the general direction of travel is to try and > remove language inconsistencies, where possible, so introducing new ones > seems like something that should be strongly avoided where possible. > > My preference would be to resolve this inconsistency by un-deprecating the > uses of non-static methods in a static context. As per the example in the > FFI class, there are clearly use-cases where both methods of calling a > function are desirable. We have a number of such examples in our code > (e.g. > we have a GetMonthName() function in our date class, which can either > operate on an instantiated object or be called statically with any > date-like > argument). These functions currently detect the context and only access > $this when called non-statically. Correctly implemented, this type of > overloading leads to very clean interfaces (though I understand the risks > that inexperienced programmers might face). > We won't do this. In fact, this functionality is already completely removed on master. Alternatively, the FFI class should implement two different methods for the > different contexts. > Another possibility would be to make most of the current static methods on the FFI class into free functions. I.e. FFI\memcpy() rather than FFI::memcpy() and only keep the things that actually interact with an FFI context on the FFI class (which might be better named FFI\Context or similar). I think this would be semantically cleanest, but also a pretty significant change. Nikita