1: <?php
2:
3: /*
4: * This file is part of the Symfony package.
5: *
6: * (c) Fabien Potencier <fabien@symfony.com>
7: *
8: * For the full copyright and license information, please view the LICENSE
9: * file that was distributed with this source code.
10: */
11:
12: namespace Symfony\Component\HttpFoundation;
13:
14: /**
15: * StreamedResponse represents a streamed HTTP response.
16: *
17: * A StreamedResponse uses a callback for its content.
18: *
19: * The callback should use the standard PHP functions like echo
20: * to stream the response back to the client. The flush() method
21: * can also be used if needed.
22: *
23: * @see flush()
24: *
25: * @author Fabien Potencier <fabien@symfony.com>
26: *
27: * @api
28: */
29: class StreamedResponse extends Response
30: {
31: protected $callback;
32: protected $streamed;
33:
34: /**
35: * Constructor.
36: *
37: * @param mixed $callback A valid PHP callback
38: * @param integer $status The response status code
39: * @param array $headers An array of response headers
40: *
41: * @api
42: */
43: public function __construct($callback = null, $status = 200, $headers = array())
44: {
45: parent::__construct(null, $status, $headers);
46:
47: if (null !== $callback) {
48: $this->setCallback($callback);
49: }
50: $this->streamed = false;
51: }
52:
53: /**
54: * {@inheritDoc}
55: */
56: public static function create($callback = null, $status = 200, $headers = array())
57: {
58: return new static($callback, $status, $headers);
59: }
60:
61: /**
62: * Sets the PHP callback associated with this Response.
63: *
64: * @param mixed $callback A valid PHP callback
65: *
66: * @throws \LogicException
67: */
68: public function setCallback($callback)
69: {
70: if (!is_callable($callback)) {
71: throw new \LogicException('The Response callback must be a valid PHP callable.');
72: }
73: $this->callback = $callback;
74: }
75:
76: /**
77: * {@inheritdoc}
78: */
79: public function prepare(Request $request)
80: {
81: $this->headers->set('Cache-Control', 'no-cache');
82:
83: return parent::prepare($request);
84: }
85:
86: /**
87: * {@inheritdoc}
88: *
89: * This method only sends the content once.
90: */
91: public function sendContent()
92: {
93: if ($this->streamed) {
94: return;
95: }
96:
97: $this->streamed = true;
98:
99: if (null === $this->callback) {
100: throw new \LogicException('The Response callback must not be null.');
101: }
102:
103: call_user_func($this->callback);
104: }
105:
106: /**
107: * {@inheritdoc}
108: *
109: * @throws \LogicException when the content is not null
110: */
111: public function setContent($content)
112: {
113: if (null !== $content) {
114: throw new \LogicException('The content cannot be set on a StreamedResponse instance.');
115: }
116: }
117:
118: /**
119: * {@inheritdoc}
120: *
121: * @return false
122: */
123: public function getContent()
124: {
125: return false;
126: }
127: }
128: