2015-08-27 12:03:05 -07:00
< ? php
/**
* Zend Framework ( http :// framework . zend . com / )
*
* @ see http :// github . com / zendframework / zend - diactoros for the canonical source repository
2017-04-13 15:53:35 +01:00
* @ copyright Copyright ( c ) 2015 - 2016 Zend Technologies USA Inc . ( http :// www . zend . com )
2015-08-27 12:03:05 -07:00
* @ license https :// github . com / zendframework / zend - diactoros / blob / master / LICENSE . md New BSD License
*/
namespace Zend\Diactoros ;
use OutOfBoundsException ;
use Psr\Http\Message\ServerRequestInterface ;
use Psr\Http\Message\ResponseInterface ;
/**
* " Serve " incoming HTTP requests
*
* Given a callback , takes an incoming request , dispatches it to the
* callback , and then sends a response .
*/
class Server
{
/**
* @ var callable
*/
private $callback ;
/**
* Response emitter to use ; by default , uses Response\SapiEmitter .
*
* @ var Response\EmitterInterface
*/
private $emitter ;
/**
* @ var ServerRequestInterface
*/
private $request ;
/**
* @ var ResponseInterface
*/
private $response ;
/**
* Constructor
*
* Given a callback , a request , and a response , we can create a server .
*
* @ param callable $callback
* @ param ServerRequestInterface $request
* @ param ResponseInterface $response
*/
public function __construct (
callable $callback ,
ServerRequestInterface $request ,
ResponseInterface $response
) {
$this -> callback = $callback ;
$this -> request = $request ;
$this -> response = $response ;
}
/**
* Allow retrieving the request , response and callback as properties
*
* @ param string $name
* @ return mixed
* @ throws OutOfBoundsException for invalid properties
*/
public function __get ( $name )
{
if ( ! property_exists ( $this , $name )) {
throw new OutOfBoundsException ( 'Cannot retrieve arbitrary properties from server' );
}
return $this -> { $name };
}
/**
* Set alternate response emitter to use .
*
* @ param Response\EmitterInterface $emitter
*/
public function setEmitter ( Response\EmitterInterface $emitter )
{
$this -> emitter = $emitter ;
}
/**
* Create a Server instance
*
* Creates a server instance from the callback and the following
* PHP environmental values :
*
* - server ; typically this will be the $_SERVER superglobal
* - query ; typically this will be the $_GET superglobal
* - body ; typically this will be the $_POST superglobal
* - cookies ; typically this will be the $_COOKIE superglobal
* - files ; typically this will be the $_FILES superglobal
*
* @ param callable $callback
* @ param array $server
* @ param array $query
* @ param array $body
* @ param array $cookies
* @ param array $files
* @ return static
*/
public static function createServer (
callable $callback ,
array $server ,
array $query ,
array $body ,
array $cookies ,
array $files
) {
$request = ServerRequestFactory :: fromGlobals ( $server , $query , $body , $cookies , $files );
$response = new Response ();
return new static ( $callback , $request , $response );
}
/**
* Create a Server instance from an existing request object
*
* Provided a callback , an existing request object , and optionally an
* existing response object , create and return the Server instance .
*
* If no Response object is provided , one will be created .
*
* @ param callable $callback
* @ param ServerRequestInterface $request
* @ param null | ResponseInterface $response
* @ return static
*/
public static function createServerFromRequest (
callable $callback ,
ServerRequestInterface $request ,
ResponseInterface $response = null
) {
if ( ! $response ) {
$response = new Response ();
}
return new static ( $callback , $request , $response );
}
/**
* " Listen " to an incoming request
*
* If provided a $finalHandler , that callable will be used for
* incomplete requests .
*
* Output buffering is enabled prior to invoking the attached
* callback ; any output buffered will be sent prior to any
* response body content .
*
* @ param null | callable $finalHandler
*/
public function listen ( callable $finalHandler = null )
{
$callback = $this -> callback ;
ob_start ();
$bufferLevel = ob_get_level ();
$response = $callback ( $this -> request , $this -> response , $finalHandler );
if ( ! $response instanceof ResponseInterface ) {
$response = $this -> response ;
}
$this -> getEmitter () -> emit ( $response , $bufferLevel );
}
/**
* Retrieve the current response emitter .
*
* If none has been registered , lazy - loads a Response\SapiEmitter .
*
* @ return Response\EmitterInterface
*/
private function getEmitter ()
{
if ( ! $this -> emitter ) {
$this -> emitter = new Response\SapiEmitter ();
}
return $this -> emitter ;
}
}