Skip to content

Commit 8b38e08

Browse files
authored
Merge pull request #3 from MaplePHP/develop
v2.0.0 - Improve code quality and ensure compatibility with PHP 8.1+
2 parents fdfe299 + 437bdde commit 8b38e08

14 files changed

Lines changed: 242 additions & 140 deletions

Interfaces/ContainerExceptionInterface.php

Lines changed: 0 additions & 12 deletions
This file was deleted.

Interfaces/ContainerInterface.php

Lines changed: 0 additions & 49 deletions
This file was deleted.

Interfaces/NotFoundExceptionInterface.php

Lines changed: 0 additions & 10 deletions
This file was deleted.

README.md

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@ Container, Factories and dependency injectors will help to make your PHP code mo
1414
Containers allowing you to easily create and retrieve objects that are needed throughout your application.
1515
```php
1616
use MaplePHP\Container\Container;
17+
1718
$container = new Container();
18-
$container->set("YourClass", \YourNamespace\To\YourClass::class); // Bind "YourClass" to container and dependency injector
19-
$yourClass = $container->get("YourClass")->get(); // Will return "YourClass"
20-
//$yourClass->yourClassMehthod();
19+
20+
// You can set mixed values in the container
21+
$container->set("hasEmail", true);
22+
23+
$hasEmail = $container->get("hasEmail")->get();
24+
var_dump($hasEmail); // Result in: (bool) true
2125
```
2226
If the constructor of "YourClass" contains unresolved class arguments, the dependency injector will attempt to automatically locate them for you. Read more under the headline **dependency injector**.
2327

@@ -40,32 +44,16 @@ Take a look at this example
4044

4145
```php
4246

43-
$container->set("YourClass", \YourNamespace\To\YourClass::class);
44-
$testService = $container->get("YourClass");
45-
echo $testService->start();
46-
47-
```
48-
The above code will load **YourClass** and auto initialize the class **Test**.
49-
50-
```php
51-
namespace YourNamespace\To;
52-
53-
use YourNamespace\ToTestClasses\Test;
54-
55-
class YourClass {
56-
57-
private $test;
47+
use MaplePHP\Container\Container;
48+
use MaplePHP\Container\Autowire;
49+
use App\Services\MailService;
5850

59-
// Dependency injector will auto load "Test" class and the "Test" classes and so on.
60-
function __construct(Test $test) {
61-
$this->test = $test;
62-
}
51+
$container = new Container();
52+
$container->set("MailService", new Autowire(MailService::class));
6353

64-
function start() {
65-
return $this->test->get("This is the start page");
66-
}
67-
68-
}
54+
// This will return "MailService" with all dependencies resolved on constructor
55+
$mailService = $container->get("MailService")->get();
56+
echo $mailService->send();
6957
```
7058

7159
## Event handler

composer.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
{
22
"name": "maplephp/container",
33
"type": "library",
4-
"version": "v1.1.4",
54
"description": "Container, Factories and dependency injectors with full PSR-11 support.",
65
"keywords": [
76
"container",
8-
"psr11",
7+
"PSR-11",
98
"factories",
109
"dependency injectors",
1110
"injectors"
@@ -23,12 +22,13 @@
2322
}
2423
],
2524
"require": {
26-
"php": ">=8.0",
27-
"maplephp/dto": "^3.0"
25+
"php": ">=8.2",
26+
"psr/container": "^2.0",
27+
"maplephp/dto": "^3.1"
2828
},
2929
"autoload": {
3030
"psr-4": {
31-
"MaplePHP\\Container\\": ""
31+
"MaplePHP\\Container\\": "src"
3232
}
3333
},
3434
"minimum-stability": "dev"

src/Autowire.php

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MaplePHP\Container;
6+
7+
use MaplePHP\Container\Interfaces\AutowireInterface;
8+
9+
class Autowire implements AutowireInterface
10+
{
11+
private Reflection $reflect;
12+
/**
13+
* @var mixed|object|null
14+
*/
15+
private mixed $class = null;
16+
private bool $disableDI = false;
17+
18+
/**
19+
* @param string $class
20+
* @throws \ReflectionException
21+
*/
22+
public function __construct(string $class)
23+
{
24+
if (is_string($class) && class_exists($class)) {
25+
$this->reflect = new Reflection($class);
26+
} else {
27+
throw new \InvalidArgumentException("The class {$class} does not exist.");
28+
}
29+
}
30+
31+
/**
32+
* Disable the dependency injector
33+
*
34+
* Note: This method MUST be implemented in such a way as to retain the immutability
35+
*
36+
* @return $this
37+
*/
38+
public function disableDI(): self
39+
{
40+
$inst = clone $this;
41+
$inst->disableDI = true;
42+
return $inst;
43+
}
44+
45+
/**
46+
* Pass custom arguments to the class constructor
47+
*
48+
* Note: This method MUST be implemented in such a way as to retain the immutability
49+
* NOTE: This will disable the dependency injector
50+
*
51+
* @param array $args
52+
* @return $this
53+
*/
54+
public function addArgs(array $args): self
55+
{
56+
if (count($args) <= 0) {
57+
throw new \InvalidArgumentException("You must provide at least one argument.");
58+
}
59+
$inst = $this->disableDI();
60+
$inst->reflect->setArgs($args);
61+
return $inst;
62+
}
63+
64+
/**
65+
* Run the class with all dependencies.
66+
*
67+
* @return mixed
68+
* @throws \ReflectionException
69+
*/
70+
public function run(): mixed
71+
{
72+
if (is_null($this->class)) {
73+
$this->class = ($this->disableDI) ? $this->reflect->get() : $this->reflect->dependencyInjector();
74+
}
75+
return $this->class;
76+
}
77+
}

Container.php renamed to src/Container.php

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
namespace MaplePHP\Container;
66

77
use Closure;
8-
use MaplePHP\Container\Interfaces\ContainerInterface;
8+
use MaplePHP\Container\Interfaces\AutowireInterface;
9+
use Psr\Container\ContainerInterface;
910
use MaplePHP\Container\Interfaces\FactoryInterface;
1011
use MaplePHP\DTO\Format\Arr;
1112
//use MaplePHP\Container\Reflection;
@@ -34,10 +35,10 @@ public function __call($method, $args)
3435
* TestClasses\Test::class,
3536
* TestClasses\Test::class."::__construct",
3637
* TestClasses\Test::class."::getStaticMethod",
37-
* @param array|null $args Pass argumnets to constructor staticMethod if you choose.
38+
* @param array|null $args Pass arguments to constructor staticMethod if you choose.
3839
* @param bool $overwrite Will throw exception if already been defined if not arg is set to TRUE.
3940
*/
40-
public function set(string $identifier, $value, ?array $args = null, bool $overwrite = false): ContainerInterface
41+
public function set(string $identifier, mixed $value, ?array $args = null, bool $overwrite = false): ContainerInterface
4142
{
4243
if (!$overwrite && $this->has($identifier)) {
4344
$type = ($this->isFactory($identifier)) ? "factory" : "container";
@@ -112,27 +113,26 @@ public function isContainer(string $identifier): bool
112113

113114
/**
114115
* Get a container or factory
115-
* @param string $identifier [description]
116-
* @param array $args Is possible to overwrite/add __construct or method argumnets
117-
* @return mixed
116+
* @template T of object
117+
* @param class-string<T>|string $identifier The class or service identifier
118+
* @param string $identifier
119+
* @param array $args Is possible to overwrite/add __construct or method arguments
120+
* @return T
118121
* @throws ReflectionException
119122
*/
120123
public function get(string $identifier, array $args = []): mixed
121124
{
122-
if ($service = $this->getService($identifier)) {
125+
$service = $this->getService($identifier);
126+
if (isset($service)) {
123127
if (count($args) === 0) {
124128
$args = $this->getArgs($identifier);
125129
}
126130
if ($this->isFactory($identifier)) {
127131
$this->getter[$identifier] = $service(...$args);
128132
} else {
129-
if (empty($this->getter[$identifier])) {
130-
if (is_string($service) && class_exists($service)) {
131-
$reflect = new Reflection($service);
132-
if (count($args) > 0) {
133-
$reflect->setArgs($args);
134-
}
135-
$this->getter[$identifier] = $reflect->get();
133+
if (!isset($this->getter[$identifier])) {
134+
if ($service instanceof AutowireInterface) {
135+
$this->getter[$identifier] = $service->run();
136136
} else {
137137
$this->getter[$identifier] = $service;
138138
}
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,18 @@ public function addHandler(object|string $handler, string|array $method = null):
5151
public function addEvent(callable|object|string $event, ?string $bind = null): void
5252
{
5353

54-
if(!is_callable($event)) {
55-
if(is_string($event)) {
54+
if (!is_callable($event)) {
55+
if (is_string($event)) {
5656
$reflect = new Reflection($event);
5757
$event = $reflect->get();
5858
}
5959

60-
if(is_object($event) && !($event instanceof EventInterface)) {
60+
if (is_object($event) && !($event instanceof EventInterface)) {
6161
throw new Exception("Event object/class needs to be instance of \"EventInterface\"!", 1);
6262
}
6363
}
6464

65-
if (is_null($bind)) {
65+
if ($bind === null) {
6666
$this->event[] = $event;
6767
} else {
6868
$this->event[] = [$bind => $event];
@@ -95,7 +95,7 @@ public function __call(string $method, array $args): mixed
9595
throw new BadMethodCallException("The method \"".$method."\" does not exist in the class (" . $handler[0]::class . ")", 1);
9696
}
9797
*/
98-
if (is_null($handler[1][0]) || in_array($method, $handler[1])) {
98+
if ($handler[1][0] === null || in_array($method, $handler[1])) {
9999
$this->bindable[$method] = $method;
100100
}
101101
$data = call_user_func_array([$handler[0], $method], $args);
@@ -136,7 +136,7 @@ final protected function triggerEvents(): void
136136
*/
137137
final protected function getEvent(callable|object $data): void
138138
{
139-
if(is_callable($data)) {
139+
if (is_callable($data)) {
140140
$data();
141141
} else {
142142
$data->resolve();
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace MaplePHP\Container\Exceptions;
44

55
use InvalidArgumentException;
6-
use MaplePHP\Container\Interfaces\ContainerExceptionInterface;
6+
use Psr\Container\ContainerExceptionInterface;
77

88
/**
99
* Base interface representing a generic exception in a container.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace MaplePHP\Container\Exceptions;
44

5-
use MaplePHP\Container\Interfaces\NotFoundExceptionInterface;
5+
use Psr\Container\NotFoundExceptionInterface;
66
use RuntimeException;
77

88
/**

0 commit comments

Comments
 (0)