Within a class, is there a way to bind a class attribute to a method parameter so that a two-way link is established on Ctrl click?
class Attachments extends Repository { public Documents $documents; public function fromDocuments(callable $scope) { $this->scopeOnRepoProperty($scope, 'documents'); } }
What I mean is that in this case the second parameter documents in the scopeOnRepoProperty() method should refer to the property $documents.
The broader context is:
The problem is that a large part of the code is very similar, i.e. most scopeXXX/fromXXX methods do something similar, i.e. properties repository is passed as a parameter to the method. For example, in the above example, $scope($this->documents) would be executed; furthermore, if $this->documents was not initialized, a new instance would be created.
So the code looks like this:
public function fromDocuments(callable $scope) { if (!isset($this->documents)) { $this->documents = new Documents(); } $scope($this->documents); }
I wanted to avoid writing an if statement, creating a new object, and calling a method every time, so I thought I could do it with a method that would accept a callable object, a property name, and a type reflection class name.
The code runs fine, but unfortunately due to this approach I lose the binding to these properties. In previous versions, it was $this->documents, so the link was present, but that is no longer the case.
I would like to know if there is any way to achieve this. Any ideas?
This way the reference includes both the attribute and the class you want to use there. This is usually better than using a string representing both (and also losing references to concrete properties and concrete class names).
What you are doing here is also known as lazy initialization. The problem is that the new keyword is used in the class, making the code difficult to test. Still, this is an improvement over working with strings.
You may also be interested in the new @mixin in PhpStorm
This may allow you to omit the injection of the callable, but I'm not entirely clear on what exactly you are achieving with this method, so this is just an extra tip and may not suit your needs.
Reference: