Skip to content

Commit e271b17

Browse files
committed
Initial commit
0 parents  commit e271b17

32 files changed

+1673
-0
lines changed

.editorconfig

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
root = true
2+
3+
[*]
4+
end_of_line = lf
5+
charset = utf-8
6+
trim_trailing_whitespace = true
7+
insert_final_newline = true
8+
indent_style = space
9+
indent_size = 4
10+
11+
[*.yml]
12+
indent_style = space
13+
indent_size = 2
14+
15+
[*.md]
16+
indent_style = space
17+
indent_size = 4
18+
19+
[Makefile]
20+
indent_style = tab
21+
indent_size = 4

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
build
2+
composer.lock
3+
vendor

.travis.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
sudo: false
2+
3+
cache:
4+
directories:
5+
- $COMPOSER_CACHE_DIR
6+
- $HOME/.composer/cache
7+
- $TRAVIS_BUILD_DIR/build
8+
9+
language: php
10+
11+
php:
12+
- 7.1
13+
- 7.2
14+
15+
before_script:
16+
- if [[ $TRAVIS_PHP_VERSION != "7.1" ]]; then phpenv config-rm xdebug.ini; fi
17+
18+
script:
19+
- if [[ $TRAVIS_PHP_VERSION == "7.1" ]]; then make test-coveralls; else make test; fi

Dockerfile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
FROM php:7.1-alpine3.8
2+
3+
RUN apk add --no-cache make $PHPIZE_DEPS \
4+
&& pecl install xdebug \
5+
&& docker-php-ext-enable xdebug
6+
7+
RUN echo $'\
8+
xdebug.coverage_enable=1\n\
9+
xdebug.default_enable=1\n\
10+
' >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
11+
12+
ENV COMPOSER_ALLOW_SUPERUSER 1
13+
14+
RUN curl -o /tmp/composer-setup.php https://getcomposer.org/installer && \
15+
curl -o /tmp/composer-setup.sig https://composer.github.io/installer.sig && \
16+
php -r "if (hash('SHA384', file_get_contents('/tmp/composer-setup.php')) !== trim(file_get_contents('/tmp/composer-setup.sig'))) { unlink('/tmp/composer-setup.php'); echo 'Invalid installer' . PHP_EOL; exit(1); }" && \
17+
php /tmp/composer-setup.php && \
18+
mv composer.phar /usr/local/bin/composer
19+
20+
RUN wget -O phpunit https://phar.phpunit.de/phpunit-7.phar && \
21+
chmod +x phpunit && \
22+
mv phpunit /usr/local/bin/phpunit
23+
24+
WORKDIR app

LICENSE

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
The olvlvl/symfony-dependency-injection-proxy package is free software.
2+
It is released under the terms of the following BSD License.
3+
4+
Copyright (c) 2018 by Olivier Laviale
5+
All rights reserved.
6+
7+
Redistribution and use in source and binary forms, with or without modification,
8+
are permitted provided that the following conditions are met:
9+
10+
* Redistributions of source code must retain the above copyright notice,
11+
this list of conditions and the following disclaimer.
12+
13+
* Redistributions in binary form must reproduce the above copyright notice,
14+
this list of conditions and the following disclaimer in the documentation
15+
and/or other materials provided with the distribution.
16+
17+
* Neither the name of Olivier Laviale nor the names of its
18+
contributors may be used to endorse or promote products derived from this
19+
software without specific prior written permission.
20+
21+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
25+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Makefile

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
PHPUNIT=$(shell which phpunit)
2+
3+
vendor:
4+
@composer install
5+
6+
test: test-setup
7+
@php -d xdebug.coverage_enable=0 $(PHPUNIT)
8+
9+
test-coverage: test-setup
10+
@mkdir -p build/coverage
11+
@$(PHPUNIT) --coverage-html build/coverage
12+
13+
test-coveralls: test-setup
14+
@mkdir -p build/logs
15+
composer require satooshi/php-coveralls '^2.0'
16+
@$(PHPUNIT) --coverage-clover build/logs/clover.xml
17+
php vendor/bin/php-coveralls -v
18+
19+
test-container:
20+
@docker-compose run --rm app sh
21+
@docker-compose down
22+
23+
test-setup: vendor
24+
@rm -f tests/sandbox/*
25+
26+
.PHONY: all test test-container test-coverage test-coveralls test-setup

README.md

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
# Proxy generator for Symfony's DIC
2+
3+
[![Release](https://img.shields.io/packagist/v/olvlvl/symfony-dependency-injection-proxy.svg)](https://packagist.org/packages/olvlvl/symfony-dependency-injection-proxy)
4+
[![Build Status](https://img.shields.io/travis/olvlvl/symfony-dependency-injection-proxy.svg)](http://travis-ci.org/olvlvl/symfony-dependency-injection-proxy)
5+
[![Code Quality](https://img.shields.io/scrutinizer/g/olvlvl/symfony-dependency-injection-proxy.svg)](https://scrutinizer-ci.com/g/olvlvl/symfony-dependency-injection-proxy)
6+
[![Code Coverage](https://img.shields.io/coveralls/olvlvl/symfony-dependency-injection-proxy.svg)](https://coveralls.io/r/olvlvl/symfony-dependency-injection-proxy)
7+
[![Packagist](https://img.shields.io/packagist/dt/olvlvl/symfony-dependency-injection-proxy.svg)](https://packagist.org/packages/olvlvl/symfony-dependency-injection-proxy)
8+
9+
This package provides a proxy generator for [Symfony's dependency injection component][1] that generates super tiny,
10+
super simple proxies, especially when [compared to Symphony's default implementation][2].
11+
12+
> If you're not familiar with proxy services, better have a look at [Symfony's documentation][3] before going any
13+
> further.
14+
15+
The generator works with the following assumptions: the service we want to proxy implements an interface and services
16+
using that service expect that interface too. Pretty normal stuff. Consider the following code, where an
17+
`ExceptionHandler` service requires a logger implementing `LogInterface`:
18+
19+
```php
20+
<?php
21+
22+
use Psr\Log\LoggerInterface;
23+
24+
class ExceptionHandler
25+
{
26+
private $logger;
27+
28+
public function __construct(LoggerInterface $logger)
29+
{
30+
$this->logger = $logger;
31+
}
32+
33+
// …
34+
}
35+
```
36+
37+
Now imagine we're using [Monolog](https://github.com/Seldaek/monolog) as a logger, and we have an expansive stream to
38+
setup. Why waste time building that logger for every request when it's seldom used? That's when we mark our service as
39+
_lazy_.
40+
41+
The following example demonstrates how we can mark our `Psr\Log\LoggerInterface` service as lazy (we could use PHP code
42+
or XML just the same):
43+
44+
```yaml
45+
services:
46+
47+
Psr\Log\LoggerInterface:
48+
class: Monolog\Logger
49+
lazy: true
50+
#
51+
```
52+
53+
The service can also use a factory:
54+
55+
```yaml
56+
services:
57+
58+
Psr\Log\LoggerInterface:
59+
factory: 'LoggerFactory::build'
60+
lazy: true
61+
#
62+
```
63+
64+
> We don't have to define our service with a class, we could use `logger` instead of `Psr\Log\LoggerInterface` just
65+
> the same, except we would have to define `class` for the factory one.
66+
67+
Now let's see how to build our container.
68+
69+
## Building the dependency injection container
70+
71+
The following code demonstrates how to build, compile, and dump a container:
72+
73+
```php
74+
<?php
75+
76+
use olvlvl\SymfonyDependencyInjectionProxy\FactoryRenderer;
77+
use olvlvl\SymfonyDependencyInjectionProxy\InterfaceResolver\BasicInterfaceResolver;
78+
use olvlvl\SymfonyDependencyInjectionProxy\MethodRenderer;
79+
use olvlvl\SymfonyDependencyInjectionProxy\ProxyDumper;
80+
use Symfony\Component\DependencyInjection\ContainerBuilder;
81+
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
82+
83+
$builder = new ContainerBuilder();
84+
85+
// …
86+
// Here we load our config, or build the container using clever PHP calls.
87+
// We might event have some compile passes to add.
88+
// …
89+
90+
$builder->compile();
91+
92+
$dumper = new PhpDumper($builder);
93+
$dumper->setProxyDumper(new ProxyDumper(
94+
new BasicInterfaceResolver(),
95+
new FactoryRenderer(new MethodRenderer)
96+
));
97+
98+
/* @var string $containerFile */
99+
100+
file_put_contents($containerFile, $dumper->dump());
101+
```
102+
103+
There you have it. We can use our container as usual and everything is awesome and cute.
104+
105+
106+
107+
108+
109+
### What if my lazy service implements multiple interfaces?
110+
111+
The basic interface resolver will have a hard time figuring out which interface to implement if a service implements
112+
many. For instance, if a service was an instance of `ArrayObject` the following exception would be raised:
113+
114+
```
115+
Don't know which interface to choose from for ArrayObject: IteratorAggregate, Traversable, ArrayAccess, Serializable, Countable.
116+
```
117+
118+
We can help by decorating the basic interface resolver with a map, and specify which interface to implement for which
119+
class:
120+
121+
```php
122+
<?php
123+
124+
use olvlvl\SymfonyDependencyInjectionProxy\FactoryRenderer;
125+
use olvlvl\SymfonyDependencyInjectionProxy\InterfaceResolver\BasicInterfaceResolver;
126+
use olvlvl\SymfonyDependencyInjectionProxy\InterfaceResolver\MapInterfaceResolver;
127+
use olvlvl\SymfonyDependencyInjectionProxy\MethodRenderer;
128+
use olvlvl\SymfonyDependencyInjectionProxy\ProxyDumper;
129+
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
130+
131+
/* @var PhpDumper $dumper */
132+
133+
$dumper->setProxyDumper(new ProxyDumper(
134+
new MapInterfaceResolver(new BasicInterfaceResolver(), [
135+
ArrayObject::class => ArrayAccess::class,
136+
]),
137+
new FactoryRenderer(new MethodRenderer)
138+
));
139+
```
140+
141+
142+
143+
144+
145+
----------
146+
147+
148+
149+
150+
151+
## Requirements
152+
153+
The package requires PHP 7.1 or later.
154+
155+
156+
157+
158+
159+
## Installation
160+
161+
The recommended way to install this package is through [Composer](http://getcomposer.org/):
162+
163+
$ composer require olvlvl/symfony-dependency-injection-proxy
164+
165+
166+
167+
168+
169+
### Cloning the repository
170+
171+
The package is [available on GitHub](https://github.com/olvlvl/symfony-dependency-injection-proxy),
172+
its repository can be cloned with the following command line:
173+
174+
$ git clone https://github.com/olvlvl/symfony-dependency-injection-proxy.git
175+
176+
177+
178+
179+
180+
## Testing
181+
182+
The test suite is ran with the `make test` command. [PHPUnit](https://phpunit.de/) and
183+
[Composer](http://getcomposer.org/) need to be globally available to run the suite. The command
184+
installs dependencies as required. The `make test-coverage` command runs test suite and also creates
185+
an HTML coverage report in `build/coverage`. If your environment doesn't meet the requirements you can run the tests
186+
with a container, run `make test-container` to create it.
187+
188+
The package is continuously tested by [Travis CI](http://about.travis-ci.org/).
189+
190+
[![Build Status](https://img.shields.io/travis/olvlvl/symfony-dependency-injection-proxy.svg)](http://travis-ci.org/olvlvl/symfony-dependency-injection-proxy)
191+
[![Code Coverage](https://img.shields.io/coveralls/olvlvl/symfony-dependency-injection-proxy.svg)](https://coveralls.io/r/olvlvl/symfony-dependency-injection-proxy)
192+
193+
194+
195+
196+
197+
## License
198+
199+
**olvlvl/symfony-dependency-injection-proxy** is licensed under the New BSD License - See the [LICENSE](LICENSE) file for details.
200+
201+
202+
203+
204+
205+
206+
[1]: https://symfony.com/doc/current/components/dependency_injection.html
207+
[2]: https://github.com/olvlvl/symfony-dependency-injection-proxy/wiki/Comparing-olvlvl's-proxy-generator-with-Symphony's
208+
[3]: https://symfony.com/doc/current/service_container/lazy_services.html

composer.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "olvlvl/symfony-dependency-injection-proxy",
3+
"description": "Generate super tiny proxies for Symfony's dependency injection",
4+
"keywords": [ "symfony", "dependency", "injection", "proxy" ],
5+
"type": "library",
6+
"license": "BSD-3-Clause",
7+
"authors": [
8+
{
9+
"name": "Olivier Laviale",
10+
"email": "[email protected]"
11+
}
12+
],
13+
"require": {
14+
"php": ">=7.1",
15+
"ext-json": "*",
16+
"symfony/dependency-injection": "^4.1"
17+
},
18+
"autoload": {
19+
"psr-4": {
20+
"olvlvl\\SymfonyDependencyInjectionProxy\\": "lib"
21+
}
22+
},
23+
"autoload-dev": {
24+
"psr-4": {
25+
"tests\\olvlvl\\SymfonyDependencyInjectionProxy\\": "tests"
26+
}
27+
}
28+
}

docker-compose.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
version: "2.1"
3+
services:
4+
app:
5+
build: .
6+
volumes:
7+
- .:/app:delegated
8+
- ~/.composer:/root/.composer:delegated

0 commit comments

Comments
 (0)