Какое исключение PHP генерировать, когда последний метод в цепочке требует другого метода, вызываемого первым - PullRequest
0 голосов
/ 09 октября 2019

Я пишу библиотеку в стиле построителя запросов PHP, которая использует цепочку методов для добавления ограничений в запрос с последним вызовом get() в конце для выполнения запроса, аналогично построителю запросов Laravel, но с использованием общедоступного JSONAPI через Guzzle для данных. Например:

// valid
Foo::queryType()->take(5)->skip(50)->get();

// invalid, missing query type
Foo::take->(5)->get();

Foo - это просто фасад для доступа к библиотеке. queryType() является обязательным начальным методом (может быть одним из многих, например queryTypeA(), queryTypeB()), который устанавливает переменную защищенного класса в Foo. Я хочу выбросить Exception, если get() вызывается без того, чтобы эта переменная была установлена ​​первой. И я хочу быть точным в том, что бросили.

Документация PHP перечисляет несколько вариантов:

  • BadMethodCallException:

    Исключение выдается, если обратный вызов ссылается на неопределенный метод или если отсутствуют некоторые аргументы.

Возможно, не ссылается на отсутствующие предварительные условия, и я получаюощущение, что это больше предназначено для динамических вызовов, где метод не существует.

  • BadFunctionCallException

    Исключение выдается, если обратный вызов ссылается на неопределенную функциюили если некоторые аргументы отсутствуют.

В основном то же, что и раньше, но для общих функций , и BadMethodCallException на самом деле является дочерним классом этого.

  • InvalidArgumentException

    Исключение выдается, если аргумент не относится к ожидаемому типу.

Хотя технически это не аргумент , неустановленная переменная защищенного класса, необходимая для продолжения выполнения, соответствует общей идее. Таким образом, это имеет смысл на данный момент.

  • UnexpectedValueException

    Исключение выдается, если значение не совпадает с набором значений. Обычно это происходит, когда функция вызывает другую функцию и ожидает, что возвращаемое значение будет иметь определенный тип или значение, не включая арифметические или связанные с буфером ошибки.

Не совсем вариант;в то время как само название подразумевает, что мне может потребоваться противоположное этому - я ожидаю значение, которое будет установлено, а его нет - описание кажется менее подходящим, чем другие, и нет пользовательских замечаний, которые могли бы помочь уточнить.

  • RuntimeException

    Исключение выдается, если возникает ошибка, которая может быть обнаружена только во время выполнения.

Мой запасной вариант. Может я обдумываю это? Какое исключение PHP имеет больше смысла?

1 Ответ

0 голосов
/ 10 октября 2019

Основываясь на дизайне моей библиотеки, я выбрал BadMethodCallException. Поскольку внешний класс был просто фасадом, я использовал магический метод __call для прохождения через любые неопределенные вызовы метода внутренней переменной класса.

После прохождения вызова внутренней переменной класса задается значение null, чтобы буквально отменить определение вызова метода. Однако для того, чтобы отличать неопределенные методы от цепочки не по порядку, я явно проверяю переменную класса на нулевое значение и выдаю конкретную ошибку.

protected $request = null;

/**
 * Pass through non-explicitly defined method calls to the internal request class
 * @param  string $function
 * @param  array $args
 * @return mixed
 * @throws \BadMethodCallException
 */
public function __call($function, $args)
{
    if ($this->request === null) {
        throw new \BadMethodCallException('Must specify request type before chaining constraints.');
    }

    if (method_exists($this->request, $function)) {
        $result = $this->request->$function(sizeof($args) ? $args[0] : null);

        $this->request = null;

        return $result;
    }

    throw new \BadMethodCallException('Method \'' . $function . '()\' does not exist.');
}
...