优雅地使Symfony服务工厂失败的正确方法是什么?

时间:2018-06-06 04:44:07

标签: php symfony service containers graceful-degradation

Symfony's documentation for service factories解释了如何允许服务容器使用工​​厂实例化服务,但没有解释创建失败时推荐的最佳实践,即服务因任何原因不可用时。

例如;想象一下Redis内存缓存服务。在工厂类中,您有一个实例化并返回Redis客户端对象的方法;

public function createRedisClient() {
  $redis = new \Redis();
  $connectionResult = $redis->connect($host, $port);

  return $redis;
}

如果Redis服务器暂时不可用,并且我希望能够优雅地回退到另一个存储我们拥有的数据的解决方案,那么工厂应该返回null,抛出某种特定类型的例外,或者根本不关心可用性?

2 个答案:

答案 0 :(得分:0)

您可以使用PHP的 is_object 方法:

    public function createRedisClient() {
      $redis = new \Redis();
      $connectionResult = $redis->connect($host, $port);
      if (!is_object($redis)) {
        return false;
      }
      return $redis;
}

返回值

如果var是对象,则返回 TRUE ,否则返回FALSE。

参考:PHP is_object

答案 1 :(得分:0)

如果你想要"后备"这里的解决方案最佳实践是在通用接口下对这些服务进行分组,而不是尝试一次实例化一个类似于"责任链":首先可以实例化,返回。 当然,在您的客户中,您将使用该界面,因此对于客户开发人员而言,此过程将非常简单。

获得此功能的最佳方法是使用SessionStorageFactory(通用版),您可以注册"所有具体工厂(RedisFactory,...,DefaultSessionStorageFactory)并尝试一次实例化一个。

当然缺点是,如果你需要一个"超集"属性(如hostport等)对所有工厂都没用,但是具体参数是必需的。