Skip to content
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

AccessInterceptorValueHolder which proxies a parent __get triggers E_USER_NOTICE #759

Open
arjenm opened this issue May 6, 2022 · 0 comments
Labels

Comments

@arjenm
Copy link

arjenm commented May 6, 2022

When you generate a AccessInterceptorValueHolder proxy, a E_USER_NOTICE is always triggered when a property is not defined on the class, even if the that class has a __get-method.

This is caused by the getPublicAccessSimulationCode call here:

$callParent = PublicScopeSimulator::getPublicAccessSimulationCode(

And results in something like:

Notice: Undefined property: TestGet::$thisShouldNotGiveANotice in test.php on line ...

In contrast, the LazyLoadingValueHolder's __get-proxy does check for the parent and skips the call to getPublicAccessSimulationCode

And lastly the AccessInterceptorScopeLocalizer also doesn't give a notice about a undefined property (although it does cause, "Notice: Only variables should be assigned by reference")

Here is some test code:

use ProxyManager\Factory\AccessInterceptorScopeLocalizerFactory;
use ProxyManager\Factory\AccessInterceptorValueHolderFactory;
use ProxyManager\Factory\LazyLoadingValueHolderFactory;

error_reporting(E_ALL);

class TestGet {
    public string $notViaGet = 'not via __get';

    public function __get(string $name): string
    {
        return $name;
    }
}

// Class directly
// These don't give a notice
echo (new TestGet())->notViaGet, PHP_EOL;
echo (new TestGet())->thisShouldNotGiveANotice, PHP_EOL;

// LazyLoadingValueHolder
$lazyProxy = (new LazyLoadingValueHolderFactory())->createProxy(TestGet::class,
    function (&$wrappedObject, $proxy, $method, $parameters, &$initializer) {
        $wrappedObject = new TestGet();
        $initializer   = null;

        return true;
    }
);

// Neither do these
echo $lazyProxy->notViaGet, PHP_EOL;
echo $lazyProxy->thisShouldNotGiveANotice, PHP_EOL;

// AccessInterceptorValueHolder
$interceptorValueProxy = (new AccessInterceptorValueHolderFactory())->createProxy(
    new TestGet(),
);

// No notice
echo $interceptorValueProxy->notViaGet, PHP_EOL;
// But this one does give a notice: "Notice: Undefined property: TestGet::$thisShouldNotGiveANotice"
echo $interceptorValueProxy->thisShouldNotGiveANotice, PHP_EOL;

// AccessInterceptorScopeLocalizer
$interceptorScopeProxy = (new AccessInterceptorScopeLocalizerFactory())->createProxy(
    new TestGet(),
);

// This results in "Notice: Only variables should be assigned by reference"
echo '$interceptorScopeProxy->thisDoesNotGiveANotice', PHP_EOL;
@Ocramius Ocramius added the bug label May 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants