-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.json
More file actions
1 lines (1 loc) · 31.5 KB
/
index.json
File metadata and controls
1 lines (1 loc) · 31.5 KB
1
[{"id":"\/1.x\/request\/overview.html#1-1-1","title":"1.1.1. Overview","content":"The Sapien Request is a value object, composed of other value objects, representing the PHP request received by the server. Use a Request instead of the various PHP superglobals."},{"id":"\/1.x\/request\/overview.html#1-1-1-1","title":"1.1.1.1. Instantiation","content":"Instantiation of Request is straightforward:use Sapien\\Request; $request = new Request(); "},{"id":"\/1.x\/request\/overview.html#1-1-1-2","title":"1.1.1.2. Further Reading","content":"The Request provides public readonly properties related to these areas: globals file uploads request method request url headers accept* authorization forwarded and x-forwarded content You can also extend the Request for your own purposes."},{"id":"\/1.x\/request\/globals.html#1-1-2","title":"1.1.2. Globals","content":"The Request object presents these readonly properties as copies of the PHP superglobals: array $cookies: A copy of $_COOKIE. array $files: A copy of $_FILES. array $input: A copy of $_POST, or a json_decode()d array from the content body (see below). array $query: A copy of $_GET. array $server: A copy of $_SERVER. You can work with them the same as you would with any readonly array:\/\/ get the `?q=` value, defaulting to an empty string $searchTerm = $request->query['q'] ?? ''; "},{"id":"\/1.x\/request\/globals.html#1-1-2-1","title":"1.1.2.1. JSON Decoding","content":"The $_POST superglobal is populated by PHP when it can decode the content body as application\/x-www-form-urlencoded or multipart\/form-data. However, it is often the case that content bodies are JSON encoded instead.Thus, as a convenience, if the Request content-type is application\/json, then $request->input will be an array computed by applying json_decode() to the content body."},{"id":"\/1.x\/request\/globals.html#1-1-2-2","title":"1.1.2.2. Custom Values","content":"You can provide alternative or custom values via the $globals constructor parameter:$request = new Request( globals: [ '_COOKIE' => [...], '_FILES' => [...], '_GET' => [...], '_POST' => [...], '_SERVER' => [...], ] ); Any values not present in the $globals constructor parameter will be provided by the existing superglobal."},{"id":"\/1.x\/request\/uploads.html#1-1-3","title":"1.1.3. Uploads","content":"The Request $uploads property is a ValueCollection of Sapien\\Request\\Upload objects.Each Upload object is composed of these public readonly properties: ?string $name: The original name of the file on the client machine. ?string $fullPath: The original path of the file on the client machine. ?string $type: The mime type of the file, if the client provided this information. ?int $size: The size, in bytes, of the uploaded file. ?string $tmpName: The temporary filename of the file in which the uploaded file was stored on the server. ?int $error: The error code associated with this file upload. These values are derived from the Request $files array.In addition, each Upload object has this public method: move(string $destination) : bool: The equivalent of move_uploaded_file. "},{"id":"\/1.x\/request\/uploads.html#1-1-3-1","title":"1.1.3.1. Motivation","content":"The Request $files property is an identical copy of $_FILES. Normally, $_FILES looks like this with multi-file uploads:\/\/ $_FILES ... [ 'images' => [ 'name' => [ 0 => 'image1.png', 1 => 'image2.gif', 2 => 'image3.jpg', ], 'full_path' => [ 0 => 'image1.png', 1 => 'image2.gif', 2 => 'image3.jpg', ], 'type' => [ 0 => 'image\/png', 1 => 'image\/gif', 2 => 'image\/jpeg', ], 'tmp_name' [ 0 => '\/tmp\/path\/phpABCDEF', 1 => '\/tmp\/path\/phpGHIJKL', 2 => '\/tmp\/path\/phpMNOPQR', ], 'error' => [ 0 => 0, 1 => 0, 2 => 0, ], 'size' =>[ 0 => 123456, 1 => 234567, 2 => 345678, ], ], ]; However, that structure is surprising when we are used to working with $_POST.Therefore, the Request $uploads property restructures the data in $_FILES to look like $_POST does ...\/\/ $request->uploads in transition ... [ 'images' => [ 0 => [ 'name' => 'image1.png', 'full_path' => 'image1.png', 'type' => 'image\/png', 'tmp_name' => '\/tmp\/path\/phpABCDEF', 'error' => 0, 'size' => 123456, ], 1 => [ 'name' => 'image2.gif', 'full_path' => 'image2.gif', 'type' => 'image\/gif', 'tmp_name' => '\/tmp\/path\/phpGHIJKL', 'error' => 0, 'size' => 234567, ], 2 => [ 'name' => 'image3.jpg', 'full_path' => 'image3.jpg', 'type' => 'image\/jpeg', 'tmp_name' => '\/tmp\/path\/phpMNOPQR', 'error' => 0, 'size' => 345678, ], ], ]; ... and then replaces each array-based descriptor with an Upload instance."},{"id":"\/1.x\/request\/method.html#1-1-4","title":"1.1.4. Method","content":"The Request $method property is a Sapien\\Request\\Method instance derived from the $server values.The Method $name property is a readonly string.\/\/ returns the derived method value $requestMethod = $request->method->name; \/\/ the method object is stringable: assert($request->method->name === (string) $request->method); The $name value is computed from the Request $server['REQUEST_METHOD'] element, or the Request $server['HTTP_X_HTTP_METHOD_OVERRIDE'] element, as appropriate.In addition, the Method object has an is() method for checking the method name:$isPost = $request->method->is('post'); You can override the default method value with a custom one via the Request constructor ...$request = new Request( method: 'delete', ); ... or you can provide a Method object of your own construction:$request = new Request( method: new Request\\Method('delete'), ); "},{"id":"\/1.x\/request\/url.html#1-1-5","title":"1.1.5. URL","content":"The Request $url property is an instance of a Url object.Each Url object has these properties: ?string $scheme ?string $host ?int $port ?string $user ?string $pass ?string $path ?string $query ?string $fragment The property values are derived from applying parse_url() to the various Request $server elements: If $server['HTTPS'] === 'on', the scheme is 'https'; otherwise, it is 'http'. If $server['HTTP_HOST'] is present, it is used as the host name; otherwise, $server['SERVER_NAME'] is used. If a port number is present on the host name, it is used as the port; otherwise, $server['SERVER_PORT'] is used. $server['REQUEST_URI'] is used for the path and query string. If the parsing attempt fails, all Url properties will be null.The Url is stringable, and will return the full URL string:$url = (string) $request->url; \/\/ https:\/\/example.com\/path\/etc "},{"id":"\/1.x\/request\/headers.html#1-1-6","title":"1.1.6. Headers","content":"The Request $headers property is a readonly array derived from various Request $server property values.Each $server['HTTP_*'] element will be represented in $headers using a lower-kebab-cased key, along with the $server['CONTENT_LENGTH'] and $server['CONTENT_TYPE'] values.$_SERVER = [ 'HTTP_HOST' => 'example.com', 'HTTP_FOO_BAR_BAZ' => 'dib,zim,gir', 'CONTENT_LENGTH' => '123', 'CONTENT_TYPE' => 'text\/plain', ]; $request = new Request(); assert($request->headers['host'] === $_SERVER['HTTP_HOST']); assert($request->headers['foo-bar-baz'] === 'dib,zim,gir'); assert($request->headers['content-length'] === '123'); assert($request->headers['content-type'] === 'text\/plain'); You can work with $headers as you would with any readonly array:$fooBarBaz = $request->headers['foo-bar-baz'] ?? null; "},{"id":"\/1.x\/request\/accept.html#1-1-7","title":"1.1.7. Accept","content":"The Request $accept property is a Sapien\\Request\\Header\\Accept object.The Accept object has these readonly ValueCollection properties: TypeCollection $types: A collection of Accept\\Type objects computed from $header['accept']. CharsetCollection $charsets: A collection of Accept\\Charset objects computed from $header['accept-charset']. EncodingCollection $encodings: A collection of Accept\\Encoding objects computed from $header['accept-encoding']. LanguageCollection $languages: A collection of Accept\\Language objects computed from $header['accept-language']. Each collection is sorted from highest q parameter value to lowest.Each Accept\\* object has these readonly properties: string $value: The main value of the accept header. string $quality: The 'q=' parameter value. array $params: A key-value array of all other parameters. Each Accept\\Language object has these additional readonly properties: string $type: The language type. ?string $subtype: The language subtype, if any. "},{"id":"\/1.x\/request\/authorization.html#1-1-8","title":"1.1.8. Authorization","content":"The Request $authorization property is a Sapien\\Request\\Header\\Authorization\\Scheme object.The Scheme class itself is a marker, and may be one of several different implementations. The implementation is based on the scheme indicated by the Request $headers['authorization'] scheme. Warning: The Scheme objects do not indicate a user has been authenticated or authorized. They only carry the untrusted user inputs provided by the client. Use them to perform your own authentication and authorization logic. "},{"id":"\/1.x\/request\/authorization.html#1-1-8-1","title":"1.1.8.1. Basic","content":"The Basic scheme presents these readonly properties computed from the Request $headers['authorization'] credentials: string $username: The base64-decoded username. string $password: The base64-decoded password. "},{"id":"\/1.x\/request\/authorization.html#1-1-8-2","title":"1.1.8.2. Bearer","content":"The Bearer scheme presents this readonly property computed from the Request $headers['authorization'] credentials: string $token: The bearer token. "},{"id":"\/1.x\/request\/authorization.html#1-1-8-3","title":"1.1.8.3. Digest","content":"The Digest scheme presents these readonly properties computed from the Request $headers['authorization'] credentials: ?string $cnonce: The client nonce. ?int $nc: The nonce count. ?string $nonce: The server nonce. ?string $opaque: The server opaque string. ?string $qop: The quality of protection. ?string $realm: The authentication realm. ?string $response: The client response. ?string $uri: The effective request URI. ?bool $userhash: Whether or not the username has been hashed. ?string $username: The username in the realm. "},{"id":"\/1.x\/request\/authorization.html#1-1-8-4","title":"1.1.8.4. Generic","content":"The Generic scheme is used when the authorization scheme does not have a corresponding class. It presents these readonly properties: string $scheme: The authorization scheme. string $credentials: The authorization credentials. "},{"id":"\/1.x\/request\/authorization.html#1-1-8-5","title":"1.1.8.5. None","content":"The None scheme is empty, and indicates there was no authorization header."},{"id":"\/1.x\/request\/forward.html#1-1-9","title":"1.1.9. Forward","content":"The Request object has two readonly properties related to forwarding."},{"id":"\/1.x\/request\/forward.html#1-1-9-1","title":"1.1.9.1. $xForwarded\n","content":"The $xForwarded property is an instance of Sapien\\Request\\Header\\XForwarded.The XForwarded object has these readonly properties: array $for: An array computed from treating $header['x-forwarded-for'] as comma-separated values. ?string $host: The $headers['x-forwarded-host'] value, if any. ?int $port: The $headers['x-forwarded-port'] value, if any. ?string $prefix: The $headers['x-forwarded-prefix'] value, if any. ?string $proto: The $headers['x-forwarded-proto'] value, if any. "},{"id":"\/1.x\/request\/forward.html#1-1-9-2","title":"1.1.9.2. $forwarded\n","content":"The $forwarded property is a readonly ValueCollection of Sapien\\Request\\Header\\Forwarded objects.Each Forwarded object has the following readonly properties computed from the $headers['forwarded'] element: ?string $by: The interface where the request came in to the proxy server. ?string $for: Discloses information about the client that initiated the request. ?string $host: The original value of the Host header field. ?string $proto: The value of the used protocol type. Note: Cf. the Forwarded HTTP Extension. "},{"id":"\/1.x\/request\/content.html#1-1-10","title":"1.1.10. Content","content":"The Request object $content property is a Sapien\\Request\\Content object.The Content object has these readonly properties: ?string $body: The content body; see below for the value of this property. ?string $charset: The charset parameter value of $headers['content-type'], if any. ?int $length: The value of $headers['content-length'], if any. ?string $md5: The value of $headers['content-md5'], if any. ?string $type: The value of $headers['content-type'], if any, minus any parameters. When the $body property is null, Content will read from php:\/\/input instead:$request = new Request(); $body = $request->content->body; \/\/ returns `file_get_contents('php:\/\/input')` If you want to provide a custom content body string instead, pass it as a Request argument ...$request = new Request( content: 'custom-php-input-string' ); ... or pass an entire Content object of your own construction:$body = 'custom-php-input-string'; $request = new Request( content: new Request\\Content( body: $body, length: strlen($body), type: 'text\/plain', charset: 'utf-8', md5: md5($body), ) ); Note that the $headers values are not modified when you pass in custom content bodies or objects."},{"id":"\/1.x\/request\/extending.html#1-1-11","title":"1.1.11. Extending the Request\n","content":"The Sapien Request class can be extended to provide other userland functionality."},{"id":"\/1.x\/request\/extending.html#1-1-11-1","title":"1.1.11.1. Constructor","content":"The Request class has a constructor. Child classes overriding __construct() should be sure to call parent::__construct(), or else the parent readonly properties will remain uninitialized. Likewise, child classes specifying a constructor will need to duplicate the parent parameters."},{"id":"\/1.x\/request\/extending.html#1-1-11-2","title":"1.1.11.2. Properties and Methods","content":"The parent Request properties are readonly and cannot be modified or overridden. However, child classes may add new properties as desired. Even so, Sapien reserves the right to add new properties named for HTTP headers, along with new*() methods to populate those properties on demand.For example, try not to not add properties and methods named for HTTP headers ...class MyRequest extends \\Sapien\\Request { \/\/ ... protected MyRequest\\Authorization $authorization; protected function newAuthorization() : MyRequest\\Authorization { \/\/ ... } } ... but you may add methods and properties for application-specific needs. For example, immutable application attributes:class MyRequest extends \\Sapien\\Request { \/\/ ... protected $attributes = []; public function withAttributes(array $attribues) : static { $clone = clone $this; $clone->attributes = $attributes; return $clone; } public function withAttribute(string $key, mixed $value) : static { $clone = clone $this; $clone->attributes[$key] = $value; return $clone; } } "},{"id":"\/1.x\/request\/extending.html#1-1-11-3","title":"1.1.11.3. Magic Methods","content":"Protected properties in child classes will automatically be available via magic __get(), though private properties will not be.The methods __set(), __isset(), and __unset() are declared final and so cannot be overridden. This is to help prevent subversion of the readonly nature of Request."},{"id":"\/1.x\/response\/overview.html#1-2-1","title":"1.2.1. Overview","content":"The Sapien Response is a mutable object representing the PHP response to be sent from the server.It provides a retention space for the HTTP response version, code, headers, cookies, and content, so they can be inspected before sending.Use a Response in place of the header(), setcookie(), setrawcookie(), etc. functions."},{"id":"\/1.x\/response\/overview.html#1-2-1-1","title":"1.2.1.1. Instantiation","content":"Instantation is straightforward:use Sapien\\Response; $response = new Response(); "},{"id":"\/1.x\/response\/overview.html#1-2-1-2","title":"1.2.1.2. Examples","content":"Here are some basic examples of creating and sending a response:\/\/ a \"200 OK\" response with some body content: $response ->setHeader('content-type', 'text\/plain') ->setContent('Hello World!') ->send(); \/\/ a \"303 See Other\" response $response ->setCode(303) ->setHeader('location', '\/path\/to\/resource') ->send(); \/\/ sending a cookie with the response; note how the setter methods \/\/ are fluent, allowing you to chain calls to the Response $response ->setCookie(name: 'foo', value: 'bar') ->setContent(\"Cookie has been set!\") ->send(); "},{"id":"\/1.x\/response\/overview.html#1-2-1-3","title":"1.2.1.3. Further Reading","content":"The Response provides public methods related to these areas: protocol version status code headers cookies header callbacks content sending the response You can extend the Response for your own purposes, though you should check out one of the specialized responses before doing so."},{"id":"\/1.x\/response\/version.html#1-2-2-1","title":"1.2.2.1. Setting the Version","content":"final public setVersion(?string $version) : staticThis sets the protocol version for the Response (typically '1.0', '1.1', or '2').The method is fluent, allowing you to chain a call to another Response method."},{"id":"\/1.x\/response\/version.html#1-2-2-2","title":"1.2.2.2. Getting the Version","content":"final public getVersion() : ?stringReturns the protocol version for the response."},{"id":"\/1.x\/response\/code.html#1-2-3-1","title":"1.2.3.1. Setting the Code","content":"final public setCode(?int $code) : staticSets the status code for the Response; a buffered equivalent of http_response_code($code).The method is fluent, allowing you to chain a call to another Response method."},{"id":"\/1.x\/response\/code.html#1-2-3-2","title":"1.2.3.2. Getting the Code","content":"final public getCode() : ?intReturns the the status code for the response."},{"id":"\/1.x\/response\/headers.html#1-2-4","title":"1.2.4. Headers","content":"The header field labels are retained internally in lower-case. This is to comply with HTTP\/2 requirements; while HTTP\/1.x has no such requirement, lower-case is also recognized as valid.Further, the header field values are retained and returned as Sapien\\Request\\Header objects, not strings."},{"id":"\/1.x\/response\/headers.html#1-2-4-1-1","title":"1.2.4.1.1. Setting One Header","content":"final public setHeader(string $label, Header|string $value) : staticOverwrites the $label HTTP header in the Response; a buffered equivalent of header(\"$label: $value\", true).The method is fluent, allowing you to chain a call to another Response method."},{"id":"\/1.x\/response\/headers.html#1-2-4-1-2","title":"1.2.4.1.2. Setting All Headers","content":"final public setHeaders(array $headers) : staticOverwrites all previous headers on the Response, replacing them with the new $headers array. Each $headers element key is the field label, and the corresponding element value is the field value.The method is fluent, allowing you to chain a call to another Response method."},{"id":"\/1.x\/response\/headers.html#1-2-4-2","title":"1.2.4.2. Adding","content":"final public addHeader(string $label, Header|string $value) : staticAppends to the $label HTTP header in the Response, comma-separating it from the existing value; a buffered equivalent of header(\"$label: $value\", false).The method is fluent, allowing you to chain a call to another Response method."},{"id":"\/1.x\/response\/headers.html#1-2-4-3-1","title":"1.2.4.3.1. Getting One Header","content":"final public getHeader(string $label) : ?HeaderReturns the $label header from the Response, if it exists."},{"id":"\/1.x\/response\/headers.html#1-2-4-3-2","title":"1.2.4.3.2. Getting All Headers","content":"final public getHeaders() : arrayReturns the array of Header objects in the Response."},{"id":"\/1.x\/response\/headers.html#1-2-4-4","title":"1.2.4.4. Checking","content":"final public hasHeader(string $label) : boolReturns true if the $label header exists in the Response, false if not."},{"id":"\/1.x\/response\/headers.html#1-2-4-5-1","title":"1.2.4.5.1. Removing One Header","content":"final public unsetHeader(string $label) : staticRemoves the $label header from the Response.The method is fluent, allowing you to chain a call to another Response method."},{"id":"\/1.x\/response\/headers.html#1-2-4-5-2","title":"1.2.4.5.2. Removing All Headers","content":"final public unsetHeaders() : staticRemoves all headers from the buffer.The method is fluent, allowing you to chain a call to another Response method."},{"id":"\/1.x\/response\/cookies.html#1-2-5","title":"1.2.5. Cookies","content":"The Response retains each cookie as a Sapien\\Response\\Cookie value object."},{"id":"\/1.x\/response\/cookies.html#1-2-5-1-1","title":"1.2.5.1.1. Setting One Encoded Cookie","content":"final public setCookie( string $name, string $value = '', int $expires = null, string $path = null, string $domain = null, bool $secure = null, bool $httponly = null, string $samesite = null ) : static A buffered equivalent of setcookie(), with the various options expanded out to method parameters.The method is fluent, allowing you to chain a call to another Response method."},{"id":"\/1.x\/response\/cookies.html#1-2-5-1-2","title":"1.2.5.1.2. Setting One Raw Cookie","content":"final public setRawCookie( string $name, string $value = '', int $expires = null, string $path = null, string $domain = null, bool $secure = null, bool $httponly = null, string $samesite = null ) : static A buffered equivalent of setrawcookie(), with the various options expanded out to method parameters.The method is fluent, allowing you to chain a call to another Response method."},{"id":"\/1.x\/response\/cookies.html#1-2-5-1-3","title":"1.2.5.1.3. Setting One Cookie Instance","content":"final public setCookie( string $name, Cookie $value ) : static If you have a Cookie instance in hand, you may set it into the Reponse using setCookie().The method is fluent, allowing you to chain a call to another Response method."},{"id":"\/1.x\/response\/cookies.html#1-2-5-1-4","title":"1.2.5.1.4. Setting All Cookies","content":"final public setCookies(array $cookies) : staticResets the Response cookies to the key-value pairs of $cookies. The value may be a string, in which case the value will be encoded, or it may be a Cookie instance, in which case it will be retained as-is.The method is fluent, allowing you to chain a call to another Response method."},{"id":"\/1.x\/response\/cookies.html#1-2-5-2-1","title":"1.2.5.2.1. Getting One Cookie","content":"final public getCookie(string $name) : ?CookieReturns the $name Cookie from the Response."},{"id":"\/1.x\/response\/cookies.html#1-2-5-2-2","title":"1.2.5.2.2. Getting All Cookies","content":"final public getCookies() : arrayReturns the array of Cookie objects in the Response."},{"id":"\/1.x\/response\/cookies.html#1-2-5-3","title":"1.2.5.3. Checking","content":"final public hasCookie(string $name) : boolReturns true if the $name Cookie exists in the Response, false if not."},{"id":"\/1.x\/response\/cookies.html#1-2-5-4-1","title":"1.2.5.4.1. Removing One Cookie","content":"final public unsetCookie(string $name) : staticRemoves the $name Cookie from the Response.The method is fluent, allowing you to chain a call to another Response method."},{"id":"\/1.x\/response\/cookies.html#1-2-5-4-2","title":"1.2.5.4.2. Removing All Cookies","content":"final public unsetCookies() : staticRemoves all Cookie objects from the Response.The method is fluent, allowing you to chain a call to another Response method."},{"id":"\/1.x\/response\/callbacks.html#1-2-6-1","title":"1.2.6.1. Setting","content":"final public setHeaderCallbacks(array $callbacks) : staticSets an array of callbacks to be invoked just before headers are sent by the Response, replacing any existing callbacks.This method is similar to header_register_callback(), except that multiple callbacks may be registered with the Response.Each value in the $callbacks array is expected to be a callable with the following signature:function (Response $response) : voidThe method is fluent, allowing you to chain a call to another Response method."},{"id":"\/1.x\/response\/callbacks.html#1-2-6-2","title":"1.2.6.2. Adding","content":"final public addHeaderCallback(callable $callback) : staticAppends one callback to the current array of header callbacks in the Response.The $callback is expected to be a callable with the following signature:function (Response $response) : voidThe method is fluent, allowing you to chain a call to another Response method."},{"id":"\/1.x\/response\/callbacks.html#1-2-6-3","title":"1.2.6.3. Getting","content":"final public getHeaderCallbacks() : arrayReturns the array of header callbacks in the Response."},{"id":"\/1.x\/response\/callbacks.html#1-2-6-4","title":"1.2.6.4. Checking","content":"final public hasHeaderCallbacks() : boolReturns true if there are any header callbacks in the Response, false if not."},{"id":"\/1.x\/response\/callbacks.html#1-2-6-5","title":"1.2.6.5. Removing","content":"final public unsetHeaderCallbacks() : staticRemoves all header callbacks from the Response.The method is fluent, allowing you to chain a call to another Response method."},{"id":"\/1.x\/response\/content.html#1-2-7-1","title":"1.2.7.1. Setting","content":"public setContent(mixed $content) : staticSets the content of the Response.The $content may may be null, a string, a resource, an object, or anything else. How the content will be sent is determined by the Response sending logic.The method is fluent, allowing you to chain a call to another Response method.Note that unlike almost all the other Response methods, setContent() is not declared as final. This means you can override it in extended Response classes (though of course the signature must remain)."},{"id":"\/1.x\/response\/content.html#1-2-7-2","title":"1.2.7.2. Getting","content":"final public getContent() : mixedReturns the content of the Response."},{"id":"\/1.x\/response\/sending.html#1-2-8","title":"1.2.8. Sending","content":"public function send() : voidTo send the Response, call its send() method. Doing so will: call each of the $headerCallbacks in order send the status line $version and $code using header() calls; the default version is 1.1 and the default code is 200 send each of the $headers using header() calls send each of the $cookies using setcookie() and setrawcookie() as appropriate send the content using the Response sendContent() method (see below for details). Note that the send() method, unlike most Response methods, is not declared as final. This means you can override it in extended Response classes (though of course the signature must remain)."},{"id":"\/1.x\/response\/sending.html#1-2-8-1","title":"1.2.8.1. Content Handling","content":"protected function sendContent() : voidRecall that the setContent() method allows anything to be content: a string, an object, a resource, etc. It is the sendContent() method that determines how to actually send the Response content.If the content is ... a resource or SplFileObject, then sendContent() will rewind() it and send it with fpassthru(). a non-string callable, then sendContent() will invoke it. Further, sendContent() will echo the return value (if any) from that invocation. This means the callable may emit output itself, or it may return a string for sendContent() to echo, or do both. an iterable, then sendContent() will foreach() through it, and echo each value. a string or a Stringable, then sendContent() will merely echo it. anything else, then sendContent() will do nothing, and return. The above conditions are in precedence order. That is, if the content is both callable and iterable, the callable handling will take precedence over the iterable handling.Note that the sendContent() method, unlike most Response methods, is not declared as final. This means you can override it in extended Response classes (though of course the signature must remain)."},{"id":"\/1.x\/response\/special.html#1-2-9-1","title":"1.2.9.1. FileResponse","content":"The FileResponse is customized for sending back downloads.Use setContent() to specify a string path to the file to be sent, or an SplFileObject object:use Sapien\\Response\\FileResponse; $fileResponse = new FileResponse(); \/\/ use a string path ... $fileResponse->setContent('\/path\/to\/file.txt'); \/\/ ... or an SplFileObject: $fileResponse->setContent(new \\SplFileObject('\/path\/to\/file.txt')); The FileResponse will set itself up to send the file ... disposed as an 'attachment', with whatever content-type is already set (or application\/octet-stream if none), using whatever content-transfer-encoding is already set (or binary if none), naming the download for the filename. Alternatively, call the setFile() method for better control over some aspects of the FileResponse:$fileResponse->setFile( file: '\/path\/to\/file.b64', \/\/ or an SplFileObject instance disposition: 'attachment', \/\/ or 'inline' name: 'SomeOtherName.b64', \/\/ an alternative name for the download type: 'text\/plain' \/\/ set this content-type encoding: 'base64' \/\/ set this content-transfer-encoding ); In any case, you may always modify the FileResponse values after setContent() or setFile()."},{"id":"\/1.x\/response\/special.html#1-2-9-2","title":"1.2.9.2. JsonResponse","content":"The JsonResponse is customized for sending back JSON content.Use setContent() to specify a value to be JSON-encoded at sending time:use Sapien\\Response\\JsonResponse; $jsonResponse = new JsonResponse(); \/\/ set the content to be encoded $jsonResponse->setContent(['foo' => 'bar']); The JsonResponse will set itself up with ... a content-type of application\/json, the default json_encode() flags and depth. Alternatively, call the setJson() method for better control over some aspects of the JsonResponse:$jsonResponse->setJson( value: ['foo' => 'bar'], \/\/ the value to be encoded type: 'application\/foo+json', \/\/ set this content-type flags: JSON_PRETTY_PRINT, \/\/ alternative json_encode() flags depth: 128 \/\/ alternative json_encode() depth ); In any case, you may always modify the JsonResponse values after setContent() or setJson().Further, you may call setJsonFlags() and setJsonDepth() to modify the flags and depth respectively.Finally, when you actually send() it, the JsonResponse will echo the results passing the content through json_encode()."},{"id":"\/1.x\/response\/extending.html#1-2-10","title":"1.2.10. Extending the Response\n","content":"The Sapien Response class can be extended to provide other userland functionality."},{"id":"\/1.x\/response\/extending.html#1-2-10-1","title":"1.2.10.1. Properties","content":"The properties on Response are private, which means you may not access them, except through the existing Response methods. You may add child properties as desired, though they would best be protected or private."},{"id":"\/1.x\/response\/extending.html#1-2-10-2","title":"1.2.10.2. Constructor","content":"Response is constructorless. You may add any constructor you like, and do not have to call a parent constructor."},{"id":"\/1.x\/response\/extending.html#1-2-10-3","title":"1.2.10.3. Methods","content":"Most of the methods on Response are public and final, which means you cannot extend or override them in child classes. This keeps their behavior consistent.However, these Response methods are not final, and thus are open to extension: public function setContent(mixed $content) : void public function send() : void public function sendContent() : void You may override them at will (though of course you cannot change the signatures). In general: Override setContent() to set up the Response properties in relation to the content. Be sure to call parent::setContent() to actually retain the content value. Override send() to perform pre- and post-sending behaviors. Be sure to call parent::send() to actually send the Response. Override sendContent() for custom or specialized emitting of the content value. "}]