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

Docs - #272 - document 2.0.0 changes #287

Merged
merged 23 commits into from
Jan 29, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
67554e0
Class over string reference
Ocramius Jan 28, 2016
c8f2c90
Adding basic changelog
Ocramius Jan 28, 2016
c8b1669
Linking changelog in the docs footer
Ocramius Jan 28, 2016
2af5acc
#272 - Documenting support for return type hints
Ocramius Jan 28, 2016
5d2b27d
#272 - Documenting PHP7 compatibility
Ocramius Jan 28, 2016
7a9ab64
#272 - Documenting PHP7 scalar type hints support
Ocramius Jan 28, 2016
3b1294b
#272 - Documenting variadic arguments support
Ocramius Jan 28, 2016
6e4204e
#272 - Documenting by-ref variadic arguments support
Ocramius Jan 28, 2016
f24e60d
#272 - Removing redundant note about factories supporting the new sig…
Ocramius Jan 28, 2016
410cd0c
#272 - Documenting respected constructor LSP compliance
Ocramius Jan 28, 2016
85fca38
#272 - Titles corrections
Ocramius Jan 28, 2016
c5f9ec4
#272 - Documenting support of friend classes
Ocramius Jan 28, 2016
1d2e89b
#272 - Documenting `staticProxyConstructor` existence
Ocramius Jan 28, 2016
45d11bf
#272 - Documenting lazy loading ghost object state-based initialization
Ocramius Jan 28, 2016
d40b745
#272 - Documenting new proxy by-ref initialization system
Ocramius Jan 28, 2016
6bf00cf
#272 - Class over string reference
Ocramius Jan 28, 2016
65358ec
#272 - Example of ghost object skipped properties
Ocramius Jan 28, 2016
bf84e8c
#272 - Adding skipped properties examples to travis run
Ocramius Jan 28, 2016
a04c2d2
#272 - Documenting new skipped properties behavior
Ocramius Jan 28, 2016
c5fcda0
#272 - Linking BC breaks
Ocramius Jan 28, 2016
28db889
#272 - Proxies are now generated by default
Ocramius Jan 28, 2016
e33915f
#272 - Documenting changes in the proxy hashing/signature
Ocramius Jan 28, 2016
9e02baa
#272 - PHP 4 constructors are no longer supported
Ocramius Jan 28, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ script:
- echo "Running examples"
- php examples/access-interceptor-scope-localizer.php
- php examples/ghost-object.php
- php examples/ghost-object-skipped-properties.php
- php examples/smart-reference.php
- php examples/virtual-proxy.php
- ./vendor/bin/phpcs --standard=PSR2 ./src/ ./tests/
Expand Down
283 changes: 283 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
---
title: Changelog
---

This is a list of changes/improvements that were introduced in ProxyManager

## 2.0.0

### BC Breaks

Please refer to [the upgrade documentation](UPGRADE.md) to see which backwards-incompatible
changes were applied to this release.

### New features

#### PHP 7 support

ProxyManager will now correctly operate in PHP 7 environments.

#### PHP 7 Return type hints

ProxyManager will now correctly mimic signatures of methods with return type hints:

```php
class SayHello
{
public function hello() : string
{
return 'hello!';
}
}
```

#### PHP 7 Scalar type hints

ProxyManager will now correctly mimic signatures of methods with scalar type hints

```php
class SayHello
{
public function hello(string $name) : string
{
return 'hello, ' . $name;
}
}
```

#### PHP 5.6 Variadics support

ProxyManager will now correctly mimic behavior of methods with variadic parameters:

```php
class SayHello
{
public function hello(string ...$names) : string
{
return 'hello, ' . implode(', ', $names);
}
}
```

By-ref variadic arguments are also supported:

```php
class SayHello
{
public function hello(string ... & $names)
{
foreach ($names as & $name) {
$name = 'hello, ' . $name;
}
}
}
```

#### Constructors in proxies are not replaced anymore

In ProxyManager v1.x, the constructor of a proxy was completely replaced with a method
accepting proxy-specific parameters.

This is no longer true, and you will be able to use the constructor of your objects as
if the class wasn't proxied at all:

```php
class SayHello
{
public function __construct()
{
echo 'Hello!';
}
}

/* @var $proxyGenerator \ProxyManager\ProxyGenerator\ProxyGeneratorInterface */
$proxyClass = $proxyGenerator->generateProxy(
new ReflectionClass(SayHello::class),
new ClassGenerator('ProxyClassName')
);

eval('<?php ' . $proxyClass->generate());

$proxyName = $proxyClass->getName();
$object = new ProxyClassName(); // echoes "Hello!"

var_dump($object); // a proxy object
```

If you still want to manually build a proxy (without factories), a
`public static staticProxyConstructor` method is added to the generated proxy classes.

#### Friend classes support

You can now access state of "friend objects" at any time.

```php
class EmailAddress
{
private $address;

public function __construct(string $address)
{
assertEmail($address);

$this->address = $address;
}

public function equalsTo(EmailAddress $other)
{
return $this->address === $other->address;
}
}
```

When using lazy-loading or access-interceptors, the `equalsTo` method will
properly work, as even `protected` and `private` access are now correctly proxied.

#### Ghost objects now only lazy-load on state-access

Lazy loading ghost objects now trigger lazy-loading only when their state is accessed.
This also implies that lazy loading ghost objects cannot be used with interfaces anymore.

```php
class AccessPolicy
{
private $policyName;

/**
* Calling this method WILL cause lazy-loading, when using a ghost object,
* as the method is accessing the object's state
*/
public function getPolicyName() : string
{
return $this->policyName;
}

/**
* Calling this method WILL NOT cause lazy-loading, when using a ghost object,
* as the method is not reading any from the object.
*/
public function allowAccess() : bool
{
return false;
}
}
```

#### Faster ghost object state initialization

Lazy loading ghost objects can now be initialized in a more efficient way, by avoiding
reflection or setters:

```php
class Foo
{
private $a;
protected $b;
public $c;
}

$factory = new \ProxyManager\Factory\LazyLoadingGhostFactory();

$proxy = $factory-createProxy(
Foo::class,
function (
GhostObjectInterface $proxy,
string $method,
array $parameters,
& $initializer,
array $properties
) {
$initializer = null;

$properties["\0Foo\0a"] = 'abc';
$properties["\0*\0b"] = 'def';
$properties['c'] = 'ghi';

return true;
}
);


$reflectionA = new ReflectionProperty(Foo::class, 'a');
$reflectionA->setAccessible(true);

var_dump($reflectionA->getValue($proxy)); // dumps "abc"

$reflectionB = new ReflectionProperty(Foo::class, 'b');
$reflectionB->setAccessible(true);

var_dump($reflectionB->getValue($proxy)); // dumps "def"

var_dump($proxy->c); // dumps "ghi"
```

#### Skipping lazy-loaded properties in generated proxies

Lazy loading ghost objects can now skip lazy-loading for certain properties.
This is especially useful when you have properties that are always available,
such as identifiers of entities:

```php
class User
{
private $id;
private $username;

public function getId() : int
{
return $this->id;
}

public function getUsername() : string
{
return $this->username;
}
}

/* @var $proxy User */
$proxy = (new \ProxyManager\Factory\LazyLoadingGhostFactory())->createProxy(
User::class,
function (
GhostObjectInterface $proxy,
string $method,
array $parameters,
& $initializer,
array $properties
) {
$initializer = null;

var_dump('Triggered lazy-loading!');

$properties["\0User\0username"] = 'Ocramius';

return true;
},
[
'skippedProperties' => [
"\0User\0id",
],
]
);

$idReflection = new \ReflectionProperty(User::class, 'id');

$idReflection->setAccessible(true);
$idReflection->setValue($proxy, 123);

var_dump($proxy->getId()); // 123
var_dump($proxy->getUsername()); // "Triggered lazy-loading!", then "Ocramius"
```

#### Proxies are now always generated on-the-fly by default

Proxies are now automatically generated any time you require them: no configuration
needed. If you want to gain better performance, you may still want to read
the [tuning for production docs](docs/tuning-for-production.md).

