<?php 
 
/* 
 * This file is part of the Symfony package. 
 * 
 * (c) Fabien Potencier <[email protected]> 
 * 
 * For the full copyright and license information, please view the LICENSE 
 * file that was distributed with this source code. 
 */ 
 
namespace Symfony\Component\HttpFoundation; 
 
/** 
 * StreamedResponse represents a streamed HTTP response. 
 * 
 * A StreamedResponse uses a callback for its content. 
 * 
 * The callback should use the standard PHP functions like echo 
 * to stream the response back to the client. The flush() method 
 * can also be used if needed. 
 * 
 * @see flush() 
 * 
 * @author Fabien Potencier <[email protected]> 
 */ 
class StreamedResponse extends Response 
{ 
    protected $callback; 
    protected $streamed; 
    private $headersSent; 
 
    /** 
     * Constructor. 
     * 
     * @param callable|null $callback A valid PHP callback or null to set it later 
     * @param int           $status   The response status code 
     * @param array         $headers  An array of response headers 
     */ 
    public function __construct(callable $callback = null, $status = 200, $headers = array()) 
    { 
        parent::__construct(null, $status, $headers); 
 
        if (null !== $callback) { 
            $this->setCallback($callback); 
        } 
        $this->streamed = false; 
        $this->headersSent = false; 
    } 
 
    /** 
     * Factory method for chainability. 
     * 
     * @param callable|null $callback A valid PHP callback or null to set it later 
     * @param int           $status   The response status code 
     * @param array         $headers  An array of response headers 
     * 
     * @return static 
     */ 
    public static function create($callback = null, $status = 200, $headers = array()) 
    { 
        return new static($callback, $status, $headers); 
    } 
 
    /** 
     * Sets the PHP callback associated with this Response. 
     * 
     * @param callable $callback A valid PHP callback 
     */ 
    public function setCallback(callable $callback) 
    { 
        $this->callback = $callback; 
    } 
 
    /** 
     * {@inheritdoc} 
     * 
     * This method only sends the headers once. 
     */ 
    public function sendHeaders() 
    { 
        if ($this->headersSent) { 
            return; 
        } 
 
        $this->headersSent = true; 
 
        parent::sendHeaders(); 
    } 
 
    /** 
     * {@inheritdoc} 
     * 
     * This method only sends the content once. 
     */ 
    public function sendContent() 
    { 
        if ($this->streamed) { 
            return; 
        } 
 
        $this->streamed = true; 
 
        if (null === $this->callback) { 
            throw new \LogicException('The Response callback must not be null.'); 
        } 
 
        call_user_func($this->callback); 
    } 
 
    /** 
     * {@inheritdoc} 
     * 
     * @throws \LogicException when the content is not null 
     */ 
    public function setContent($content) 
    { 
        if (null !== $content) { 
            throw new \LogicException('The content cannot be set on a StreamedResponse instance.'); 
        } 
    } 
 
    /** 
     * {@inheritdoc} 
     * 
     * @return false 
     */ 
    public function getContent() 
    { 
        return false; 
    } 
} 
 
 |