0

How would I add "functionality" to the @deprecated annotation so that I can execute code before or after (ideally both) execution of a function or when a deprecated property is accessed?

So I want to use the @deprecated annotation in PHP to do different things independent to the normal behaviour of the called function, so that developers who add the annotation to a deprecated function don't have to add the functionality to the function (e.g. logging details of the call).

In that way I think it's very usable as a developer and the IDE also recognizes the @deprecated annotation by default and suggests you not to use it.

I'm running PHP 7.3 if that's important.

  • 1
    What have you tried so far? Are you familiar with reflection? – waterloomatt Jul 10 '20 at 12:05
  • I'm just getting started with reflections. Caching all functions which are deprecated would be doable for me. But then I still can't react to a function or property which is called or can I? I'd say I need something like the before or after hooks from PhpUnit but have no idea how to do this – Felix Fischbach Jul 10 '20 at 12:30
  • PHP, unlike Java, has no concept of altering behaviour based on annotations. They're simply commented out code which it ignores. That's why you need reflection to read and parse the annotations. Although this is not very difficult to do on its face, your code needs to be structured in a way to intercept all calls and run your pre/post hooks as you described. This is not a trivial task. Can you please give us more information about your project setup? Are you open to a setup like this? https://stackoverflow.com/a/3242061/296555 – waterloomatt Jul 10 '20 at 12:51
  • So we are using ZendFramework 1 (yes I know, we are planning to migrate soon :) ) and the project has several hundred classes. The funcionality should ideally be used in the whole project, so switching every creation of an object by wrapping it is not an option. Would there be a way interally in PHP or ZendFramework 1 to intercept a call to a property or a function? – Felix Fischbach Jul 10 '20 at 13:07
  • And what about the deprecated methods themselves? Where are they located? Scattered around? Controllers/actions, helpers, services, custom classes? – waterloomatt Jul 10 '20 at 13:26
  • Good question. Now that I think about it the functionality is only really important for about 150 classes which inherit from the same base class as they are the only classes which external users can interact with. Does that help? We are using magic methods to access the properties, which should also be able to be deprecated. – Felix Fischbach Jul 10 '20 at 14:03
  • Using the magic method `__get` to access the properties makes it easy to detect when a specific property is annotated with `@deprecated`. Within `__get`, use reflection to inspect the annotation and do whatever you need to do. Doing this for methods or functions is a different beast entirely. The most common way I have seen is to change all methods to private/protected and then rely on `__call` to kick in, where you can hook into it. I have to point out that this adds significant overhead to your code. – waterloomatt Jul 10 '20 at 19:01
  • If you're only dealing with a few dozen methods, I'd just do it old skool and add some pre/post hooks/behaviours directly to the deprecated methods. – waterloomatt Jul 10 '20 at 19:03

0 Answers0