Skip to content

Commit

Permalink
Merge pull request #4 from renakdup/php-dic-remove-interfaces
Browse files Browse the repository at this point in the history
Package prepared for composer usage

- Remove PSR11 interfaces.
- Container returns just Exceptions.
- Renamed namespace from Pisarevskii\ to Renakdup.
  • Loading branch information
renakdup authored May 12, 2024
2 parents daff968 + ea856a6 commit b7b7de8
Show file tree
Hide file tree
Showing 19 changed files with 133 additions and 181 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

d.run74:
php.connect74:
docker run --rm -it -v "${PWD}":/usr/src/myapp -w /usr/src/myapp pimlab/composer:2.0.0-alpha3-php7.4 sh


d.run82:
php.connect82:
docker run --rm -it -v "${PWD}":/usr/src/myapp -w /usr/src/myapp shopware/development:8.2-composer-2 bash
62 changes: 23 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,39 @@
# Simple PHP DIC (SimpleDIC) - DI Container in one file.
# Simple DIC - PHP DI Container in one file for your WordPress.
[![Software License][ico-license]](LICENSE)
[![UnitTests](https://github.com/renakdup/simple-wordpress-dic/actions/workflows/phpunit.yaml/badge.svg)](https://github.com/renakdup/simple-wordpress-dic/actions/workflows/phpunit.yaml)
[![PHPStan](https://github.com/renakdup/simple-wordpress-dic/actions/workflows/phpstan.yaml/badge.svg)](https://github.com/renakdup/simple-wordpress-dic/actions/workflows/phpstan.yaml)



Simple PHP DI Container with autowiring in a single file allows you to easily use it in your simple PHP applications and especially convenient for WordPress plugins and themes.
Simple DI Container with **autowiring** in a single file **without dependencies** allows you to easily use it in your PHP applications and especially convenient for **WordPress** plugins and themes.

## Why choose Simple DI Container?
1. Easy to integrate into your PHP Application or WordPress project, just copy one file.
2. Simple PHP DI Container hasn't any dependencies on other scripts or libraries.
3. Supports auto-wiring `__constructor` parameters for classes as well as for scalar types that have default values.
4. Supports Lazy Load class instantiating.
5. Allow you following the best practices for developing your code.
6. Supports PSR11 (read more about below).
7. Supports PHP ^8 and PHP 7.4.
4. Supports PHP ^8 and PHP 7.4.
5. Supports Lazy Load class instantiating.
6. Allow you following the best practices for developing your code.
7. Supports PSR11 (read more about below).
8. No phpcs conflicts.

## How to integrate it in a project?

1. Just copy the file `./src/Container.php` to your plugin directory or theme.
2. Rename `namespace` in the file from `Pisarevskii\SimpleDIC` to `<Your_Plugin_Name>\SimpleDIC`
2. Rename `namespace` in the file from `Renakdup\SimpleDIC` to `<Your_Plugin_Name>\SimpleDIC`
3. Require this file.

## How to use it in code

### Get started:

1. Create a container
2. Set a service
3. Get a service
4. Use object
1. Add file to your application and `include`.
2. Create a container.
3. Set a service
4. Get a service
5. Use object
```php
use Pisarevskii\SimpleDIC\Container;
use Renakdup\SimpleDIC\Container;

// create container
$container = new Container();
Expand Down Expand Up @@ -177,25 +180,7 @@ Dependencies of PayPal service will not be recreated and will be taken from alre
---

## PSR11 Compatibility
This Simple DI Container compatible with PSR11 standards ver 2.0, to use it:
1. Just import PSR11 interfaces in `Container.php`
```php
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
```
2. Remove PSR11 interfaces from the `Container.php` file:
```php
######## PSR11 2.0 interfaces #########

# ..... PSR11 interfaces

######## PSR11 interfaces - END #########
```

> [!NOTE]
> Some plugins use PSR11 interfaces and these files are stored inside these plugins as well as PSR interfaces have versions and are usually not compatible between major versions.
> **Due that I highly recommend you keep these interfaces inside the file and use PSR11 interfaces under your Plugin/Theme namespace.**
in progress

## Roadmap
- [x] Add binding services with configuration
Expand All @@ -208,15 +193,9 @@ use Psr\Container\NotFoundExceptionInterface;
- [x] Add ability to create new instances of service every time.
- [x] Improve performance.
- [x] Fix deprecated `Use ReflectionParameter::getType() and the ReflectionType APIs should be used instead.` for PHP8
- [ ] Circular dependency protector.
- [ ] Allow to set definitions via `__constructor`.
- [ ] Bind $container instance by default.
- [ ] Add supporting Code Driven IoC.
- [ ] Add configurations of Container.
- [x] Bind $container instance by default.
- [ ] Add `remove` method.
- [ ] Save cache in opcache.
- [ ] PHP 8 named arguments and autowiring.
- [ ] Add Performance Benchmarks
- [ ] Circular dependency protector.

## Nice to have
- [x] Integrate CI with running autotests
Expand All @@ -229,6 +208,11 @@ use Psr\Container\NotFoundExceptionInterface;
- [ ] Add if class exist checks in the Container file?
- [ ] Rename Container.php to SimpleContainer.php
- [ ] Show stack trace when I have a debug only?
- [ ] PHP 8 named arguments and autowiring.
- [ ] Allow to set definitions via `__constructor`.
- [ ] Add supporting Code Driven IoC.
- [ ] Add configurations of Container.
- [ ] Add Performance Benchmarks

## License

Expand Down
25 changes: 20 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
{
"name": "pisarevskii/simple-dic",
"description": "Simple DI Container with autowiring for your PHP application or WordPress plugins.",
"name": "renakdup/simple-php-dic",
"description": "Simple DI Container with autowiring for your WordPress application with NO dependencies.",
"type": "library",
"license": "MIT",
"keywords": [
"dic",
"di container",
"simple dic",
"dic autowiring",
"simple php dic",
"wordpress dic",
"wordpress di container",
"wp",
"wordpress",
"wordpress plugin",
"wordpress mu-plugin",
"wordpress-library",
"wp plugin",
"mu-plugin"
],
"authors": [
{
"name": "Andrei Pisarevskii",
Expand All @@ -22,8 +37,8 @@
},
"autoload-dev": {
"psr-4": {
"Pisarevskii\\SimpleDIC\\": "src/",
"PisarevskiiTests\\SimpleDIC\\": "tests/"
"Renakdup\\SimpleDIC\\": "src/",
"RenakdupTests\\SimpleDIC\\": "tests/"
}
},
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
</coverage>

<testsuites>
<testsuite name="pisarevskii-simple-dic Test Suite">
<testsuite name="renakdup-simple-dic Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
Expand Down
109 changes: 32 additions & 77 deletions src/Container.php
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
<?php // phpcs:ignoreFile
/**
* Simple PHP DIC - DI Container in one file.
* Simple PHP DIC - DI Container in one file for WordPress.
* Supports autowiring and allows you to easily use it in your simple PHP applications and
* especially convenient for WordPress plugins and themes.
*
* Author: Andrei Pisarevskii
* Author Email: [email protected]
* Author Site: https://wp-yoda.com/en/
*
* Version: 0.2.6
* Version: 1.0
* Source Code: https://github.com/renakdup/simple-php-dic
*
* Licence: MIT License
*/

declare( strict_types=1 );

namespace Pisarevskii\SimpleDIC;
namespace Renakdup\SimpleDIC;

use Closure;
use InvalidArgumentException;
use Exception;
use ReflectionClass;
use ReflectionException;
use ReflectionNamedType;
Expand All @@ -29,58 +29,7 @@
use function class_exists;
use function is_string;

######## PSR11 2.0 interfaces #########
# If you want to support PSR11, then remove 3 interfaces below
# (ContainerInterface, ContainerExceptionInterface, NotFoundExceptionInterface)
# and import PSR11 interfaces in this file:
# -----
# use Psr\Container\ContainerExceptionInterface;
# use Psr\Container\ContainerInterface;
# use Psr\Container\NotFoundExceptionInterface;
###############################
interface ContainerInterface {
/**
* Finds an entry of the container by its identifier and returns it.
*
* @param string $id Identifier of the entry to look for.
*
* @return mixed Entry.
*
* @throws ContainerExceptionInterface Error while retrieving the entry.
* @throws NotFoundExceptionInterface No entry was found for **this** identifier.
*/
public function get( string $id );

/**
* Returns true if the container can return an entry for the given identifier.
* Returns false otherwise.
*
* `has($id)` returning true does not mean that `get($id)` will not throw an exception.
* It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`.
*
* @param string $id Identifier of the entry to look for.
*
* @return bool
*/
public function has( string $id ): bool;
}

/**
* Base interface representing a generic exception in a container.
*/
interface ContainerExceptionInterface extends \Throwable {}

/**
* No entry was found in the container.
*/
interface NotFoundExceptionInterface extends ContainerExceptionInterface {}
######## PSR11 interfaces - END #########


###############################
# Simple DIC code
###############################
class Container implements ContainerInterface {
class Container {
/**
* @var mixed[]
*/
Expand All @@ -99,8 +48,7 @@ class Container implements ContainerInterface {
public function __construct() {
// Auto-register the container
$this->resolved = [
self::class => $this,
ContainerInterface::class => $this,
self::class => $this,
];
}

Expand All @@ -117,7 +65,14 @@ public function set( string $id, $service ): void {
}

/**
* {@inheritdoc}
* Finds an entry of the container by its identifier and returns it.
*
* @param string $id Identifier of the entry to look for.
*
* @return mixed Entry.
*
* @throws Exception Error while retrieving the entry.
* || No entry was found for **this** identifier.
*/
public function get( string $id ) {
if ( isset( $this->resolved[ $id ] ) || array_key_exists( $id, $this->resolved ) ) {
Expand All @@ -132,7 +87,15 @@ public function get( string $id ) {
}

/**
* @inheritdoc
* Returns true if the container can return an entry for the given identifier.
* Returns false otherwise.
*
* `has($id)` returning true does not mean that `get($id)` will not throw an exception.
* It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`.
*
* @param string $id Identifier of the entry to look for.
*
* @return bool
*/
public function has( string $id ): bool {
return array_key_exists( $id, $this->services );
Expand All @@ -143,22 +106,20 @@ public function has( string $id ): bool {
* dependencies will not instantiate every time. If dependencies were resolved before
* then they will be passed as resolved dependencies.
*
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws Exception
*/
public function make( string $id ): object {
if ( ! class_exists( $id ) ) {
$message = "Service `{$id}` could not be resolved because class not exist.";
throw new ContainerException( $message );
throw new Exception( $message );
}

return $this->resolve_object( $id );
}

/**
* @return mixed
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws Exception
*/
protected function resolve( string $id ) {
if ( $this->has( $id ) ) {
Expand All @@ -177,15 +138,14 @@ protected function resolve( string $id ) {
return $this->resolve_object( $id );
}

throw new ContainerNotFoundException( "Service `{$id}` not found in the Container." );
throw new Exception( "Service `{$id}` not found in the Container." );
}

/**
* @param class-string $service
*
* @return object
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws Exception
*/
protected function resolve_object( string $service ): object {
try {
Expand All @@ -206,7 +166,7 @@ protected function resolve_object( string $service ): object {
$resolved_params = $this->resolve_parameters( $params );

} catch ( ReflectionException $e ) {
throw new ContainerException(
throw new Exception(
"Service `{$service}` could not be resolved due the reflection issue: `{$e->getMessage()}`"
);
}
Expand All @@ -218,7 +178,7 @@ protected function resolve_object( string $service ): object {
* @param ReflectionParameter[] $params
*
* @return mixed[]
* @throws ContainerExceptionInterface
* @throws Exception
* @throws ReflectionException
*/
protected function resolve_parameters( array $params ): array {
Expand All @@ -234,7 +194,7 @@ protected function resolve_parameters( array $params ): array {
* @param ReflectionParameter $param
*
* @return mixed|object
* @throws ContainerExceptionInterface
* @throws Exception
* @throws ReflectionException
*/
protected function resolve_parameter( ReflectionParameter $param ) {
Expand All @@ -250,7 +210,7 @@ protected function resolve_parameter( ReflectionParameter $param ) {

// @phpstan-ignore-next-line - Cannot call method getName() on ReflectionClass|null.
$message = "Parameter `{$param->getName()}` of `{$param->getDeclaringClass()->getName()}` can't be resolved.";
throw new ContainerException( $message );
throw new Exception( $message );
}

protected function get_stack_trace(): string {
Expand All @@ -274,8 +234,3 @@ protected function get_stack_trace(): string {
return $stackTraceString;
}
}

class ContainerNotFoundException extends InvalidArgumentException implements NotFoundExceptionInterface {}

class ContainerException extends InvalidArgumentException implements ContainerExceptionInterface {}

2 changes: 1 addition & 1 deletion tests/Assets/AbstractClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare( strict_types=1 );

namespace PisarevskiiTests\SimpleDIC\Assets;
namespace RenakdupTests\SimpleDIC\Assets;

abstract class AbstractClass {

Expand Down
Loading

0 comments on commit b7b7de8

Please sign in to comment.