#### Proxy names are now hashed, simplified signature is attached to them

Proxy classes now have shorter names, as the parameters used to generate them are
hashed into their name. A signature is attached to proxy classes (as a private static
property) so that proxy classes aren't re-used across library updates.
Upgrading ProxyManager will now cause all proxies to be re-generated automatically,
while the old proxy files are going to be ignored.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Here's how you build a lazy loadable object with ProxyManager using a *Virtual P
$factory = new \ProxyManager\Factory\LazyLoadingValueHolderFactory();

$proxy = $factory->createProxy(
'MyApp\HeavyComplexObject',
\MyApp\HeavyComplexObject::class,
function (& $wrappedObject, $proxy, $method, $parameters, & $initializer) {
$wrappedObject = new HeavyComplexObject(); // instantiation logic here
$initializer = null; // turning off further lazy initialization
Expand Down
1 change: 1 addition & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ This is a list of backwards compatibility (BC) breaks introduced in ProxyManager
* Private properties are now also correctly handled by ProxyManager: accessing proxy state via friend classes
(protected or private scope) does not require any particular workarounds anymore.
* `ProxyManager\Version::VERSION` was removed. Please use `ProxyManager\Version::getVersion()` instead.
* PHP 4 style constructors are no longer supported

# 1.0.0

Expand Down
1 change: 1 addition & 0 deletions doc-template/default.twig
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
<ul>
<li><a href="{{ baseUrl }}/stability.html">Stability</a> | </li>
<li><a href="{{ baseUrl }}/upgrade.html">Upgrade Notes</a> | </li>
<li><a href="{{ baseUrl }}/changelog.html">Changelog</a> | </li>
<li><a href="{{ baseUrl }}/contributing.html">Contributing</a> | </li>
<li><a href="{{ baseUrl }}/docs/credits.html">Credits</a> | </li>
<li><a href="{{ baseUrl }}/docs/copyright.html">Copyright</a></li>
Expand Down
51 changes: 51 additions & 0 deletions examples/ghost-object-skipped-properties.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

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

use ProxyManager\Factory\LazyLoadingGhostFactory;
use ProxyManager\Proxy\GhostObjectInterface;

class User
{
private $id;
private $username;

public function getId() : int
{
return $this->id;
}

public function getUsername() : string
{
return $this->username;
}
}

/* @var $proxy User */
$proxy = (new LazyLoadingGhostFactory())->createProxy(
User::class,
function (GhostObjectInterface $proxy, string $method, array $parameters, & $initializer, array $properties) {
$initializer = null;

var_dump('Triggered lazy-loading!');

$properties["\0User\0username"] = 'Ocramius';

return true;
},
[
'skippedProperties' => [
"\0User\0id",
],
]
);

$idReflection = new \ReflectionProperty(User::class, 'id');

$idReflection->setAccessible(true);
$idReflection->setValue($proxy, 123);

var_dump($proxy->getId());
var_dump($proxy->getUsername());
2 changes: 1 addition & 1 deletion examples/ghost-object.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public function getFoo() : string

for ($i = 0; $i < 1000; $i += 1) {
$proxy = $factory->createProxy(
'Foo',
Foo::class,
function (GhostObjectInterface $proxy, string $method, array $parameters, & $initializer, array $properties) {
$initializer = null;

Expand Down
2 changes: 1 addition & 1 deletion examples/remote-proxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function bar() : string
$factory = new RemoteObjectFactory(
new XmlRpc(new Client('http://localhost:9876/remote-proxy/remote-proxy-server.php'))
);
$proxy = $factory->createProxy('Foo');
$proxy = $factory->createProxy(Foo::class);

try {
var_dump($proxy->bar()); // bar remote !
Expand Down
2 changes: 1 addition & 1 deletion examples/virtual-proxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function doFoo()

for ($i = 0; $i < 1000; $i += 1) {
$proxy = $factory->createProxy(
'Foo',
Foo::class,
function (& $wrappedObject, $proxy, $method, $parameters, & $initializer) {
$initializer = null;
$wrappedObject = new Foo();
Expand Down