flow-development-collection icon indicating copy to clipboard operation
flow-development-collection copied to clipboard

Don't proxies for classes that don't need it

Open bwaidelich opened this issue 6 years ago • 2 comments

Flow creates a proxy class for every PHP class of a package with enabled object management (all Flow packages by default).

This allows the corresponding class to use annotation based Dependency Injection and to be targeted by AOP aspects

Instead a proxy class should only be generated if it is really needed (= class uses DI or is targetted by AOP aspects).

Background

The reason for this feature is (apart from performance) that certain construct don't work with proxy classes. For example the following code

<?php
final class SomeClass
{
    private function __construct(string $foo)
    {
        // ...
    }
}

leads to the proxy class code

final class SomeClass extends SomeClass_Original implements \Neos\Flow\ObjectManagement\Proxy\ProxyInterface {

    // ...

    public function __construct()
    {
        $arguments = func_get_args();
        if (!array_key_exists(0, $arguments)) throw new \Neos\Flow\ObjectManagement\Exception\UnresolvedDependenciesException('Missing required constructor argument $foo in class ' . __CLASS__ . '. Note that constructor injection is only support for objects of scope singleton (and this is not a singleton) – for other scopes you must pass each required argument to the constructor yourself.', 1296143788);
        call_user_func_array('parent::__construct', $arguments);
    }
    // ...
}

bwaidelich avatar Apr 08 '19 07:04 bwaidelich

generally yes please, I just thought this might feel rather weird if you add something that requires a proxy and it breaks then suddenly...

I think implementation could be relatively easy as the \Neos\Flow\ObjectManagement\Proxy\ProxyClass knows if there are any proxied methods, added traits, properties or interfaces, which should be all that is needed.

kitsunet avatar Apr 08 '19 07:04 kitsunet

That would be cool indeed. A lot less useless proxy classes and breaking for non-DI/AOP cases.

albe avatar Apr 10 '19 18:04 albe

Have a first prototype going, so far mostly for objects with only simple type properties, but I can see more options there.

kitsunet avatar Feb 21 '23 08:02 kitsunet

A little summary at this point:

I developed a few improvements which are currently under review. I tested my biggest application – Flownative Beach – using that updated code base and removed all (> 100) Proxy(false) annotations from my code.

Using Flow 8.3 – without these patches and with the > 100 Proxy(false) annotations – I found 1354 proxy classes in my cache directory.

Using Flow 9.0 dev – with these patches and without Proxy(false) – it's only 727 proxy classes. And as far as I can see, all of them are justified, because they need DI or AOP.

Therefore, if the mentioned PRs are merged I guess that we can close this issue for now.

robertlemke avatar May 16 '23 07:05 robertlemke