-
-
Notifications
You must be signed in to change notification settings - Fork 188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proxy->__destruct called although service's __construct() was never called #373
Comments
As already described in the issues above, this library cannot make any assumptions about the behavior of
I don't force anything - the library is agnostic, and it will try honoring the initial behavior as much as possible. As a workaround, I suggest implementing an intermediate class that doesn't implement |
Just adding an example of how this would work, since this hackery would be EXTREMELY complex to add at ProxyManager level: class MyRedis
{
public function __construct(string $dsn) { /* connect to redis here */ }
public function doSomething() { /* interact with redis here */ }
public function __destruct() { /* disconnect here */ }
}
class MyRedisWithoutSillyConstruct extends MyRedis
{
public function __construct(MyRedis $originalInstance) { $this->originalInstance = $originalInstance; }
public function doSomething() { return $this->originalInstance->doSomething(); }
// no constructor
}
$lazyService = $factory->createProxy(MyRedisWithoutSillyConstruct::class, ...); |
Yes, I understand your point. But Am I totally wrong with the assumption that the proxy is instantiated as placeholder for the real service until the real service is requested and therefor instantiated? So in a real world without the proxy mechanism the |
Does it? A lot of stuff like session handling, profiling, etc uses
That's what every proxy implementing the
In most cases, yes, you probably don't want initialization via |
Yes it is. But only on an concrete instance. The destruct is invoked by PHP on every object which is not referenced anymore or at the script shutdown.
Yes, but the proxy pattern adds the logic that a target service will not be instantiated until it's used. So I can argument that the proxy library does exactly what you not want, execute behavior that would not be executed without the proxy. Yes, I agree to you that the proxy needs to be equivalent to the target service but it needs to be equivalent in the way of usage as well, what means that if I don't instantiate the service then my |
A profiler may need to run and be initialized after all headers have been sent. Same for an error handler/collector. A perfectly valid example of this could be following: class Profiler {
public function __construct(PDO $db) { ... }
public function profile($something) { ... }
public function __destruct() {
$this->db->insert($this->profileMetadata());
$this->db->insert($this->getAccumulatedProfiles());
}
} $profiler = $proxyFactory->create(Profiler::class, function () {
return new Profiler(connect_to_profiler_db();
});;
(new App($profiler))->run(); This will either initialize the profiler at runtime, when the application does something with it, or in any case at I can't agree that the above is good code (I don't think it is), but it is real-world code that works with this library (I've seen it done before too).
Your service is ALWAYS used at The workaround I proposed above (implementing a middle-man class), is basically telling PHP that |
No. Only if I did class MyService
{
public function __construct(){}
function __destruct(){}
}
$myServiceProxy = $proxyFactory->create(MyService::class, function () {
return new MyService();
});
(new App())->run(); This would force |
You did |
Ok, I think I got your point now. But I unterstand why you say that it's necessary that the __destruct() at least invokes the Thank you for the long discussion. |
@cjost1988 no worries! Thanks for your understanding: I considered adding a flag to ProxyManager before, but the solution provided above is simpler and easier to understand too. |
@Ocramius We've also talked about the possibility to add an additional flag to enable skipping But for now, we write a custom adapter which handles the expected proxy behavior. Have a nice day. |
Hey,
as I can see there were some issues regarding the
proxy->__destruct()
reported before. I am running into the same issues like mentioned there.An external service establishes connections on instance construction. Everything is fine until the proxy->__destruct() is invoked that itself forces instantiation of the service although it's not needed.
Is there any specific reason that you force instantiation of the proxied service on __destruct()?
In my point of view that means additional performance costs that are not wanted - just creating the instance reserves additional memory. With this behavior you force the developers to not load data or establish connections on construction if they want to avoid the addition performance overhead.
cheers,
Chris
The text was updated successfully, but these errors were encountered: