共享同一对象实例:Auryn 与 PHP-DI
Sharing the same instance of an object: auryn vs. PHP-DI
我正在尝试构建我的第一个无框架 PHP 应用程序并且我正在关注 this tutorial。
我对教程中描述的一些概念比较陌生。尽管如此,我还是决定使用 PHP-DI instead of the suggested one (rdlowrey/auryn) 作为依赖注入器。
除了文件 Bootstrap.php
(和文件 Dependencies.php
:
之外,我已经根据教程创建了所有内容
<?php declare(strict_types = 1);
require(__DIR__ . '/../vendor/autoload.php');
...
$container = include('Dependencies.php');
$request = $container->make('Http\HttpRequest');
$response = $container->make('Http\HttpResponse');
...
switch ($routeInfo[0]) {
...
case \FastRoute\Dispatcher::FOUND:
$className = $routeInfo[1][0];
$method = $routeInfo[1][1];
$vars = $routeInfo[2];
$class = $container->make($className);
$class->$method($vars); // (**)
break;
}
echo $response->getContent(); // (*)
$class
只能是 Homepage
class 的一个实例,它只有一个方法 (show()
),在 (**) 中调用:
class Homepage
{
private $request;
private $response;
private $renderer;
public function __construct(
Request $request,
Response $response,
Renderer $renderer
) {
$this->request = $request;
$this->response = $response;
$this->renderer = $renderer;
}
public function show() {
$data = [
'name' => $this->request->getParameter('name', 'stranger'),
];
$html = $this->renderer->render('Homepage', $data);
$this->response->setContent($html); // (***)
}
}
综上所述,应用程序 returns 一个带有空主体的 200 HTTP 响应 [此处 (*)]
但是如果我尝试在 (***) 之后打印 HTTP 响应的内容,我会得到正确的响应。
这可能意味着 HttpResponse class 有两个不同的实例。 (对吗?)
教程的作者rdlowrey/auryn使用方法share()
在classes之间共享同一个HttpReponse实例,如"original"所示Dependencies.php
文件:
<?php declare(strict_types = 1);
use \Auryn\Injector;
...
$injector = new Injector;
$injector->alias('Http\Response', 'Http\HttpResponse');
$injector->share('Http\HttpResponse');
...
return $injector;
有没有办法使用 PHP-DI(具有 PHP 定义)获得相同的行为?
这是我的 Dependencies.php
版本:
<?php declare(strict_types = 1);
$definitions = [
'Http\Request' => DI\create('Http\HttpRequest')->constructor(
$_GET, $_POST, $_COOKIE, $_FILES, $_SERVER),
'Http\HttpRequest' => function () {
$r = new Http\HttpRequest($_GET, $_POST, $_COOKIE, $_FILES, $_SERVER);
return $r;
},
'Http\Response' => DI\create('Http\HttpResponse'),
'Twig\Environment' => function () {
$loader = new Twig\Loader\FilesystemLoader(
dirname(__DIR__) . '/templates');
$twig = new Twig\Environment($loader);
return $twig;
},
'Example\Template\TwigRenderer' => function (Twig\Environment $renderer) {
return new Example\Template\TwigRenderer($renderer);
},
'Example\Template\Renderer' => DI\create(
'Example\Template\TwigRenderer')->constructor(
DI\get('Twig\Environment')),
];
$containerBuilder = new DI\ContainerBuilder;
$containerBuilder->addDefinitions($definitions);
$container = $containerBuilder->build();
return $container;
在 Bootstrap.php
中,获取 (get()
) HttpRequest
/HttpResponse
个实例,而不是创建 (make()
) 个实例,解决了问题。
...
$container = include('Dependencies.php');
$request = $container->get('Http\HttpRequest');
$response = $container->get('Http\HttpResponse');
...
正如 documentation 中明确指出的那样:
The make() method works like get() except it will resolve the entry
every time it is called. [..] if the entry is an object, an new instance will be created every time [..]
我正在尝试构建我的第一个无框架 PHP 应用程序并且我正在关注 this tutorial。 我对教程中描述的一些概念比较陌生。尽管如此,我还是决定使用 PHP-DI instead of the suggested one (rdlowrey/auryn) 作为依赖注入器。
除了文件 Bootstrap.php
(和文件 Dependencies.php
:
<?php declare(strict_types = 1);
require(__DIR__ . '/../vendor/autoload.php');
...
$container = include('Dependencies.php');
$request = $container->make('Http\HttpRequest');
$response = $container->make('Http\HttpResponse');
...
switch ($routeInfo[0]) {
...
case \FastRoute\Dispatcher::FOUND:
$className = $routeInfo[1][0];
$method = $routeInfo[1][1];
$vars = $routeInfo[2];
$class = $container->make($className);
$class->$method($vars); // (**)
break;
}
echo $response->getContent(); // (*)
$class
只能是 Homepage
class 的一个实例,它只有一个方法 (show()
),在 (**) 中调用:
class Homepage
{
private $request;
private $response;
private $renderer;
public function __construct(
Request $request,
Response $response,
Renderer $renderer
) {
$this->request = $request;
$this->response = $response;
$this->renderer = $renderer;
}
public function show() {
$data = [
'name' => $this->request->getParameter('name', 'stranger'),
];
$html = $this->renderer->render('Homepage', $data);
$this->response->setContent($html); // (***)
}
}
综上所述,应用程序 returns 一个带有空主体的 200 HTTP 响应 [此处 (*)] 但是如果我尝试在 (***) 之后打印 HTTP 响应的内容,我会得到正确的响应。 这可能意味着 HttpResponse class 有两个不同的实例。 (对吗?)
教程的作者rdlowrey/auryn使用方法share()
在classes之间共享同一个HttpReponse实例,如"original"所示Dependencies.php
文件:
<?php declare(strict_types = 1);
use \Auryn\Injector;
...
$injector = new Injector;
$injector->alias('Http\Response', 'Http\HttpResponse');
$injector->share('Http\HttpResponse');
...
return $injector;
有没有办法使用 PHP-DI(具有 PHP 定义)获得相同的行为?
这是我的 Dependencies.php
版本:
<?php declare(strict_types = 1);
$definitions = [
'Http\Request' => DI\create('Http\HttpRequest')->constructor(
$_GET, $_POST, $_COOKIE, $_FILES, $_SERVER),
'Http\HttpRequest' => function () {
$r = new Http\HttpRequest($_GET, $_POST, $_COOKIE, $_FILES, $_SERVER);
return $r;
},
'Http\Response' => DI\create('Http\HttpResponse'),
'Twig\Environment' => function () {
$loader = new Twig\Loader\FilesystemLoader(
dirname(__DIR__) . '/templates');
$twig = new Twig\Environment($loader);
return $twig;
},
'Example\Template\TwigRenderer' => function (Twig\Environment $renderer) {
return new Example\Template\TwigRenderer($renderer);
},
'Example\Template\Renderer' => DI\create(
'Example\Template\TwigRenderer')->constructor(
DI\get('Twig\Environment')),
];
$containerBuilder = new DI\ContainerBuilder;
$containerBuilder->addDefinitions($definitions);
$container = $containerBuilder->build();
return $container;
在 Bootstrap.php
中,获取 (get()
) HttpRequest
/HttpResponse
个实例,而不是创建 (make()
) 个实例,解决了问题。
...
$container = include('Dependencies.php');
$request = $container->get('Http\HttpRequest');
$response = $container->get('Http\HttpResponse');
...
正如 documentation 中明确指出的那样:
The make() method works like get() except it will resolve the entry every time it is called. [..] if the entry is an object, an new instance will be created every time [..]