Как анализировать / проверять / обрабатывать заголовки http в PHP

В настоящее время я создаю свой собственный php-фреймворк и сейчас я создаю реализацию интерфейса PHP-FIG PSR-7 MessageInterface. В частности метод withHeader. В нем говорится, что метод может выдать исключение: \InvalidArgumentException для недопустимых имен или значений заголовков.

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

Теперь я могу сказать, что если заголовок имеет несколько значений, они разделяются запятыми. Но это не всегда применимо. Если я смотрю на заголовок агента пользователя, например, само значение иногда содержит запятую. Но вы должны рассматривать это как единую ценность.

2 ответа

Решение

Действительно, "опасно" передавать имя заголовка - в качестве аргумента withHeader(), который

  • является NULL
  • это не строка
  • пустая строка

То же самое относится к аргументу значения заголовка. Это должен быть массив или строка (представляющая только одно значение, а не список значений через запятую!).

Что касается реализации withHeader метод:

/**
 * Return an instance with the provided value replacing the specified header.
 *
 * ...
 *
 * @param string $name Case-insensitive header field name.
 * @param string|string[] $value Header value(s).
 * @return static
 * @throws \InvalidArgumentException for invalid header names or values.
 */
public function withHeader($name, $value) {
    $this
            ->validateHeaderName($name)
            ->validateHeaderValue($value)
    ;

    $clone = clone $this;

    $clone->replaceHeader($name, $value);

    return $clone;
}

/**
 * =================
 * Not part of PSR-7
 * =================
 * 
 * Validate header name.
 * 
 * @param string $name Case-insensitive header field name.
 * @return $this
 * @throws \InvalidArgumentException
 */
protected function validateHeaderName($name) {
    if (!isset($name)) {
        throw new \InvalidArgumentException('No header name provided!');
    }

    if (!is_string($name)) {
        throw new \InvalidArgumentException('The header name must be a string!');
    }

    if (empty($name)) {
        throw new \InvalidArgumentException('Empty header name provided!');
    }

    return $this;
}

/**
 * =================
 * Not part of PSR-7
 * =================
 * 
 * Validate header value.
 * 
 * @param string|string[] $value Header value(s).
 * @return $this
 * @throws \InvalidArgumentException
 */
protected function validateHeaderValue($value) {
    if (isset($value) && !is_array($value) && !is_string($value)) {
        throw new \InvalidArgumentException('The header value must be a string or an array!');
    }

    return $this;
}

/**
 * =================
 * Not part of PSR-7
 * =================
 * 
 * Replace a header item with a new one.
 * 
 * @param string $name Case-insensitive header field name.
 * @param string|string[] $value Header value(s).
 * @return $this
 * @done
 */
protected function replaceHeader($name, $value) {
    $this
            ->removeHeader($name)
            ->addHeader($name, $value)
    ;

    return $this;
}

Вы можете найти это в RFC 7230. Проверьте Zend Diactoro класс HeaderSecurity для реализации.

Другие вопросы по тегам