Skip to content

Latest commit

 

History

History
109 lines (82 loc) · 3.83 KB

access-interceptor-value-holder.md

File metadata and controls

109 lines (82 loc) · 3.83 KB

Access Interceptor Value Holder Proxy

An access interceptor value holder is a smart reference proxy that allows you to dynamically define the logic that will be executed before or after any of the wrapped object's methods logic.

It wraps around a real instance of the object to be proxied and can be useful for things like:

  • caching execution of slow and heavy methods
  • log method calls
  • debugging
  • event triggering
  • handling of orthogonal logic, and AOP in general

Example

Here's an example of how you can create and use an access interceptor value holder:

<?php

use ProxyManager\Factory\AccessInterceptorValueHolderFactory as Factory;

require_once __DIR__ . '/vendor/autoload.php';

class Foo
{
    public function doFoo()
    {
        echo "Foo!\n";
    }
}

$factory = new Factory();

$proxy = $factory->createProxy(
    new Foo(),
    ['doFoo' => function () { echo "PreFoo!\n"; }],
    ['doFoo' => function () { echo "PostFoo!\n"; }]
);

$proxy->doFoo();

This sends something like following to your output:

PreFoo!
Foo!
PostFoo!

Implementing pre- and post- access interceptors

A proxy produced by the ProxyManager\Factory\AccessInterceptorValueHolderFactory implements the ProxyManager\Proxy\AccessInterceptorValueHolderInterface.

Therefore, you can set an access interceptor callback by calling:

$proxy->setMethodPrefixInterceptor('methodName', function () { echo 'pre'; });
$proxy->setMethodSuffixInterceptor('methodName', function () { echo 'post'; });

You can also listen to public properties access by attaching interceptors to __get, __set, __isset and __unset.

A prefix interceptor (executed before method logic) should have the following signature:

/**
 * @var object $proxy       the proxy that intercepted the method call
 * @var object $instance    the wrapped instance within the proxy
 * @var string $method      name of the called method
 * @var array  $params      sorted array of parameters passed to the intercepted
 *                          method, indexed by parameter name
 * @var bool   $returnEarly flag to tell the interceptor proxy to return early, returning
 *                          the interceptor's return value instead of executing the method logic
 *
 * @return mixed
 */
$prefixInterceptor = function ($proxy, $instance, $method, $params, & $returnEarly) {};

A suffix interceptor (executed after method logic) should have the following signature:

/**
 * @var object $proxy       the proxy that intercepted the method call
 * @var object $instance    the wrapped instance within the proxy
 * @var string $method      name of the called method
 * @var array  $params      sorted array of parameters passed to the intercepted
 *                          method, indexed by parameter name
 * @var mixed  $returnValue the return value of the intercepted method
 * @var bool   $returnEarly flag to tell the proxy to return early, returning the interceptor's
 *                          return value instead of the value produced by the method
 *
 * @return mixed
 */
$suffixInterceptor = function ($proxy, $instance, $method, $params, $returnValue, & $returnEarly) {};

Known limitations

  • methods using func_get_args(), func_get_arg() and func_num_arg() will not function properly for parameters that are not part of the proxied object interface: use variadic arguments instead.

Tuning performance for production

See Tuning ProxyManager for Production.