Changelog History
Page 3
-
v2.1.0 Changes
November 30, 20162.1.0
๐ Improved
- ๐ Introduced support for PHP 7.1,
void
and nullable (?
)
types #314
#327 - โ The test suite is now fully CI-covered by mutation testing #348
- ๐ Moved all performance testing to PHPBench #326
- ๐ PHP 7.0 support dropped #327
Total issues resolved: 9
- 290: Branch-alias version bump: master bump to 3.0.x
- 314: Nullable params type
- ๐ 326: Moved performance tests to phpbench-based suite
- ๐ 327: PHP 7.1 support
- ๐ 336: Hotfix tests for php 7 support
- 339: Provided type ?... is invalid
- 343: Fix typo in ghost objects lazy loading code example
- โ 348: Introduced full mutation testing
- 349: install xdebug manually for php 7.1
- ๐ Introduced support for PHP 7.1,
-
v2.0.3 Changes
July 01, 20162.0.3
๐ Fixed
- โ
Various test suite cleanups, mostly because of
๐ new PHPUnit 5.4.0 deprecations being introduced
#318 - โ Removed
zendframework/zend-code:3.0.3
from installable dependencies, since
๐ a critical bug was introduced in it #321
#323
โฌ๏ธ #324. Please upgrade to
zendframework/zend-code:3.0.4
or newer.
Total issues resolved: 4
- ๐ 318: Cleanup: remove unused imports, deprecated method usage, static/non-static assertion mixup
- 321: Syntax error, unexpected '' (T_NS_SEPARATOR) when using Zend-Code 3.0.3
- 323: Excluding
zendframework/zend-code
3.0.3
from compatible dependencies - 324: Excluding
zendframework/zend-code
3.0.3
from compatible dependencies (2.0.x backport)
- โ
Various test suite cleanups, mostly because of
-
v2.0.2 Changes
๐ Fixed
- ๐ฆ Various optimizations were performed in the
ocramius/package-versions
integration in order to prevent "class not found" fatals. #294 - Null objects produced via a given class name were not extending from the given class name, causing obvious LSP compliance and type-compatibility issues. #300 #301
- ๐ Specific installation versions were removed from the [README.md](README.md) install instructions, since composer is installing the latest available version by default. #305
- ๐ PHP 7.0.6 support was dropped. PHP 7.0.6 includes some nasty reflection bugs that caused
__isset
to be called whenReflectionProperty#getValue()
is used (https://bugs.php.net/72174). #306 #308 - PHP 7.0.7 contains additional limitations as to when
$this
can be used. Specifically,$this
cannot be used as a parameter name for closures that have an already assigned$this
. Due to$this
being incorrectly used as parameter name within this library, running ProxyManager on PHP 7.0.7 would have caused a fatal error. #306 #308 #316 - PHP 7.1.0-DEV includes type-checks for incompatible arithmetic operations: some of those operations were erroneously performed in the library internals. #308
- ๐ฆ Various optimizations were performed in the
-
v2.0.1 Changes
๐ Fixed
- โ Travis-CI environment was fixed to test the library using the minimum dependencies version.
โ Added
- โ Added unit test to make sure that properties skipped should be preserved even being cloned.
-
v2.0.0 Changes
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:
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
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:
class SayHello { public function hello(string ...$names) : string { return 'hello, ' . implode(', ', $names); } }
๐ By-ref variadic arguments are also supported:
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.
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 evenprotected
andprivate
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.
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:
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:
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"
0๏ธโฃ 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.