Skip to content

Instantly share code, notes, and snippets.

@h4cc
Created March 1, 2013 11:25
Show Gist options
  • Save h4cc/5064051 to your computer and use it in GitHub Desktop.
Save h4cc/5064051 to your computer and use it in GitHub Desktop.
A Guzzle Plugin for streaming files. Maybe someday a real Guzzle Plugin with Composer package...
<?php
/**
* Direct streamer for guzzle.
* Makes a HEAD request to fetch content length first.
* Uses GET request to stream read data directly to the browser.
*
* @author Julius Beckmann
*/
include('guzzle.phar');
use Guzzle\Http\Client;
use Guzzle\Common\Event;
class StreamPlugin implements Symfony\Component\EventDispatcher\EventSubscriberInterface
{
private $head_request = null;
public static function getSubscribedEvents() {
return array(
'curl.callback.write' => 'onCurlCallbackWrite',
'request.before_send' => 'configureRequest',
);
}
public function configureRequest($event) {
$request = $event->offsetGet('request');
$request->getParams()->set('curl.emit_io', true);
}
public function onCurlCallbackWrite(Guzzle\Common\Event $event){
// Maybe sue ob_flush() here.
echo $event->offsetGet('write');
}
}
class GuzzleStreamer {
private $client;
private $plugin;
public function __construct(Guzzle\Http\Client $client) {
$this->client = $client;
$this->plugin = new StreamPlugin();
$client->addSubscriber($this->plugin);
}
public function stream($url) {
// Fetch Content-Length via HEAD request.
$response = $this->client->head($url)->send();
$content_length = (string)$response->getHeader('Content-Length');
if($content_length) {
header('Content-Length: '.$content_length);
}
// Request and output directly.
$this->client->get($url)->send();
}
}
$client = new Client('http://example.com');
$streamer = new GuzzleStreamer($client);
$streamer->stream('/file');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment