phasync
Request handlers / FormBody

Class

FormBody

The form data of a request, parsed when first asked for: what PHP puts in $_POST and $_FILES.

Introduction#

PHP parses a request body only when its head says to: a POST whose Content-Type is application/x-www-form-urlencoded or multipart/form-data, with enable_post_data_reading on. Every other body (a PUT, a JSON POST) stays raw. A framework adapter (swerve-psr15, Symfony, Tether) follows the same rule, but lazily: the body is read on the first fields() or files(), so a handler that streams the body itself, or never looks at it, costs nothing.

PHP's limits from php.ini apply as PHP applies them: post_max_size (the whole body; beyond it the form is empty, with a warning), upload_max_filesize (a larger file gets UPLOAD_ERR_INI_SIZE), max_file_uploads (further files are dropped), max_input_vars (further fields are dropped), max_multipart_body_parts, and file_uploads. Uploaded files are streamed to temporary files in upload_tmp_dir, and deleted when the request is gone unless moved.

Names are decoded as PHP decodes them (a[b][], dots and spaces in top-level names becoming underscores), by handing them to parse_str(). One difference: parse_str() keeps exactly max_input_vars fields, where PHP's own POST parser keeps one more.

Class synopsis#

final class FormBody {
    /* Methods */
    public static FormBody::for(
        string $method,
        string $contentType,
        StreamInterface $body
    ): ?FormBody
    public FormBody::fields(): array
    public FormBody::files(): array
    public FormBody::input(): StreamInterface
    public FormBody::__destruct()
}

Methods#

MethodDescription
forThe form of a request with this method and Content-Type, or null when PHP would not parse its body.
fields$_POST: the fields.
files$_FILES, as PSR-7 UploadedFileInterface objects.
inputphp://input: an url-encoded body's bytes, still readable after parsing; a multipart one's are used up by the parser, as in PHP.
__destructDelete the uploaded files' temporary copies that were not moved with moveTo().

Examples#

Example 1The fields of a url-encoded form
use phasync\Psr\StringStream;
use Swerve\Psr\FormBody;

// A url-encoded POST body, as a browser's form sends it
$body = new StringStream('name=Ann+Lee&tags[]=php&tags[]=async&user.age=42');
$form = FormBody::for('POST', 'application/x-www-form-urlencoded', $body);

var_export($form->fields());   // what $_POST would hold: a.b becomes a_b, as in PHP
echo "\n";
Output
array (
  'name' => 'Ann Lee',
  'tags' => 
  array (
    0 => 'php',
    1 => 'async',
  ),
  'user_age' => '42',
)

See also#