All Versions
26
Latest Version
Avg Release Cycle
87 days
Latest Release
1252 days ago

Changelog History
Page 3

  • v2.1.0 Changes

    November 30, 2016

    2.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

  • v2.0.4 Changes

    November 05, 2016

    ๐Ÿ— Build Status

    ๐Ÿ›  Fixed

    • โœ‚ Remove deprecated getMock usage from tests #325
    • ๐Ÿ›  Fix incorrect type in docs example #329
    • ๐Ÿ‘ _get method support in lazy loading value holders #344
    • ๐Ÿ›  Fix #344 - lazy loading value holder magic method support #345
  • v2.0.3 Changes

    July 01, 2016

    ๐Ÿ— Build Status

    2.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)
  • 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 when ReflectionProperty#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
  • 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 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.

    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.