Skip to content

Instantly share code, notes, and snippets.

@joelharkes
Last active November 25, 2021 08:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joelharkes/3d7e6df0d3ebc3016cb00666cca772ad to your computer and use it in GitHub Desktop.
Save joelharkes/3d7e6df0d3ebc3016cb00666cca772ad to your computer and use it in GitHub Desktop.
Making streams in PHP/Laravel
<?php
public function writeQueryAsCsvFileToStorage() {
$disk = Storage::disk('yourDiskNameHer');
// optional: ensure file doesn't exist:
// $disk->delete($filePath);
$cursor = $this->getQuery()
->toBase() // +-10x speed improvement, skip making laravel models
->cursor() // avoid loading whole result set into memory.
->map(fn ($item) => $this->map((array) $item));
// writes all data (1 by 1) to a temporary file then we can then stream to external disk.
$stream = StreamHelper::streamCsvAssoc($cursor);
$disk->writeStream($filePath, $stream);
fclose($stream);
}
<?php
class StreamHelper
{
public static function streamCsv(iterable $iterator, string $separator = ',', string $enclosure = '"', string $escape = '\\')
{
return self::stream($iterator, function ($stream, $value) use ($escape, $enclosure, $separator) {
fputcsv($stream, $value, $separator, $enclosure, $escape);
});
}
public static function streamCsvAssoc(iterable $iterator, string $separator = ',', string $enclosure = '"', string $escape = '\\')
{
$first = true;
return self::stream($iterator, function ($stream, $value) use (&$first, $escape, $enclosure, $separator) {
if ($first) {
fputcsv($stream, array_keys($value), $separator, $enclosure, $escape);
$first = false;
}
fputcsv($stream, array_values($value), $separator, $enclosure, $escape);
});
}
public static function streamJsonList(iterable $iterator, int $flags = 0, int $depth = 512)
{
$stream = tmpfile();
fwrite($stream, '[');
$first = true;
foreach ($iterator as $value) {
if (!$first) {
fwrite($stream, ',');
} else {
$first = false;
}
fwrite($stream, json_encode($value, $flags, $depth));
}
fwrite($stream, ']');
rewind($stream);
return $stream;
}
/**
* @param iterable $iterator
* @param $writeFunction (stream, value)
*
* @return resource
*/
public static function stream(iterable $iterator, callable $writeFunction)
{
$stream = tmpfile();
if (false === $stream) {
throw new \Exception('failed making stream');
}
foreach ($iterator as $value) {
$writeFunction($stream, $value);
}
rewind($stream);
return $stream;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment