PDF rausgenommen
This commit is contained in:
105
msd2/phpBB3/vendor/ocramius/proxy-manager/docs/access-interceptor-scope-localizer.md
vendored
Normal file
105
msd2/phpBB3/vendor/ocramius/proxy-manager/docs/access-interceptor-scope-localizer.md
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
# Access Interceptor Scope Localizer Proxy
|
||||
|
||||
An access interceptor scope localizer is a smart reference proxy that allows you to dynamically
|
||||
define logic to be executed before or after any of the proxied object's methods' logic.
|
||||
|
||||
It works exactly like the [access interceptor value holder](access-interceptor-value-holder.md),
|
||||
with some minor differences in behavior.
|
||||
|
||||
The working concept of an access interceptor scope localizer is to localize scope of a proxied object:
|
||||
|
||||
```php
|
||||
class Example
|
||||
{
|
||||
protected $foo;
|
||||
protected $bar;
|
||||
protected $baz;
|
||||
|
||||
public function doFoo()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
class ExampleProxy extends Example
|
||||
{
|
||||
public function __construct(Example $example)
|
||||
{
|
||||
$this->foo = & $example->foo;
|
||||
$this->bar = & $example->bar;
|
||||
$this->baz = & $example->baz;
|
||||
}
|
||||
|
||||
public function doFoo()
|
||||
{
|
||||
return parent::doFoo();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This allows to create a mirror copy of the real instance, where any change in the proxy or in the real
|
||||
instance is reflected in both objects.
|
||||
|
||||
The main advantage of this approach is that the proxy is now safe against fluent interfaces, which
|
||||
would break an [access interceptor value holder](access-interceptor-value-holder.md) instead.
|
||||
|
||||
## Differences with [access interceptor value holder](access-interceptor-value-holder.md):
|
||||
|
||||
* It does **NOT** implement the `ProxyManager\Proxy\ValueHolderInterface`, since the proxy itself
|
||||
does not keep a reference to the original object being proxied
|
||||
* In all interceptor methods (see [access interceptor value holder](access-interceptor-value-holder.md)),
|
||||
the `$instance` passed in is the proxy itself. There is no way to gather a reference to the
|
||||
original object right now, and that's mainly to protect from misuse.
|
||||
|
||||
## Known limitations
|
||||
|
||||
* It is **NOT** possible to intercept access to public properties
|
||||
* It is **NOT** possible to proxy interfaces, since this proxy relies on `parent::method()` calls.
|
||||
Interfaces obviously don't provide a parent method implementation.
|
||||
* calling `unset` on a property of an access interceptor scope localizer (or the real instance)
|
||||
will cause the two objects to be un-synchronized, with possible unexpected behaviour.
|
||||
* serializing or un-serializing an access interceptor scope localizer (or the real instance)
|
||||
will not cause the real instance (or the proxy) to be serialized or un-serialized
|
||||
* if a proxied object contains private properties, then an exception will be thrown if you use
|
||||
PHP `< 5.4.0`.
|
||||
|
||||
## Example
|
||||
|
||||
Here's an example of how you can create and use an access interceptor scope localizer :
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use ProxyManager\Factory\AccessInterceptorScopeLocalizerFactory as Factory;
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
class Foo
|
||||
{
|
||||
public function doFoo()
|
||||
{
|
||||
echo "Foo!\n";
|
||||
}
|
||||
}
|
||||
|
||||
$factory = new Factory();
|
||||
|
||||
$proxy = $factory->createProxy(
|
||||
new Foo(),
|
||||
array('doFoo' => function () { echo "PreFoo!\n"; }),
|
||||
array('doFoo' => function () { echo "PostFoo!\n"; })
|
||||
);
|
||||
|
||||
$proxy->doFoo();
|
||||
```
|
||||
|
||||
This send something like following to your output:
|
||||
|
||||
```
|
||||
PreFoo!
|
||||
Foo!
|
||||
PostFoo!
|
||||
```
|
||||
|
||||
This is pretty much the same logic that you can find
|
||||
in [access interceptor value holder](access-interceptor-value-holder.md).
|
108
msd2/phpBB3/vendor/ocramius/proxy-manager/docs/access-interceptor-value-holder.md
vendored
Normal file
108
msd2/phpBB3/vendor/ocramius/proxy-manager/docs/access-interceptor-value-holder.md
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
# Access Interceptor Value Holder Proxy
|
||||
|
||||
An access interceptor value holder is a smart reference proxy that allows you to dynamically
|
||||
define logic to 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](http://en.wikipedia.org/wiki/Aspect-oriented_programming) in general
|
||||
|
||||
## Example
|
||||
|
||||
Here's an example of how you can create and use an access interceptor value holder:
|
||||
|
||||
```php
|
||||
<?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(),
|
||||
array('doFoo' => function () { echo "PreFoo!\n"; }),
|
||||
array('doFoo' => function () { echo "PostFoo!\n"; })
|
||||
);
|
||||
|
||||
$proxy->doFoo();
|
||||
```
|
||||
|
||||
This send something like following to your output:
|
||||
|
||||
```
|
||||
PreFoo!
|
||||
Foo!
|
||||
PostFoo!
|
||||
```
|
||||
|
||||
## Implementing pre- and post- access interceptors
|
||||
|
||||
A proxy produced by the
|
||||
[`ProxyManager\Factory\AccessInterceptorValueHolderFactory`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Factory/AccessInterceptorValueHolderFactory.php)
|
||||
implements both the
|
||||
[`ProxyManager\Proxy\ValueHolderInterface`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Proxy/ValueHolderInterface.php)
|
||||
and the
|
||||
[`ProxyManager\Proxy\AccessInterceptorInterface`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Proxy/ValueHolderInterface.php).
|
||||
|
||||
Therefore, you can set an access interceptor callback by calling:
|
||||
|
||||
```php
|
||||
$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 following signature:
|
||||
|
||||
```php
|
||||
/**
|
||||
* @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 following signature:
|
||||
|
||||
```php
|
||||
/**
|
||||
* @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) {};
|
||||
```
|
||||
|
||||
## Tuning performance for production
|
||||
|
||||
See [Tuning ProxyManager for Production](https://github.com/Ocramius/ProxyManager/blob/master/docs/tuning-for-production.md).
|
16
msd2/phpBB3/vendor/ocramius/proxy-manager/docs/generator-strategies.md
vendored
Normal file
16
msd2/phpBB3/vendor/ocramius/proxy-manager/docs/generator-strategies.md
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
# Generator strategies
|
||||
|
||||
ProxyManager allows you to generate classes based on generator strategies and a
|
||||
given `Zend\Code\Generator\ClassGenerator` as of
|
||||
the [interface of a generator strategy](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/GeneratorStrategy/GeneratorStrategyInterface.php).
|
||||
|
||||
Currently, 3 generator strategies are shipped with ProxyManager:
|
||||
|
||||
* [`ProxyManager\GeneratorStrategy\BaseGeneratorStrategy`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/GeneratorStrategy/BaseGeneratorStrategy.php),
|
||||
which simply retrieves the string representation of the class from `ClassGenerator`
|
||||
* [`ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/GeneratorStrategy/EvaluatingGeneratorStrategy.php),
|
||||
which calls `eval()` upon the generated class code before returning it. This is useful in cases
|
||||
where you want to generate multiple classes at runtime
|
||||
* [`ProxyManager\GeneratorStrategy\FileWriterGeneratorStrategy`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/GeneratorStrategy/FileWriterGeneratorStrategy.php),
|
||||
which accepts a [`ProxyManager\FileLocator\FileLocatorInterface`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/FileLocator/FileLocatorInterface.php)
|
||||
instance as constructor parameter, and based on it, writes the generated class to a file before returning its code.
|
206
msd2/phpBB3/vendor/ocramius/proxy-manager/docs/lazy-loading-ghost-object.md
vendored
Normal file
206
msd2/phpBB3/vendor/ocramius/proxy-manager/docs/lazy-loading-ghost-object.md
vendored
Normal file
@ -0,0 +1,206 @@
|
||||
# Lazy Loading Ghost Object Proxies
|
||||
|
||||
A lazy loading ghost object proxy is a ghost proxy that looks exactly like the real instance of the proxied subject,
|
||||
but which has all properties nulled before initialization.
|
||||
|
||||
## Lazy loading with the Ghost Object
|
||||
|
||||
In pseudo-code, in userland, [lazy loading](http://www.martinfowler.com/eaaCatalog/lazyLoad.html) in a ghost object
|
||||
looks like following:
|
||||
|
||||
```php
|
||||
class MyObjectProxy
|
||||
{
|
||||
private $initialized = false;
|
||||
private $name;
|
||||
private $surname;
|
||||
|
||||
public function doFoo()
|
||||
{
|
||||
$this->init();
|
||||
|
||||
// Perform doFoo routine using loaded variables
|
||||
}
|
||||
|
||||
private function init()
|
||||
{
|
||||
if (! $this->initialized) {
|
||||
$data = some_logic_that_loads_data();
|
||||
|
||||
$this->name = $data['name'];
|
||||
$this->surname = $data['surname'];
|
||||
|
||||
$this->initialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Ghost objects work similarly to virtual proxies, but since they don't wrap around a "real" instance of the proxied
|
||||
subject, they are better suited for representing dataset rows.
|
||||
|
||||
## When do I use a ghost object?
|
||||
|
||||
You usually need a ghost object in cases where following applies
|
||||
|
||||
* you are building a small data-mapper and want to lazily load data across associations in your object graph
|
||||
* you want to initialize objects representing rows in a large dataset
|
||||
* you want to compare instances of lazily initialized objects without the risk of comparing a proxy with a real subject
|
||||
* you are aware of the internal state of the object and are confident in working with its internals via reflection
|
||||
or direct property access
|
||||
|
||||
## Usage examples
|
||||
|
||||
[ProxyManager](https://github.com/Ocramius/ProxyManager) provides a factory that creates lazy loading ghost objects.
|
||||
To use it, follow these steps:
|
||||
|
||||
First of all, define your object's logic without taking care of lazy loading:
|
||||
|
||||
```php
|
||||
namespace MyApp;
|
||||
|
||||
class Customer
|
||||
{
|
||||
private $name;
|
||||
private $surname;
|
||||
|
||||
// just write your business logic or generally logic
|
||||
// don't worry about how complex this object will be!
|
||||
// don't code lazy-loading oriented optimizations in here!
|
||||
public function getName() { return $this->name; }
|
||||
public function setName($name) { $this->name = (string) $name; }
|
||||
public function getSurname() { return $this->surname; }
|
||||
public function setSurname($surname) { $this->surname = (string) $surname; }
|
||||
}
|
||||
```
|
||||
|
||||
Then use the proxy manager to create a ghost object of it.
|
||||
You will be responsible of setting its state during lazy loading:
|
||||
|
||||
```php
|
||||
namespace MyApp;
|
||||
|
||||
use ProxyManager\Factory\LazyLoadingGhostFactory;
|
||||
use ProxyManager\Proxy\LazyLoadingInterface;
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
$factory = new LazyLoadingGhostFactory();
|
||||
$initializer = function (LazyLoadingInterface $proxy, $method, array $parameters, & $initializer) {
|
||||
$initializer = null; // disable initialization
|
||||
|
||||
// load data and modify the object here
|
||||
$proxy->setName('Agent');
|
||||
$proxy->setSurname('Smith');
|
||||
|
||||
return true; // confirm that initialization occurred correctly
|
||||
};
|
||||
|
||||
$instance = $factory->createProxy('MyApp\Customer', $initializer);
|
||||
```
|
||||
|
||||
You can now simply use your object as before:
|
||||
|
||||
```php
|
||||
// this will just work as before
|
||||
echo $proxy->getName() . ' ' . $proxy->getSurname(); // Agent Smith
|
||||
```
|
||||
|
||||
## Lazy Initialization
|
||||
|
||||
As you can see, we use a closure to handle lazy initialization of the proxy instance at runtime.
|
||||
The initializer closure signature for ghost objects should be as following:
|
||||
|
||||
```php
|
||||
/**
|
||||
* @var object $proxy the instance the ghost object proxy that is being initialized
|
||||
* @var string $method the name of the method that triggered lazy initialization
|
||||
* @var array $parameters an ordered list of parameters passed to the method that
|
||||
* triggered initialization, indexed by parameter name
|
||||
* @var Closure $initializer a reference to the property that is the initializer for the
|
||||
* proxy. Set it to null to disable further initialization
|
||||
*
|
||||
* @return bool true on success
|
||||
*/
|
||||
$initializer = function ($proxy, $method, $parameters, & $initializer) {};
|
||||
```
|
||||
|
||||
The initializer closure should usually be coded like following:
|
||||
|
||||
```php
|
||||
$initializer = function ($proxy, $method, $parameters, & $initializer) {
|
||||
$initializer = null; // disable initializer for this proxy instance
|
||||
|
||||
// modify the object with loaded data
|
||||
$proxy->setFoo(/* ... */);
|
||||
$proxy->setBar(/* ... */);
|
||||
|
||||
return true; // report success
|
||||
};
|
||||
```
|
||||
|
||||
The
|
||||
[`ProxyManager\Factory\LazyLoadingGhostFactory`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Factory/LazyLoadingGhostFactory.php)
|
||||
produces proxies that implement both the
|
||||
[`ProxyManager\Proxy\GhostObjectInterface`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Proxy/GhostObjectInterface.php)
|
||||
and the
|
||||
[`ProxyManager\Proxy\LazyLoadingInterface`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Proxy/LazyLoadingInterface.php).
|
||||
|
||||
At any point in time, you can set a new initializer for the proxy:
|
||||
|
||||
```php
|
||||
$proxy->setProxyInitializer($initializer);
|
||||
```
|
||||
|
||||
In your initializer, you **MUST** turn off any further initialization:
|
||||
|
||||
```php
|
||||
$proxy->setProxyInitializer(null);
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```php
|
||||
$initializer = null; // if you use the initializer passed by reference to the closure
|
||||
```
|
||||
|
||||
## Triggering Initialization
|
||||
|
||||
A lazy loading ghost object is initialized whenever you access any property or method of it.
|
||||
Any of the following interactions would trigger lazy initialization:
|
||||
|
||||
```php
|
||||
// calling a method
|
||||
$proxy->someMethod();
|
||||
|
||||
// reading a property
|
||||
echo $proxy->someProperty;
|
||||
|
||||
// writing a property
|
||||
$proxy->someProperty = 'foo';
|
||||
|
||||
// checking for existence of a property
|
||||
isset($proxy->someProperty);
|
||||
|
||||
// removing a property
|
||||
unset($proxy->someProperty);
|
||||
|
||||
// cloning the entire proxy
|
||||
clone $proxy;
|
||||
|
||||
// serializing the proxy
|
||||
$unserialized = unserialize(serialize($proxy));
|
||||
```
|
||||
|
||||
Remember to call `$proxy->setProxyInitializer(null);` to disable initialization of your proxy, or it will happen more
|
||||
than once.
|
||||
|
||||
## Proxying interfaces
|
||||
|
||||
You can also generate proxies from an interface FQCN. By proxying an interface, you will only be able to access the
|
||||
methods defined by the interface itself, even if the `wrappedObject` implements more methods. This will anyway save
|
||||
some memory since the proxy won't contain any properties.
|
||||
|
||||
## Tuning performance for production
|
||||
|
||||
See [Tuning ProxyManager for Production](https://github.com/Ocramius/ProxyManager/blob/master/docs/tuning-for-production.md).
|
202
msd2/phpBB3/vendor/ocramius/proxy-manager/docs/lazy-loading-value-holder.md
vendored
Normal file
202
msd2/phpBB3/vendor/ocramius/proxy-manager/docs/lazy-loading-value-holder.md
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
# Lazy Loading Value Holder Proxy
|
||||
|
||||
A lazy loading value holder proxy is a virtual proxy that wraps and lazily initializes a "real" instance of the proxied
|
||||
class.
|
||||
|
||||
## What is lazy loading?
|
||||
|
||||
In pseudo-code, in userland, [lazy loading](http://www.martinfowler.com/eaaCatalog/lazyLoad.html) looks like following:
|
||||
|
||||
```php
|
||||
class MyObjectProxy
|
||||
{
|
||||
private $wrapped;
|
||||
|
||||
public function doFoo()
|
||||
{
|
||||
$this->init();
|
||||
|
||||
return $this->wrapped->doFoo();
|
||||
}
|
||||
|
||||
private function init()
|
||||
{
|
||||
if (null === $this->wrapped) {
|
||||
$this->wrapped = new MyObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This code is problematic, and adds a lot of complexity that makes your unit tests' code even worse.
|
||||
|
||||
Also, this kind of usage often ends up in coupling your code with a particular
|
||||
[Dependency Injection Container](http://martinfowler.com/articles/injection.html)
|
||||
or a framework that fetches dependencies for you.
|
||||
That way, further complexity is introduced, and some problems related
|
||||
with service location raise, as I've explained
|
||||
[in this article](http://ocramius.github.com/blog/zf2-and-symfony-service-proxies-with-doctrine-proxies/).
|
||||
|
||||
Lazy loading value holders abstract this logic for you, hiding your complex, slow, performance-impacting objects behind
|
||||
tiny wrappers that have their same API, and that get initialized at first usage.
|
||||
|
||||
## When do I use a lazy value holder?
|
||||
|
||||
You usually need a lazy value holder in cases where following applies
|
||||
|
||||
* your object takes a lot of time and memory to be initialized (with all dependencies)
|
||||
* your object is not always used, and the instantiation overhead can be avoided
|
||||
|
||||
## Usage examples
|
||||
|
||||
[ProxyManager](https://github.com/Ocramius/ProxyManager) provides a factory that eases instantiation of lazy loading
|
||||
value holders. To use it, follow these steps:
|
||||
|
||||
First of all, define your object's logic without taking care of lazy loading:
|
||||
|
||||
```php
|
||||
namespace MyApp;
|
||||
|
||||
class HeavyComplexObject
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
// just write your business logic
|
||||
// don't worry about how heavy initialization of this will be!
|
||||
}
|
||||
|
||||
public function doFoo() {
|
||||
echo "OK!"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Then use the proxy manager to create a lazy version of the object (as a proxy):
|
||||
|
||||
```php
|
||||
namespace MyApp;
|
||||
|
||||
use ProxyManager\Factory\LazyLoadingValueHolderFactory;
|
||||
use ProxyManager\Proxy\LazyLoadingInterface;
|
||||
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
$factory = new LazyLoadingValueHolderFactory();
|
||||
$initializer = function (& $wrappedObject, LazyLoadingInterface $proxy, $method, array $parameters, & $initializer) {
|
||||
$initializer = null; // disable initialization
|
||||
$wrappedObject = new HeavyComplexObject(); // fill your object with values here
|
||||
|
||||
return true; // confirm that initialization occurred correctly
|
||||
};
|
||||
|
||||
$instance = $factory->createProxy('MyApp\HeavyComplexObject', $initializer);
|
||||
```
|
||||
|
||||
You can now simply use your object as before:
|
||||
|
||||
```php
|
||||
// this will just work as before
|
||||
$proxy->doFoo(); // OK!
|
||||
```
|
||||
|
||||
## Lazy Initialization
|
||||
|
||||
As you can see, we use a closure to handle lazy initialization of the proxy instance at runtime.
|
||||
The initializer closure signature should be as following:
|
||||
|
||||
```php
|
||||
/**
|
||||
* @var object $wrappedObject the instance (passed by reference) of the wrapped object,
|
||||
* set it to your real object
|
||||
* @var object $proxy the instance proxy that is being initialized
|
||||
* @var string $method the name of the method that triggered lazy initialization
|
||||
* @var string $parameters an ordered list of parameters passed to the method that
|
||||
* triggered initialization, indexed by parameter name
|
||||
* @var Closure $initializer a reference to the property that is the initializer for the
|
||||
* proxy. Set it to null to disable further initialization
|
||||
*
|
||||
* @return bool true on success
|
||||
*/
|
||||
$initializer = function (& $wrappedObject, $proxy, $method, $parameters, & $initializer) {};
|
||||
```
|
||||
|
||||
The initializer closure should usually be coded like following:
|
||||
|
||||
```php
|
||||
$initializer = function (& $wrappedObject, $proxy, $method, $parameters, & $initializer) {
|
||||
$newlyCreatedObject = new Foo(); // instantiation logic
|
||||
$newlyCreatedObject->setBar('baz') // instantiation logic
|
||||
$newlyCreatedObject->setBat('bam') // instantiation logic
|
||||
|
||||
$wrappedObject = $newlyCreatedObject; // set wrapped object in the proxy
|
||||
$initializer = null; // disable initializer
|
||||
|
||||
return true; // report success
|
||||
};
|
||||
```
|
||||
|
||||
The
|
||||
[`ProxyManager\Factory\LazyLoadingValueHolderFactory`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Factory/LazyLoadingValueHolderFactory.php)
|
||||
produces proxies that implement both the
|
||||
[`ProxyManager\Proxy\ValueHolderInterface`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Proxy/ValueHolderInterface.php)
|
||||
and the
|
||||
[`ProxyManager\Proxy\LazyLoadingInterface`](https://github.com/Ocramius/ProxyManager/blob/master/src/ProxyManager/Proxy/LazyLoadingInterface.php).
|
||||
|
||||
At any point in time, you can set a new initializer for the proxy:
|
||||
|
||||
```php
|
||||
$proxy->setProxyInitializer($initializer);
|
||||
```
|
||||
|
||||
In your initializer, you currently **MUST** turn off any further initialization:
|
||||
|
||||
```php
|
||||
$proxy->setProxyInitializer(null);
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```php
|
||||
$initializer = null; // if you use the initializer by reference
|
||||
```
|
||||
|
||||
## Triggering Initialization
|
||||
|
||||
A lazy loading proxy is initialized whenever you access any property or method of it.
|
||||
Any of the following interactions would trigger lazy initialization:
|
||||
|
||||
```php
|
||||
// calling a method
|
||||
$proxy->someMethod();
|
||||
|
||||
// reading a property
|
||||
echo $proxy->someProperty;
|
||||
|
||||
// writing a property
|
||||
$proxy->someProperty = 'foo';
|
||||
|
||||
// checking for existence of a property
|
||||
isset($proxy->someProperty);
|
||||
|
||||
// removing a property
|
||||
unset($proxy->someProperty);
|
||||
|
||||
// cloning the entire proxy
|
||||
clone $proxy;
|
||||
|
||||
// serializing the proxy
|
||||
$unserialized = serialize(unserialize($proxy));
|
||||
```
|
||||
|
||||
Remember to call `$proxy->setProxyInitializer(null);` to disable initialization of your proxy, or it will happen more
|
||||
than once.
|
||||
|
||||
## Proxying interfaces
|
||||
|
||||
You can also generate proxies from an interface FQCN. By proxying an interface, you will only be able to access the
|
||||
methods defined by the interface itself, even if the `wrappedObject` implements more methods. This will anyway save
|
||||
some memory since the proxy won't contain useless inherited properties.
|
||||
|
||||
## Tuning performance for production
|
||||
|
||||
See [Tuning ProxyManager for Production](https://github.com/Ocramius/ProxyManager/blob/master/docs/tuning-for-production.md).
|
89
msd2/phpBB3/vendor/ocramius/proxy-manager/docs/null-object.md
vendored
Normal file
89
msd2/phpBB3/vendor/ocramius/proxy-manager/docs/null-object.md
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
# Null Object Proxy
|
||||
|
||||
A Null Object proxy is a [null object pattern](http://en.wikipedia.org/wiki/Null_Object_pattern) implementation.
|
||||
The proxy factory creates a new object with defined neutral behavior based on an other object, class name or interface.
|
||||
|
||||
## What is null object proxy ?
|
||||
|
||||
In your application, when you can't return the object related to the request, the consumer of the model must check
|
||||
for the return value and handle the failing condition gracefully, thus generating an explosion of conditionals throughout your code.
|
||||
Fortunately, this seemingly-tangled situation can be sorted out simply by creating a polymorphic implementation of the
|
||||
domain object, which would implement the same interface as the one of the object in question, only that its methods
|
||||
wouldn’t do anything, therefore offloading client code from doing repetitive checks for ugly null values when the operation
|
||||
is executed.
|
||||
|
||||
## Usage examples
|
||||
|
||||
```php
|
||||
class UserMapper
|
||||
{
|
||||
private $adapter;
|
||||
|
||||
public function __construct(DatabaseAdapterInterface $adapter) {
|
||||
$this->adapter = $adapter;
|
||||
}
|
||||
|
||||
public function fetchById($id) {
|
||||
$this->adapter->select("users", array("id" => $id));
|
||||
if (!$row = $this->adapter->fetch()) {
|
||||
return null;
|
||||
}
|
||||
return $this->createUser($row);
|
||||
}
|
||||
|
||||
private function createUser(array $row) {
|
||||
$user = new Entity\User($row["name"], $row["email"]);
|
||||
$user->setId($row["id"]);
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you want to remove conditionals from client code, you need to have a version of the entity conforming to the corresponding
|
||||
interface. With the Null Object Proxy, you can build this object :
|
||||
|
||||
```php
|
||||
$factory = new \ProxyManager\Factory\NullObjectFactory();
|
||||
|
||||
$nullUser = $factory->createProxy('Entity\User');
|
||||
|
||||
var_dump($nullUser->getName()); // empty return
|
||||
```
|
||||
|
||||
You can now return a valid entity :
|
||||
|
||||
```php
|
||||
class UserMapper
|
||||
{
|
||||
private $adapter;
|
||||
|
||||
public function __construct(DatabaseAdapterInterface $adapter) {
|
||||
$this->adapter = $adapter;
|
||||
}
|
||||
|
||||
public function fetchById($id) {
|
||||
$this->adapter->select("users", array("id" => $id));
|
||||
return $this->createUser($this->adapter->fetch());
|
||||
}
|
||||
|
||||
private function createUser($row) {
|
||||
if (!$row) {
|
||||
$factory = new \ProxyManager\Factory\NullObjectFactory();
|
||||
|
||||
return $factory->createProxy('Entity\User');
|
||||
}
|
||||
$user = new Entity\User($row["name"], $row["email"]);
|
||||
$user->setId($row["id"]);
|
||||
return $user;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Proxying interfaces
|
||||
|
||||
You can also generate proxies from an interface FQCN. By proxying an interface, you will only be able to access the
|
||||
methods defined by the interface itself, and like with the object, the methods are empty.
|
||||
|
||||
## Tuning performance for production
|
||||
|
||||
See [Tuning ProxyManager for Production](https://github.com/Ocramius/ProxyManager/blob/master/docs/tuning-for-production.md).
|
100
msd2/phpBB3/vendor/ocramius/proxy-manager/docs/remote-object.md
vendored
Normal file
100
msd2/phpBB3/vendor/ocramius/proxy-manager/docs/remote-object.md
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
# Remote Object Proxy
|
||||
|
||||
The remote object implementation is a mechanism that enables an local object to control an other object on an other server.
|
||||
Each call method on the local object will do a network call to get information or execute operations on the remote object.
|
||||
|
||||
## What is remote object proxy ?
|
||||
|
||||
A remote object is based on an interface. The remote interface defines the API that a consumer can call. This interface
|
||||
must be implemented both by the client and the RPC server.
|
||||
|
||||
## Adapters
|
||||
|
||||
ZendFramework's RPC components (XmlRpc, JsonRpc & Soap) can be used easily with the remote object.
|
||||
You will need to require the one you need via composer, though:
|
||||
|
||||
```sh
|
||||
$ php composer.phar require zendframework/zend-xmlrpc:2.*
|
||||
$ php composer.phar require zendframework/zend-json:2.*
|
||||
$ php composer.phar require zendframework/zend-soap:2.*
|
||||
```
|
||||
|
||||
ProxyManager comes with 3 adapters:
|
||||
|
||||
* `ProxyManager\Factory\RemoteObject\Adapter\XmlRpc`
|
||||
* `ProxyManager\Factory\RemoteObject\Adapter\JsonRpc`
|
||||
* `ProxyManager\Factory\RemoteObject\Adapter\Soap`
|
||||
|
||||
## Usage examples
|
||||
|
||||
RPC server side code (`xmlrpc.php` in your local webroot):
|
||||
|
||||
```php
|
||||
interface FooServiceInterface
|
||||
{
|
||||
public function foo();
|
||||
}
|
||||
|
||||
class Foo implements FooServiceInterface
|
||||
{
|
||||
/**
|
||||
* Foo function
|
||||
* @return string
|
||||
*/
|
||||
public function foo()
|
||||
{
|
||||
return 'bar remote';
|
||||
}
|
||||
}
|
||||
|
||||
$server = new Zend\XmlRpc\Server();
|
||||
$server->setClass('Foo', 'FooServiceInterface'); // my FooServiceInterface implementation
|
||||
$server->handle();
|
||||
```
|
||||
|
||||
Client side code (proxy) :
|
||||
|
||||
```php
|
||||
|
||||
interface FooServiceInterface
|
||||
{
|
||||
public function foo();
|
||||
}
|
||||
|
||||
$factory = new \ProxyManager\Factory\RemoteObjectFactory(
|
||||
new \ProxyManager\Factory\RemoteObject\Adapter\XmlRpc(
|
||||
new \Zend\XmlRpc\Client('https://localhost/xmlrpc.php')
|
||||
)
|
||||
);
|
||||
|
||||
$proxy = $factory->createProxy('FooServiceInterface');
|
||||
|
||||
var_dump($proxy->foo()); // "bar remote"
|
||||
```
|
||||
|
||||
## Implementing custom adapters
|
||||
|
||||
Your adapters must implement `ProxyManager\Factory\RemoteObject\AdapterInterface` :
|
||||
|
||||
```php
|
||||
interface AdapterInterface
|
||||
{
|
||||
/**
|
||||
* Call remote object
|
||||
*
|
||||
* @param string $wrappedClass
|
||||
* @param string $method
|
||||
* @param array $params
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function call($wrappedClass, $method, array $params = array());
|
||||
}
|
||||
```
|
||||
|
||||
It is very easy to create your own implementation (for RESTful web services, for example). Simply pass
|
||||
your own adapter instance to your factory at construction time
|
||||
|
||||
## Tuning performance for production
|
||||
|
||||
See [Tuning ProxyManager for Production](https://github.com/Ocramius/ProxyManager/blob/master/docs/tuning-for-production.md).
|
24
msd2/phpBB3/vendor/ocramius/proxy-manager/docs/tuning-for-production.md
vendored
Normal file
24
msd2/phpBB3/vendor/ocramius/proxy-manager/docs/tuning-for-production.md
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
## Tuning the ProxyManager for production
|
||||
|
||||
By default, all proxy factories generate the required proxy classes at runtime.
|
||||
|
||||
Proxy generation causes I/O operations and uses a lot of reflection, so be sure to have
|
||||
generated all of your proxies **before deploying your code on a live system**, or you
|
||||
may experience poor performance.
|
||||
|
||||
You can configure ProxyManager so that it will try autoloading the proxies first.
|
||||
Generating them "bulk" is not yet implemented:
|
||||
|
||||
```php
|
||||
$config = new \ProxyManager\Configuration();
|
||||
$config->setProxiesTargetDir(__DIR__ . '/my/generated/classes/cache/dir');
|
||||
|
||||
// then register the autoloader
|
||||
spl_autoload_register($config->getProxyAutoloader());
|
||||
```
|
||||
|
||||
Generating a classmap with all your proxy classes in it will also work perfectly.
|
||||
|
||||
Please note that all the currently implemented `ProxyManager\Factory\*` classes accept
|
||||
a `ProxyManager\Configuration` object as optional constructor parameter. This allows for
|
||||
fine-tuning of ProxyManager according to your needs.
|
Reference in New Issue
Block a user