pax_global_header 0000666 0000000 0000000 00000000064 13762423633 0014523 g ustar 00root root 0000000 0000000 52 comment=2870b3622b8f47eafbc8df5f70f3d0c29e1f53af
php-doctrine-instantiator-1.4.0/ 0000775 0000000 0000000 00000000000 13762423633 0016636 5 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/.doctrine-project.json 0000664 0000000 0000000 00000001604 13762423633 0023063 0 ustar 00root root 0000000 0000000 {
"active": true,
"name": "Instantiator",
"slug": "instantiator",
"docsSlug": "doctrine-instantiator",
"codePath": "/src",
"versions": [
{
"name": "1.4",
"branchName": "master",
"slug": "latest",
"upcoming": true
},
{
"name": "1.3",
"branchName": "1.3.x",
"slug": "1.3",
"aliases": [
"current",
"stable"
],
"maintained": true,
"current": true
},
{
"name": "1.2",
"branchName": "1.2.x",
"slug": "1.2"
},
{
"name": "1.1",
"branchName": "1.1.x",
"slug": "1.1"
},
{
"name": "1.0",
"branchName": "1.0.x",
"slug": "1.0"
}
]
}
php-doctrine-instantiator-1.4.0/.github/ 0000775 0000000 0000000 00000000000 13762423633 0020176 5 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/.github/FUNDING.yml 0000664 0000000 0000000 00000000173 13762423633 0022014 0 ustar 00root root 0000000 0000000 patreon: phpdoctrine
tidelift: packagist/doctrine%2Finstantiator
custom: https://www.doctrine-project.org/sponsorship.html
php-doctrine-instantiator-1.4.0/.github/workflows/ 0000775 0000000 0000000 00000000000 13762423633 0022233 5 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/.github/workflows/coding-standards.yml 0000664 0000000 0000000 00000002202 13762423633 0026176 0 ustar 00root root 0000000 0000000
name: "Coding Standards"
on:
pull_request:
branches:
- "*.x"
push:
branches:
- "*.x"
env:
COMPOSER_ROOT_VERSION: "1.4"
jobs:
coding-standards:
name: "Coding Standards"
runs-on: "ubuntu-20.04"
strategy:
matrix:
php-version:
- "7.4"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "${{ matrix.php-version }}"
tools: "cs2pr"
- name: "Cache dependencies installed with Composer"
uses: "actions/cache@v2"
with:
path: "~/.composer/cache"
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
- name: "Install dependencies with Composer"
run: "composer install --no-interaction --no-progress"
# https://github.com/doctrine/.github/issues/3
- name: "Run PHP_CodeSniffer"
run: "vendor/bin/phpcs -q --no-colors --report=checkstyle | cs2pr"
php-doctrine-instantiator-1.4.0/.github/workflows/continuous-integration.yml 0000664 0000000 0000000 00000004250 13762423633 0027506 0 ustar 00root root 0000000 0000000
name: "Continuous Integration"
on:
pull_request:
branches:
- "*.x"
push:
branches:
- "*.x"
env:
fail-fast: true
COMPOSER_ROOT_VERSION: "1.4"
jobs:
phpunit:
name: "PHPUnit with SQLite"
runs-on: "ubuntu-20.04"
strategy:
matrix:
php-version:
- "7.1"
- "7.2"
- "7.3"
- "7.4"
- "8.0"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Install PHP with XDebug"
uses: "shivammathur/setup-php@v2"
if: "${{ matrix.php-version == '7.1' }}"
with:
php-version: "${{ matrix.php-version }}"
coverage: "xdebug"
ini-values: "zend.assertions=1"
- name: "Install PHP with PCOV"
uses: "shivammathur/setup-php@v2"
if: "${{ matrix.php-version != '7.1' }}"
with:
php-version: "${{ matrix.php-version }}"
coverage: "pcov"
ini-values: "zend.assertions=1"
- name: "Cache dependencies installed with composer"
uses: "actions/cache@v2"
with:
path: "~/.composer/cache"
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
- name: "Install dependencies with composer"
run: "composer update --no-interaction --no-progress"
- name: "Run PHPUnit"
run: "vendor/bin/phpunit --coverage-clover=coverage.xml"
- name: "Upload coverage file"
uses: "actions/upload-artifact@v2"
with:
name: "phpunit-${{ matrix.php-version }}.coverage"
path: "coverage.xml"
upload_coverage:
name: "Upload coverage to Codecov"
runs-on: "ubuntu-20.04"
needs:
- "phpunit"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Download coverage files"
uses: "actions/download-artifact@v2"
with:
path: "reports"
- name: "Upload to Codecov"
uses: "codecov/codecov-action@v1"
with:
directory: reports
php-doctrine-instantiator-1.4.0/.github/workflows/phpbench.yml 0000664 0000000 0000000 00000002223 13762423633 0024544 0 ustar 00root root 0000000 0000000
name: "Performance benchmark"
on:
pull_request:
branches:
- "*.x"
push:
branches:
- "*.x"
env:
fail-fast: true
COMPOSER_ROOT_VERSION: "1.4"
jobs:
phpbench:
name: "PHPBench"
runs-on: "ubuntu-20.04"
strategy:
matrix:
php-version:
- "7.4"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
with:
fetch-depth: 2
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "${{ matrix.php-version }}"
coverage: "pcov"
ini-values: "zend.assertions=1"
- name: "Cache dependencies installed with composer"
uses: "actions/cache@v2"
with:
path: "~/.composer/cache"
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
- name: "Install dependencies with composer"
run: "composer update --no-interaction --no-progress"
- name: "Run PHPBench"
run: "php ./vendor/bin/phpbench run --iterations=3 --warmup=1 --report=aggregate"
php-doctrine-instantiator-1.4.0/.github/workflows/release-on-milestone-closed.yml 0000664 0000000 0000000 00000002747 13762423633 0030266 0 ustar 00root root 0000000 0000000 name: "Automatic Releases"
on:
milestone:
types:
- "closed"
jobs:
release:
name: "Git tag, release & create merge-up PR"
runs-on: "ubuntu-20.04"
steps:
- name: "Checkout"
uses: "actions/checkout@v2"
- name: "Release"
uses: "laminas/automatic-releases@v1"
with:
command-name: "laminas:automatic-releases:release"
env:
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
- name: "Create Merge-Up Pull Request"
uses: "laminas/automatic-releases@v1"
with:
command-name: "laminas:automatic-releases:create-merge-up-pull-request"
env:
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
- name: "Create new milestones"
uses: "laminas/automatic-releases@v1"
with:
command-name: "laminas:automatic-releases:create-milestones"
env:
"GITHUB_TOKEN": ${{ secrets.GITHUB_TOKEN }}
"SIGNING_SECRET_KEY": ${{ secrets.SIGNING_SECRET_KEY }}
"GIT_AUTHOR_NAME": ${{ secrets.GIT_AUTHOR_NAME }}
"GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }}
php-doctrine-instantiator-1.4.0/.github/workflows/static-analysis.yml 0000664 0000000 0000000 00000002174 13762423633 0026072 0 ustar 00root root 0000000 0000000
name: "Static Analysis"
on:
pull_request:
branches:
- "*.x"
push:
branches:
- "*.x"
env:
COMPOSER_ROOT_VERSION: "1.4"
jobs:
static-analysis-phpstan:
name: "Static Analysis with PHPStan"
runs-on: "ubuntu-20.04"
strategy:
matrix:
php-version:
- "7.4"
steps:
- name: "Checkout code"
uses: "actions/checkout@v2"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "${{ matrix.php-version }}"
tools: "cs2pr"
- name: "Cache dependencies installed with composer"
uses: "actions/cache@v2"
with:
path: "~/.composer/cache"
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
- name: "Install dependencies with composer"
run: "composer install --no-interaction --no-progress"
- name: "Run a static analysis with phpstan/phpstan"
run: "vendor/bin/phpstan analyse --error-format=checkstyle | cs2pr"
php-doctrine-instantiator-1.4.0/.gitignore 0000664 0000000 0000000 00000000166 13762423633 0020631 0 ustar 00root root 0000000 0000000 phpunit.xml
/.phpunit.result.cache
build
vendor
/composer.lock
coverage.clover
/phpcs.xml
/.phpcs-cache
/phpstan.neon
php-doctrine-instantiator-1.4.0/CONTRIBUTING.md 0000664 0000000 0000000 00000002010 13762423633 0021060 0 ustar 00root root 0000000 0000000 # Contributing
* Follow the [Doctrine Coding Standard](https://github.com/doctrine/coding-standard)
* The project will follow strict [object calisthenics](http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php)
* Any contribution must provide tests for additional introduced conditions
* Any un-confirmed issue needs a failing test case before being accepted
* Pull requests must be sent from a new hotfix/feature branch, not from `master`.
## Installation
To install the project and run the tests, you need to clone it first:
```sh
$ git clone git://github.com/doctrine/instantiator.git
```
You will then need to run a composer installation:
```sh
$ cd Instantiator
$ curl -s https://getcomposer.org/installer | php
$ php composer.phar update
```
## Testing
The PHPUnit version to be used is the one installed as a dev- dependency via composer:
```sh
$ ./vendor/bin/phpunit
```
Accepted coverage for new contributions is 80%. Any contribution not satisfying this requirement
won't be merged.
php-doctrine-instantiator-1.4.0/LICENSE 0000664 0000000 0000000 00000002044 13762423633 0017643 0 ustar 00root root 0000000 0000000 Copyright (c) 2014 Doctrine Project
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
php-doctrine-instantiator-1.4.0/README.md 0000664 0000000 0000000 00000003075 13762423633 0020122 0 ustar 00root root 0000000 0000000 # Instantiator
This library provides a way of avoiding usage of constructors when instantiating PHP classes.
[](https://travis-ci.org/doctrine/instantiator)
[](https://codecov.io/gh/doctrine/instantiator/branch/master)
[](https://www.versioneye.com/package/php--doctrine--instantiator)
[](https://packagist.org/packages/doctrine/instantiator)
[](https://packagist.org/packages/doctrine/instantiator)
## Installation
The suggested installation method is via [composer](https://getcomposer.org/):
```sh
php composer.phar require "doctrine/instantiator:~1.0.3"
```
## Usage
The instantiator is able to create new instances of any class without using the constructor or any API of the class
itself:
```php
$instantiator = new \Doctrine\Instantiator\Instantiator();
$instance = $instantiator->instantiate(\My\ClassName\Here::class);
```
## Contributing
Please read the [CONTRIBUTING.md](CONTRIBUTING.md) contents if you wish to help out!
## Credits
This library was migrated from [ocramius/instantiator](https://github.com/Ocramius/Instantiator), which
has been donated to the doctrine organization, and which is now deprecated in favour of this package.
php-doctrine-instantiator-1.4.0/composer.json 0000664 0000000 0000000 00000002550 13762423633 0021362 0 ustar 00root root 0000000 0000000 {
"name": "doctrine/instantiator",
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
"type": "library",
"license": "MIT",
"homepage": "https://www.doctrine-project.org/projects/instantiator.html",
"keywords": [
"instantiate",
"constructor"
],
"authors": [
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com",
"homepage": "https://ocramius.github.io/"
}
],
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"ext-phar": "*",
"ext-pdo": "*",
"doctrine/coding-standard": "^8.0",
"phpbench/phpbench": "^0.13 || 1.0.0-alpha2",
"phpstan/phpstan": "^0.12",
"phpstan/phpstan-phpunit": "^0.12",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
},
"autoload": {
"psr-4": {
"Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
}
},
"autoload-dev": {
"psr-0": {
"DoctrineTest\\InstantiatorPerformance\\": "tests",
"DoctrineTest\\InstantiatorTest\\": "tests",
"DoctrineTest\\InstantiatorTestAsset\\": "tests"
}
}
}
php-doctrine-instantiator-1.4.0/docs/ 0000775 0000000 0000000 00000000000 13762423633 0017566 5 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/docs/en/ 0000775 0000000 0000000 00000000000 13762423633 0020170 5 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/docs/en/index.rst 0000664 0000000 0000000 00000003337 13762423633 0022037 0 ustar 00root root 0000000 0000000 Introduction
============
This library provides a way of avoiding usage of constructors when instantiating PHP classes.
Installation
============
The suggested installation method is via `composer`_:
.. code-block:: console
$ composer require doctrine/instantiator
Usage
=====
The instantiator is able to create new instances of any class without
using the constructor or any API of the class itself:
.. code-block:: php
instantiate(User::class);
Contributing
============
- Follow the `Doctrine Coding Standard`_
- The project will follow strict `object calisthenics`_
- Any contribution must provide tests for additional introduced
conditions
- Any un-confirmed issue needs a failing test case before being
accepted
- Pull requests must be sent from a new hotfix/feature branch, not from
``master``.
Testing
=======
The PHPUnit version to be used is the one installed as a dev- dependency
via composer:
.. code-block:: console
$ ./vendor/bin/phpunit
Accepted coverage for new contributions is 80%. Any contribution not
satisfying this requirement won’t be merged.
Credits
=======
This library was migrated from `ocramius/instantiator`_, which has been
donated to the doctrine organization, and which is now deprecated in
favour of this package.
.. _composer: https://getcomposer.org/
.. _CONTRIBUTING.md: CONTRIBUTING.md
.. _ocramius/instantiator: https://github.com/Ocramius/Instantiator
.. _Doctrine Coding Standard: https://github.com/doctrine/coding-standard
.. _object calisthenics: http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php
php-doctrine-instantiator-1.4.0/docs/en/sidebar.rst 0000664 0000000 0000000 00000000046 13762423633 0022333 0 ustar 00root root 0000000 0000000 .. toctree::
:depth: 3
index
php-doctrine-instantiator-1.4.0/phpbench.json 0000664 0000000 0000000 00000000145 13762423633 0021320 0 ustar 00root root 0000000 0000000 {
"bootstrap": "vendor/autoload.php",
"path": "tests/DoctrineTest/InstantiatorPerformance"
}
php-doctrine-instantiator-1.4.0/phpcs.xml.dist 0000664 0000000 0000000 00000004141 13762423633 0021437 0 ustar 00root root 0000000 0000000
src
tests
*/src/*
*/src/*
tests/DoctrineTest/InstantiatorTestAsset/AbstractClassAsset.php
src/Doctrine/Instantiator/Exception/UnexpectedValueException.php
src/Doctrine/Instantiator/Exception/InvalidArgumentException.php
src/Doctrine/Instantiator/Exception/ExceptionInterface.php
src/Doctrine/Instantiator/InstantiatorInterface.php
php-doctrine-instantiator-1.4.0/phpmd.xml.dist 0000664 0000000 0000000 00000002075 13762423633 0021436 0 ustar 00root root 0000000 0000000
php-doctrine-instantiator-1.4.0/phpstan.neon.dist 0000664 0000000 0000000 00000000635 13762423633 0022142 0 ustar 00root root 0000000 0000000 includes:
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-phpunit/rules.neon
parameters:
level: max
paths:
- src
- tests
ignoreErrors:
# dynamic properties confuse static analysis
-
message: '#Access to an undefined property object::\$foo\.#'
path: '*/tests/DoctrineTest/InstantiatorTest/InstantiatorTest.php'
php-doctrine-instantiator-1.4.0/phpunit.xml.dist 0000664 0000000 0000000 00000001144 13762423633 0022011 0 ustar 00root root 0000000 0000000
./tests/DoctrineTest/InstantiatorTest
./src
php-doctrine-instantiator-1.4.0/src/ 0000775 0000000 0000000 00000000000 13762423633 0017425 5 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/src/Doctrine/ 0000775 0000000 0000000 00000000000 13762423633 0021174 5 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/src/Doctrine/Instantiator/ 0000775 0000000 0000000 00000000000 13762423633 0023653 5 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/src/Doctrine/Instantiator/Exception/ 0000775 0000000 0000000 00000000000 13762423633 0025611 5 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/src/Doctrine/Instantiator/Exception/ExceptionInterface.php 0000664 0000000 0000000 00000000300 13762423633 0032072 0 ustar 00root root 0000000 0000000 $reflectionClass
*/
public static function fromAbstractClass(ReflectionClass $reflectionClass): self
{
return new self(sprintf(
'The provided class "%s" is abstract, and can not be instantiated',
$reflectionClass->getName()
));
}
}
php-doctrine-instantiator-1.4.0/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php 0000664 0000000 0000000 00000003111 13762423633 0033276 0 ustar 00root root 0000000 0000000 $reflectionClass
*/
public static function fromSerializationTriggeredException(
ReflectionClass $reflectionClass,
Exception $exception
): self {
return new self(
sprintf(
'An exception was raised while trying to instantiate an instance of "%s" via un-serialization',
$reflectionClass->getName()
),
0,
$exception
);
}
/**
* @template T of object
* @phpstan-param ReflectionClass $reflectionClass
*/
public static function fromUncleanUnSerialization(
ReflectionClass $reflectionClass,
string $errorString,
int $errorCode,
string $errorFile,
int $errorLine
): self {
return new self(
sprintf(
'Could not produce an instance of "%s" via un-serialization, since an error was triggered '
. 'in file "%s" at line "%d"',
$reflectionClass->getName(),
$errorFile,
$errorLine
),
0,
new Exception($errorString, $errorCode)
);
}
}
php-doctrine-instantiator-1.4.0/src/Doctrine/Instantiator/Instantiator.php 0000664 0000000 0000000 00000015321 13762423633 0027045 0 ustar 00root root 0000000 0000000 buildAndCacheFromFactory($className);
}
/**
* Builds the requested object and caches it in static properties for performance
*
* @return object
*
* @template T of object
* @phpstan-param class-string $className
*
* @phpstan-return T
*/
private function buildAndCacheFromFactory(string $className)
{
$factory = self::$cachedInstantiators[$className] = $this->buildFactory($className);
$instance = $factory();
if ($this->isSafeToClone(new ReflectionClass($instance))) {
self::$cachedCloneables[$className] = clone $instance;
}
return $instance;
}
/**
* Builds a callable capable of instantiating the given $className without
* invoking its constructor.
*
* @throws InvalidArgumentException
* @throws UnexpectedValueException
* @throws ReflectionException
*
* @template T of object
* @phpstan-param class-string $className
*
* @phpstan-return callable(): T
*/
private function buildFactory(string $className): callable
{
$reflectionClass = $this->getReflectionClass($className);
if ($this->isInstantiableViaReflection($reflectionClass)) {
return [$reflectionClass, 'newInstanceWithoutConstructor'];
}
$serializedString = sprintf(
'%s:%d:"%s":0:{}',
is_subclass_of($className, Serializable::class) ? self::SERIALIZATION_FORMAT_USE_UNSERIALIZER : self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER,
strlen($className),
$className
);
$this->checkIfUnSerializationIsSupported($reflectionClass, $serializedString);
return static function () use ($serializedString) {
return unserialize($serializedString);
};
}
/**
* @throws InvalidArgumentException
* @throws ReflectionException
*
* @template T of object
* @phpstan-param class-string $className
*
* @phpstan-return ReflectionClass
*/
private function getReflectionClass(string $className): ReflectionClass
{
if (! class_exists($className)) {
throw InvalidArgumentException::fromNonExistingClass($className);
}
$reflection = new ReflectionClass($className);
if ($reflection->isAbstract()) {
throw InvalidArgumentException::fromAbstractClass($reflection);
}
return $reflection;
}
/**
* @throws UnexpectedValueException
*
* @template T of object
* @phpstan-param ReflectionClass $reflectionClass
*/
private function checkIfUnSerializationIsSupported(ReflectionClass $reflectionClass, string $serializedString): void
{
set_error_handler(static function (int $code, string $message, string $file, int $line) use ($reflectionClass, &$error): bool {
$error = UnexpectedValueException::fromUncleanUnSerialization(
$reflectionClass,
$message,
$code,
$file,
$line
);
return true;
});
try {
$this->attemptInstantiationViaUnSerialization($reflectionClass, $serializedString);
} finally {
restore_error_handler();
}
if ($error) {
throw $error;
}
}
/**
* @throws UnexpectedValueException
*
* @template T of object
* @phpstan-param ReflectionClass $reflectionClass
*/
private function attemptInstantiationViaUnSerialization(ReflectionClass $reflectionClass, string $serializedString): void
{
try {
unserialize($serializedString);
} catch (Exception $exception) {
throw UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $exception);
}
}
/**
* @template T of object
* @phpstan-param ReflectionClass $reflectionClass
*/
private function isInstantiableViaReflection(ReflectionClass $reflectionClass): bool
{
return ! ($this->hasInternalAncestors($reflectionClass) && $reflectionClass->isFinal());
}
/**
* Verifies whether the given class is to be considered internal
*
* @template T of object
* @phpstan-param ReflectionClass $reflectionClass
*/
private function hasInternalAncestors(ReflectionClass $reflectionClass): bool
{
do {
if ($reflectionClass->isInternal()) {
return true;
}
$reflectionClass = $reflectionClass->getParentClass();
} while ($reflectionClass);
return false;
}
/**
* Checks if a class is cloneable
*
* Classes implementing `__clone` cannot be safely cloned, as that may cause side-effects.
*
* @template T of object
* @phpstan-param ReflectionClass $reflectionClass
*/
private function isSafeToClone(ReflectionClass $reflectionClass): bool
{
return $reflectionClass->isCloneable()
&& ! $reflectionClass->hasMethod('__clone')
&& ! $reflectionClass->isSubclassOf(ArrayIterator::class);
}
}
php-doctrine-instantiator-1.4.0/src/Doctrine/Instantiator/InstantiatorInterface.php 0000664 0000000 0000000 00000000744 13762423633 0030671 0 ustar 00root root 0000000 0000000 $className
*/
public function instantiate($className);
}
php-doctrine-instantiator-1.4.0/tests/ 0000775 0000000 0000000 00000000000 13762423633 0020000 5 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/tests/DoctrineTest/ 0000775 0000000 0000000 00000000000 13762423633 0022407 5 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/tests/DoctrineTest/InstantiatorPerformance/ 0000775 0000000 0000000 00000000000 13762423633 0027250 5 ustar 00root root 0000000 0000000 InstantiatorPerformanceEvent.php 0000664 0000000 0000000 00000003631 13762423633 0035550 0 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/tests/DoctrineTest/InstantiatorPerformance instantiator = new Instantiator();
$this->instantiator->instantiate(self::class);
$this->instantiator->instantiate(ArrayObject::class);
$this->instantiator->instantiate(SimpleSerializableAsset::class);
$this->instantiator->instantiate(SerializableArrayObjectAsset::class);
$this->instantiator->instantiate(UnCloneableAsset::class);
}
/**
* @Revs(20000)
*/
public function benchInstantiateSelf(): void
{
$this->instantiator->instantiate(self::class);
}
/**
* @Revs(20000)
*/
public function benchInstantiateInternalClass(): void
{
$this->instantiator->instantiate(ArrayObject::class);
}
/**
* @Revs(20000)
*/
public function benchInstantiateSimpleSerializableAssetClass(): void
{
$this->instantiator->instantiate(SimpleSerializableAsset::class);
}
/**
* @Revs(20000)
*/
public function benchInstantiateSerializableArrayObjectAsset(): void
{
$this->instantiator->instantiate(SerializableArrayObjectAsset::class);
}
/**
* @Revs(20000)
*/
public function benchInstantiateUnCloneableAsset(): void
{
$this->instantiator->instantiate(UnCloneableAsset::class);
}
}
php-doctrine-instantiator-1.4.0/tests/DoctrineTest/InstantiatorTest/ 0000775 0000000 0000000 00000000000 13762423633 0025726 5 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/tests/DoctrineTest/InstantiatorTest/Exception/ 0000775 0000000 0000000 00000000000 13762423633 0027664 5 ustar 00root root 0000000 0000000 InvalidArgumentExceptionTest.php 0000664 0000000 0000000 00000004345 13762423633 0036134 0 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/tests/DoctrineTest/InstantiatorTest/Exception getMessage());
}
public function testFromNonExistingTypeWithTrait(): void
{
$exception = InvalidArgumentException::fromNonExistingClass(SimpleTraitAsset::class);
self::assertSame(
sprintf('The provided type "%s" is a trait, and can not be instantiated', SimpleTraitAsset::class),
$exception->getMessage()
);
}
public function testFromNonExistingTypeWithInterface(): void
{
$exception = InvalidArgumentException::fromNonExistingClass(InstantiatorInterface::class);
self::assertSame(
sprintf(
'The provided type "%s" is an interface, and can not be instantiated',
InstantiatorInterface::class
),
$exception->getMessage()
);
}
public function testFromAbstractClass(): void
{
$reflection = new ReflectionClass(AbstractClassAsset::class);
$exception = InvalidArgumentException::fromAbstractClass($reflection);
self::assertSame(
sprintf(
'The provided class "%s" is abstract, and can not be instantiated',
AbstractClassAsset::class
),
$exception->getMessage()
);
}
}
UnexpectedValueExceptionTest.php 0000664 0000000 0000000 00000003720 13762423633 0036140 0 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/tests/DoctrineTest/InstantiatorTest/Exception getPrevious());
self::assertSame(
'An exception was raised while trying to instantiate an instance of "'
. self::class . '" via un-serialization',
$exception->getMessage()
);
}
public function testFromUncleanUnSerialization(): void
{
$reflection = new ReflectionClass(AbstractClassAsset::class);
$exception = UnexpectedValueException::fromUncleanUnSerialization($reflection, 'foo', 123, 'bar', 456);
self::assertInstanceOf(UnexpectedValueException::class, $exception);
self::assertSame(
sprintf(
'Could not produce an instance of "%s" '
. 'via un-serialization, since an error was triggered in file "bar" at line "456"',
AbstractClassAsset::class
),
$exception->getMessage()
);
$previous = $exception->getPrevious();
self::assertInstanceOf(Exception::class, $previous);
self::assertSame('foo', $previous->getMessage());
self::assertSame(123, $previous->getCode());
}
}
php-doctrine-instantiator-1.4.0/tests/DoctrineTest/InstantiatorTest/InstantiatorTest.php 0000664 0000000 0000000 00000011300 13762423633 0031751 0 ustar 00root root 0000000 0000000 instantiator = new Instantiator();
}
/**
* @dataProvider getInstantiableClasses
* @phpstan-param class-string $className
*/
public function testCanInstantiate(string $className): void
{
self::assertInstanceOf($className, $this->instantiator->instantiate($className));
}
/**
* @dataProvider getInstantiableClasses
* @phpstan-param class-string $className
*/
public function testInstantiatesSeparateInstances(string $className): void
{
$instance1 = $this->instantiator->instantiate($className);
$instance2 = $this->instantiator->instantiate($className);
self::assertEquals($instance1, $instance2);
self::assertNotSame($instance1, $instance2);
}
public function testExceptionOnUnSerializationException(): void
{
$this->expectException(UnexpectedValueException::class);
$this->instantiator->instantiate(PDORow::class);
}
/**
* @dataProvider getInvalidClassNames
* @phpstan-param class-string $invalidClassName
*/
public function testInstantiationFromNonExistingClass(string $invalidClassName): void
{
$this->expectException(InvalidArgumentException::class);
$this->instantiator->instantiate($invalidClassName);
}
public function testInstancesAreNotCloned(): void
{
$className = 'TemporaryClass' . str_replace('.', '', uniqid('', true));
eval('namespace ' . __NAMESPACE__ . '; class ' . $className . '{}');
/**
* @phpstan-var class-string
*/
$classNameWithNamespace = __NAMESPACE__ . '\\' . $className;
$instance = $this->instantiator->instantiate($classNameWithNamespace);
$instance->foo = 'bar';
$instance2 = $this->instantiator->instantiate($classNameWithNamespace);
self::assertObjectNotHasAttribute('foo', $instance2);
}
/**
* Provides a list of instantiable classes (existing)
*
* @return string[][]
*
* @phpstan-return list
*/
public function getInstantiableClasses(): array
{
return [
[stdClass::class],
[self::class],
[Instantiator::class],
[Exception::class],
[PharException::class],
[SimpleSerializableAsset::class],
[ExceptionAsset::class],
[FinalExceptionAsset::class],
[PharExceptionAsset::class],
[UnCloneableAsset::class],
[XMLReaderAsset::class],
[PharException::class],
[ArrayObject::class],
[ArrayObjectAsset::class],
[SerializableArrayObjectAsset::class],
[WakeUpNoticesAsset::class],
[UnserializeExceptionArrayObjectAsset::class],
[SerializableFinalInternalChildAsset::class],
];
}
/**
* Provides a list of instantiable classes (existing)
*
* @return string[][]
*/
public function getInvalidClassNames(): array
{
return [
[self::class . str_replace('.', '', uniqid('', true))],
[InstantiatorInterface::class],
[AbstractClassAsset::class],
[SimpleTraitAsset::class],
];
}
}
php-doctrine-instantiator-1.4.0/tests/DoctrineTest/InstantiatorTestAsset/ 0000775 0000000 0000000 00000000000 13762423633 0026726 5 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/tests/DoctrineTest/InstantiatorTestAsset/AbstractClassAsset.php 0000664 0000000 0000000 00000000214 13762423633 0033165 0 ustar 00root root 0000000 0000000
*/
class ArrayObjectAsset extends ArrayObject
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
}
php-doctrine-instantiator-1.4.0/tests/DoctrineTest/InstantiatorTestAsset/ExceptionAsset.php 0000664 0000000 0000000 00000000654 13762423633 0032402 0 ustar 00root root 0000000 0000000
*/
class SerializableArrayObjectAsset extends ArrayObject implements Serializable
{
/**
* Constructor - should not be called
*
* @throws BadMethodCallException
*/
public function __construct()
{
throw new BadMethodCallException('Not supposed to be called!');
}
/**
* {@inheritDoc}
*/
public function serialize()
{
return '';
}
/**
* {@inheritDoc}
*
* Should not be called
*
* @throws BadMethodCallException
*/
public function unserialize($serialized)
{
throw new BadMethodCallException('Not supposed to be called!');
}
}
SerializableFinalInternalChildAsset.php 0000664 0000000 0000000 00000000371 13762423633 0036402 0 ustar 00root root 0000000 0000000 php-doctrine-instantiator-1.4.0/tests/DoctrineTest/InstantiatorTestAsset
*/
final class SerializableFinalInternalChildAsset extends ArrayIterator
{
}
php-doctrine-instantiator-1.4.0/tests/DoctrineTest/InstantiatorTestAsset/SimpleSerializableAsset.php0000664 0000000 0000000 00000001400 13762423633 0034212 0 ustar 00root root 0000000 0000000
*/
class UnserializeExceptionArrayObjectAsset extends ArrayObject
{
/**
* {@inheritDoc}
*/
public function __wakeup()
{
throw new BadMethodCallException();
}
}
php-doctrine-instantiator-1.4.0/tests/DoctrineTest/InstantiatorTestAsset/WakeUpNoticesAsset.php 0000664 0000000 0000000 00000000723 13762423633 0033162 0 ustar 00root root 0000000 0000000
*/
class WakeUpNoticesAsset extends ArrayObject
{
/**
* Wakeup method called after un-serialization
*/
public function __wakeup(): void
{
trigger_error('Something went bananas while un-serializing this instance');
}
}
php-doctrine-instantiator-1.4.0/tests/DoctrineTest/InstantiatorTestAsset/XMLReaderAsset.php 0000664 0000000 0000000 00000000643 13762423633 0032225 0 ustar 00root root 0000000 0000000