W innych odpowiedzi powiedział:
- nie można mieć to wszystko w pamięci
- rozwiązaniem byłoby wykorzystanie
CURLOPT_FILE
Ale możesz nie chcieć, aby stworzyć naprawdę plik; możesz chcieć pracować z danymi w pamięci ... Używając jej tak szybko, jak tylko "dotrze".
Jednym z możliwych rozwiązań może być definind jesteś właścicielem strumienia otoki i używać ten jeden, zamiast rzeczywistego pliku, z CURLOPT_FILE
Przede wszystkim zobacz:
A teraz, zróbmy przykład.
Najpierw stwórzmy naszą klasę strumień Wrapper:
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);
}
}
Co mogę zrobić, to:
- prace nad kawałkami danych (używam var_dump, ale trzeba robić swoje zwykłe rzeczy zamiast tego) po ich otrzymaniu:
- Zwróć uwagę, że nie otrzymujesz "pełnych linii": koniec linii jest początkiem fragmentu, a początek tej samej linii znajdował się na końcu poprzedniego fragmentu; tak, trzeba zachować niektóre części chunck między połączeniami do
stream_write
Dalej, możemy zarejestrować ten strumień opakowanie, które mają być używane z pseudo-protocol „test”:
// Register the wrapper
stream_wrapper_register("test", "MyStream")
or die("Failed to register protocol");
a teraz robimy curl wniosek, jak będziemy to robić, gdy pisanie do "prawdziwego" pliku, podobnie jak inne odpowiedzi zasugerował:
// 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);
Uwaga nie pracujemy z prawdziwym plikiem, ale z naszym pseudo-protokołem.
W ten sposób, za każdym razem porcja danych przybywa, MyStream::stream_write
metoda będzie sprawdzony i będzie w stanie pracować na małej ilości danych (kiedy testowane, zawsze dostaje 8192 bajtów, niezależnie od wartości I wykorzystywane do CURLOPT_BUFFERSIZE
)
kilka uwag:
- trzeba to sprawdzić więcej niż ja, oczywiście
- moja implementacja stream_write prawdopodobnie nie zadziała, jeśli linie są dłuższe niż 8192 bajty; do ciebie, aby to załatać ;-)
- Jest to tylko kilka wskazówek, a nie w pełni działające rozwiązanie: musisz przetestować (ponownie) i prawdopodobnie trochę więcej kodu!
Nadal mam nadzieję, że to pomoże ;-)
Miłej zabawy!
Odpowiedź w dół pod adresem http://stackoverflow.com/a/1342760/4668 jest lepsza niż moja. –