динамический SQL — Аргументы Исключения PHP

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

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

throw Exception('template has invalid tag');

Подобная ошибка не очень полезна без имени тега:

throw Exception('template has invalid tag: '.$tag);

Это было бы трудно локализовать и может привести к всевозможным проблемам с инъекцией.

ВОПРОС: Каков наилучший способ передачи дополнительных переменных с помощью Exception в PHP?

(примечание: моя библиотека выполняет построение SQL-запросов, и я бы предпочел, чтобы она была сосредоточена на задаче, а не на решении проблем с исключениями)

4

Решение

Интернационализация не является ответственность вашей библиотеки. Создать один или несколько Exception занятия для вашего проекта \Exception не рекомендуется, так как это слишком универсально), и пусть они хранят параметры в свойствах.

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

Например, вы объявляете в своей библиотеке:

class InvalidTagException extends \Exception
{
protected $tag;

public function __construct($message, $tag, $code = 0, Throwable $previous = NULL)
{
// Let the parent class initialize its members
parent::__construct($message, $code, $previous);
// Initialize own members
$this->tag = $tag;
}

public function getTag()
{
return $tag;
}
}

// Declare other Exception classes in a similar fashion, for each kind of exception you throw
class InvalidValueException extends \Exception
{
// ...
}

Приложение, которое использует вашу библиотеку:

try {
// call your library code here
} catch (InvalidTagException $e) {
// Handle in application specific way

} catch (InvalidValueException $e) {
// A different type of exception requires a different type of handling
}
4

Другие решения

Вы можете определить свой собственный класс исключений и добавить переменные в конструктор.

Например:

class AnswerException extends \Exception
{
protected $group;
public function __construct($message = "",  $group = null, $code = 0, \Exception $previous = null){
$this->group = $group;
return parent::__construct($message, $code, $previous);
}
public function getGroup(){
return $this->group;
}
}

В этом случае вы можете вызвать исключение, используя следующий синтаксис:

throw new AnswerException('template has invalid tag',$tag);

Тогда позже вы можете поймать AnswerException и использовать $exception->getGroup() функция.

3

Одним из возможных решений является использование sprintf как это:

throw new Exception(sprintf(_('template has invalid tag %s'), $tag));

где _() ваша функция локализации.

Но это не лучшее решение, потому что оно все еще открыто для html-инъекций и становится довольно грязным, когда вам нужно передать около 5 переменных. WordPress использует такой подход локализации, насколько я видел.

1