1

我希望创建一个新实例,SomeService该实例必须注入一些在 Pimple 中定义服务时未知的数据。以下在技术上有效,但肯定不是这样做的正确方法。这应该如何实现?

<?php
use Pimple\Container;

class SomeService
{
    private $theNewData;
    public function __construct(MyPdo $pdo, array $theNewData){
        $this->theNewData=$theNewData;
    }
    public function getJsonString():string{
        return json_encode($this->theNewData);
    }
}
class MyPdo{}

function getServiceSometimeInTheFuture(Container $container):SomeService {
    $someFutureData= ['a'=>1,'b'=>2,'c'=>3,];

    /*
    How do I inject this content into SomeService other than using Pimple as a temporary transport?
    */
    $container['temp']=$someFutureData;
    $newInstance=$container['someService'];
    unset($container['temp']);
    return $newInstance;
}

require '../vendor/autoload.php';

$container=new Container();

$container['myPdo'] = function ($c) {
    return new MyPdo();
};

$container['someService'] = $container->factory(function ($c) {
    return new SomeService($c['myPdo'], $c['temp']);
});

$service = getServiceSometimeInTheFuture($container);
echo($service->getJsonString());
4

2 回答 2

0

除了使用 Pimple 作为临时传输之外,如何将此内容注入到 SomeService 中?

我认为造成这个问题的根本原因future data是实际上是数据,顾名思义,随着时间的推移它会发生多次变化,所以它不应该在服务定义时传递给服务,而是每次服务中的消费者方法(getJsonString此处)需要该数据。

...定义服务时不知道

数据未知,但数据来源如何?您能否编写一个新服务来充当数据提供者,以便将来需要时原始服务可以获取所需的数据?

我可以提出两种解决方案。
(我故意从任何地方删除了 MyPdo,因为它根本没有使用,即使在构造函数中也是如此)

如果您确实需要在创建时将数据传递给服务:

<?php
require __DIR__ . '/../vendor/autoload.php';
use Pimple\Container;

class SomeService
{
    private $theNewData;
    public function __construct(array $theNewData){
        $this->theNewData=$theNewData;
    }
    public function getJsonString():string{
        return json_encode($this->theNewData);
    }
}

$container=new Container();

// Use pimple factory method to create new service instance, instead of creatng a custom function
$container['getServiceSometimeInTheFuture'] = $container->factory(function (Container $c):SomeService {
    return new SomeService($c['futureData']);
});

// `futureData` returns new data every time
$container['futureData'] = $container->factory(function(){
    return ['a' => rand(1, 10), 'b' => rand(1, 10), 'c' => rand(1, 10), ];
});

$service1 = $container['getServiceSometimeInTheFuture'];
$service2 = $container['getServiceSometimeInTheFuture'];

// Demonstrate how two different instances have different, persistent data
echo("\nservice 1:" . $service1->getJsonString());
echo("\nservice 2:" . $service2->getJsonString());
echo("\nservice 1:" . $service1->getJsonString());
echo("\nservice 2:" . $service2->getJsonString());

如果您可以在将来需要数据时推迟向服务提供数据:

<?php
require __DIR__ . '/../vendor/autoload.php';
use Pimple\Container;

// DataProvider decides what data should be provided to the service
class DataProvider {
    public function getData(){
        return ['a' => rand(1, 10), 'b' => rand(1, 10), 'c' => rand(1, 10), ];
    }
}

class SomeService
{
    private $dataProvider;
    public function __construct(DataProvider $dataProvider){
        $this->dataProvider=$dataProvider;
    }
    public function getJsonString():string{
        return json_encode($this->dataProvider->getData());
    }
}

$container=new Container();

// Use pimple factory method to create new service instance, instead of creatng a custom function
$container['getServiceSometimeInTheFuture'] = $container->factory(function (Container $c):SomeService {
    return new SomeService($c['dataProvider']);
});

$container['dataProvider'] = function() {
    return new DataProvider;
};

$service = $container['getServiceSometimeInTheFuture'];

// Demonstrate how THE SAME INSTANCE will have different data every time
echo("\n" . $service->getJsonString());
echo("\n" . $service->getJsonString());
echo("\n" . $service->getJsonString());
echo("\n" . $service->getJsonString());
于 2019-12-05T05:22:38.143 回答
-1

使用 Pimple 的raw()方法。

$container->raw('someService')($container, $someFutureData);

需要设置该服务以接受新数据。

$container['someService'] = $container->factory(function ($c, $data) {
    return new SomeService($c['myPdo'], $data);
});
于 2019-12-05T13:02:00.440 回答