Есть ли у php способ остановить цепочку вызовов, если вводится нулевое значение? - PullRequest
2 голосов
/ 11 февраля 2020

Я хотел бы сделать self::container()->get($path);, но self::container() может вернуть null.

Есть ли более быстрый способ избежать ошибки Call to a member function get() on null при связывании вызовов функций, и некоторые могут вернуть ноль вместо объект?

Есть ли лучший способ, чем безобразный обходной путь насмешки над ожидаемым объектом / членом?

public static function getDependency($path) {
 return self::container() ??
  (new class{public function get($path){return null;}})->get($path);
}

Что мне нужно, это что-то вроде null оператор доступа к условному члену (?.) в C#

1 Ответ

2 голосов
/ 11 февраля 2020

Краткий ответ: нет, в PHP такого нет.

Я бы ни за что не стал делать волхвы c, как тот, который вы предложили.

Делать :

<?php
public static function getDependency($path) {
    $container = self::container();
    if ($container instanceof ContainerInterface) {
        return $container->get($path);
    }
}

было бы легче читать / понимать.

Теперь, что касается null, это было описано его собственным создателем (Тони Хоаром) "The Billion Dollar Ошибка ".

Лучшим подходом было бы, чтобы self::container() имел бы тип возврата ContainerInterface без возможности быть null. Пытаясь вернуть null, он выдаст TypeError, который потенциально может быть пойман. Таким образом, вызов ->get() никогда не произойдет, так как исключение будет выдано ранее.

Если self::container() вернуть что-то вроде ContainerInterface|null, то всех вызывающих будет реализовано. logi c в качестве предложенного вами, что также приведет к (большому количеству) дублированного кода.

По той же причине вам, вероятно, будет безопаснее иметь указанный тип возвращаемого значения c для вашего зависимость:

<?php
public static function getServiceFoo($path): ServicFoo {
    $container = self::container();
    if (!$container instanceof ContainerInterface) {
        throw new RuntimeException("Not a valid container received");
    }

    return $container->get($path);
}

В противном случае вы столкнетесь с той же проблемой на getServiceFoo(), что у вас уже была на self::container().

...