Как сказали другие ответы:
- вы не можете хранить все это в памяти
- решение будет использовать
CURLOPT_FILE
Но вы, возможно, не захотите действительно создавать файл, который вы хотели бы работать с данными в памяти ... Используя его, как только он "прибудет".
Одним из возможных решений может быть определение собственной потоковой обертки и использование этой вместо реального файла с CURLOPT_FILE
Прежде всего, см .:
А теперь давайте рассмотрим пример.
Во-первых, давайте создадим наш класс упаковщика потока:
class MyStream {
protected $buffer;
function stream_open($path, $mode, $options, &$opened_path) {
// Has to be declared, it seems...
return true;
}
public function stream_write($data) {
// Extract the lines ; on y tests, data was 8192 bytes long ; never more
$lines = explode("\n", $data);
// The buffer contains the end of the last line from previous time
// => Is goes at the beginning of the first line we are getting this time
$lines[0] = $this->buffer . $lines[0];
// And the last line os only partial
// => save it for next time, and remove it from the list this time
$nb_lines = count($lines);
$this->buffer = $lines[$nb_lines-1];
unset($lines[$nb_lines-1]);
// Here, do your work with the lines you have in the buffer
var_dump($lines);
echo '<hr />';
return strlen($data);
}
}
Что я делаю:
- работать с кусками данных (я использую var_dump, но вместо этого вы будете делать обычные вещи), когда они поступят
- Обратите внимание, что вы не получаете "полных строк": конец строки - это начало фрагмента, а начало этой же строки было в конце предыдущего фрагмента, поэтому вам нужно сохранить некоторые части части между звонками на
stream_write
Далее мы регистрируем эту потоковую оболочку для использования с псевдопротоколом «test»:
// Register the wrapper
stream_wrapper_register("test", "MyStream")
or die("Failed to register protocol");
И теперь мы выполняем запрос curl, как при записи в «настоящий» файл, как предлагали другие ответы:
// Open the "file"
$fp = fopen("test://MyTestVariableInMemory", "r+");
// Configuration of curl
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://www.rue89.com/");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_BUFFERSIZE, 256);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FILE, $fp); // Data will be sent to our stream ;-)
curl_exec($ch);
curl_close($ch);
// Don't forget to close the "file" / stream
fclose($fp);
Обратите внимание, что мы работаем не с реальным файлом, а с нашим псевдопротоколом.
Таким образом, каждый раз, когда прибывает кусок данных, вызывается метод MyStream::stream_write
, и он сможет работать с небольшим объемом данных (когда я тестировал, я всегда получал 8192 байта, какое бы значение я ни использовал CURLOPT_BUFFERSIZE
)
Несколько заметок:
- Вам нужно проверить это больше, чем я, очевидно,
- моя реализация stream_write, вероятно, не будет работать, если строки длиной до 8192 байт до вас исправят ее; -)
- Это всего лишь несколько указателей, а не полностью работающее решение: вы должны протестировать (снова) и, вероятно, кодировать немного больше!
Тем не менее, я надеюсь, что это поможет ;-)
Веселись!