Php 将超出范围的数据传递到服务容器

Php 将超出范围的数据传递到服务容器,php,service,dependency-injection,closures,pimple,Php,Service,Dependency Injection,Closures,Pimple,我希望创建SomeService的一个新实例,该实例必须注入一些在Pimple中定义服务时未知的数据。以下技术上可行,但肯定不是正确的方法。如何做到这一点 <?php use Pimple\Container; class SomeService { private $theNewData; public function __construct(MyPdo $pdo, array $theNewData){ $this->theNewData=$t

我希望创建
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());

除了使用Pimple作为临时传输之外,我如何将此内容注入到其他服务中

我认为这个问题的根本原因是,
未来的数据
实际上正如其名称所示是数据,并且随着时间的推移它会发生多次更改,因此不应该在定义服务时将其传递给服务,而应该在每次服务中的使用者方法(
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());
使用丘疹的
raw()
方法

$container->raw('someService')($container, $someFutureData);
需要设置服务以接受新数据

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

@下流选民。请让我知道你为什么认为这是一个糟糕的解决方案。感谢Hanks Nima,对于这两种解决方案,我们如何将数据输入数据提供者?在您的示例中,
$someFutureData
来自哪里<代码>数据提供程序
应负责从同一来源获取数据。对我来说,这取决于实际的用例。数据可以从数据库中获取,也可以是一些硬编码数组,如您的示例。我可以问一下这些数据是如何以及何时可用的吗?嗨,尼玛,应用程序是一个套接字服务器而不是http服务器,因此持续运行,
$someFutureData
通过tcp套接字连接来自客户端请求。在这种情况下,DataProvider不应该首先负责获取数据吗?或者可能是另一个负责获取数据并将其传递(即调用另一个服务,而不是由该服务调用)到需要该数据的主服务的更相关的服务?但是我有一个问题,这个未来的数据是否需要传递给构造函数?这看起来更像是实际数据而不是配置,因此可以将其传递给需要数据的最终方法。类似于
$service->getJsonString($someData)
的东西。也许是我在词汇上的拙劣选择。另一个服务负责获取数据。该服务最终需要对数据执行工作,并将该数据传递给新对象的构造函数是有利的。我曾经读过这样一篇文章,人们应该尽早定义对象,而不是深入到某些脚本中,并且正在尝试这样做。