2012-07-02 5 views
2

В соответствии с documentation, php://input не всегда содержит тело запроса HTTP.Возможно ли узнать, содержит ли php: // данные, прежде чем начать читать?

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

$stream = fopen('php://input', 'rb'); 

Если приложение пользователя пытается прочитать из пустого потока, когда Content-Length > 0 я хочу, чтобы моя библиотека выбрала исключение:

Тело запроса недоступно.

Моя проблема заключается в том, что:

  • Если поток пуст, feof() возвращается false в то время как fread() не был вызван;
  • Я не могу fread() 1 байт, то fseek(), так как этот поток не поддерживает поиск;
  • Я не могу открыть еще один php://input и попытаться прочитать его заранее, так как мы не можем полагаться на этот поток, который будет доступен не один раз;
  • Я не хочу вслепую копировать php://input в php://temp, прежде чем давать руку пользователю, по соображениям производительности.

Следовательно, это можно сказать php://input, содержит ли право данных после fopen(), но перед любым fread()?

ответ

1

Решение, которое я нашел, чтобы создать класс, представляющий тело запроса, и чтение из этого класса вместо php://input непосредственно:

class RequestBody 
{ 
    protected $firstByte; 

    protected $isEmpty; 

    public function __construct($stream) 
    { 
     $this->firstByte = fread($stream, 1); 
     $this->isEmpty = ($this->firstByte === ''); 

     // ... 
    } 

    public function isEmpty() 
    { 
     return $this->isEmpty; 
    } 

    public function read($length) 
    { 
     // ... 
    } 
} 

$body = new RequestBody(fopen('php://input', 'rb')); 

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

read() скрывает эту сложность, возвращая первый байт + $length - 1 байт при первом вызове.

0

«Поток, открытый с помощью php: // ввод может быть прочитан только один раз, поток не поддерживает операции поиска».

http://php.net/manual/en/wrappers.php.php

Для меня это говорит о том, что это старомодный только для чтения потока. Вы не можете искать и проверять, является ли это окончанием файла или длины.

Смежные вопросы