繁体   English   中英

共享对象的同一个实例:auryn 与 PHP-DI

[英]Sharing the same instance of an object: auryn vs. PHP-DI

我正在尝试构建我的第一个无框架 PHP 应用程序,我正在关注本教程 我对教程中描述的一些概念比较陌生。 尽管如此,我还是决定使用PHP-DI作为依赖注入器,而不是建议的( 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类的一个实例,它只有一个方法 ( 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); // (***)
    }
}

尽管如此,应用程序返回一个带有空正文的 200 HTTP 响应 [here (*)] 但是如果我尝试在 (***) 之后打印 HTTP 响应的内容,我会得到正确的响应。 这可能意味着 HttpResponse 类有两个不同的实例。 (那正确吗?)

通过使用 rdlowrey/auryn,教程的作者,使用方法share()在类之间共享相同的 HttpReponse 实例,如“原始” 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');
...

正如文档中明确指出的:

make() 方法的工作方式与 get() 类似,只是它每次被调用时都会解析条目。 [..] 如果条目是一个对象,则每次 [..] 都会创建一个新实例

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM