Back-End

5 dez, 2016

A extensão “Request” do PHP 7

Publicidade

tl; dr: A nova extensão request fornece objetos de requisição e de resposta referentes ao servidor para PHP 7. Use-a como um objeto de substituição para requisição de funções superglobals e de resposta. Uma versão equivalente do PHP 5 está disponível no userland como pmjones/request.

Você está cansado de lidar com $_GET, $_POST etc. superglobals na sua aplicação PHP 7. Você gostaria que fosse mais fácil de lidar com $_FILES. Você preferiria envolver todos eles em um objeto para permitir passá-los para seus métodos de classe, para que eles fossem mais fáceis de testar. E enquanto eles estão todos em um objeto, pode ser bom ter analisadas representações dos vários cabeçalhos de entrada. Preferencialmente, você gostaria que eles fossem somente de leitura, de modo que as várias bibliotecas que você usa não pudessem modificar o estado superglobal para fora de você.

Da mesma forma, ver o aviso “Não é possível modificar informações de cabeçalho – cabeçalhos já enviados” está “dando nos seus nervos”. Você gostaria de nunca mais usar header(), setcookie() e o restante. Você sabe que eles são difíceis de inspecionar e de testar. O que seria ótimo é ter todo esse trabalho de resposta envolvido em outro objeto que você pode passar ao redor e inspecioná-lo ou modificá-lo antes de enviar a resposta de volta para o cliente.

Você poderia talvez adotar um framework, mas por que fazer isso para o seu projeto personalizado? Apenas alguns objetos de requisição e resposta referentes ao servidor fariam sua vida muito mais fácil. Por que não pode haver um conjunto de classes internas do PHP para isso?

Bem, agora existe. Você pode instalar a minha extensão request e de John Boehr para obter objetos de ServerRequest e ServerReponse como se o próprio PHP os tivesse fornecido.

ServerRequest

Depois de instalar a extensão, você pode emitir $request = new ServerRequest() e, em seguida:

Instead of ...                          ... use:
--------------------------------------- ---------------------------------------
$_COOKIE                                $request->cookie
$_ENV                                   $request->env
$_GET                                   $request->get
$_FILES                                 $request->files
$_POST                                  $request->post
$_SERVER                                $request->server
$_SERVER['REQUEST_METHOD']              $request->method
$_SERVER['HTTP_HEADER_NAME']            $request->headers['header-name']
file_get_contents('php://input')        $request->content
$_SERVER['HTTP_CONTENT_LENGTH']         $request->contentLength
$_SERVER['HTTP_CONTENT_MD5']            $request->contentMd5
$_SERVER['PHP_AUTH_PW']                 $request->authPw
$_SERVER['PHP_AUTH_TYPE']               $request->authType
$_SERVER['PHP_AUTH_USER']               $request->authUser

Da mesma maneira:

Instead of parsing ...                  ... use:
--------------------------------------- ---------------------------------------
isset($_SERVER['key'])                  $request->server['key'] ?? 'default'
  ? $_SERVER['key']                     (good for all superglobals)
  : 'default';
$_FILES to look more like $_POST        $request->uploads
$_SERVER['HTTP_CONTENT_TYPE']           $request->contentType and
                                        $request->contentCharset
$_SERVER['HTTP_ACCEPT']                 $request->accept
$_SERVER['HTTP_ACCEPT_CHARSET']         $request->acceptCharset
$_SERVER['HTTP_ACCEPT_ENCODING']        $request->acceptEncoding
$_SERVER['HTTP_ACCEPT_LANGUAGE']        $request->acceptLanguage
$_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] $request->method
$_SERVER['PHP_AUTH_DIGEST']             $request->authDigest
$_SERVER['HTTP_X_REQUESTED_WITH']       $request->xhr
  == 'XmlHttpRequest'

Essas propriedades são todas somente de leitura, então não há chance de elas serem alterados sem você saber (existem alguns verdadeiros imutáveis para valores relacionados a aplicações também, consulte a documentação).

ServerResponse

Para respostas, você pode emitir $response = new ServerResponse() e, em seguida:

Instead of ...                          ... use:
--------------------------------------- ---------------------------------------
header('Foo: bar', true);               $response->setHeader('Foo', 'bar');
header('Foo: bar', false);              $response->addHeader('Foo', 'bar');
setcookie('foo', 'bar');                $response->setCookie('foo', 'bar');
setrawcookie('foo', 'bar');             $response->setRawCookie('foo', 'bar');
echo $content;                          $response->setContent($content);

Você pode inspecionar o objeto $response e, em seguida, chamar $response->send() para enviar para o cliente.

Trabalhando com o JSON?

// instead of ...
header('Content-Type: application/json')
echo json_encode($value);

// .. use:
$response->setContentJson($value);

Enviando um $file para download?

// instead of ...
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
header(
    'Content-Disposition: attachment;filename="'
    . rawurlencode(basename($file)) . '"'
);
$fh = fopen($file, 'rb+');
fpasthru($fh);

// use:
$fh = fopen($file, 'rb+');
$response->setContentDownload($fh, basename($file));

Construindo um cabeçalho complexo? Passe um array em vez de uma string:

$response->setHeader('Cache-Control', [
    'public',
    'max-age' => '123',
    's-maxage' => '456',
    'no-cache',
]); // Cache-Control: public, max-age=123, s-maxage=456, no-cache

$response->setHeader('X-Whatever', [
    'foo',
    'bar' => [
        'baz' => 'dib',
        'zim',
        'gir' => 'irk',
    ],
    'qux' => 'quux',
]); // X-Whatever: foo, bar;baz=dib;zim;gir=irk, qux=quux

Descubra mais

Você pode ler o resto da documentação em https://gitlab.com/pmjones/ext-request para descobrir mais funcionalidades convenientes. E se você está preso no PHP 5.x, a extensão tem uma versão userland instalável via Composer como pmjones/request.

Experimente a extensão request hoje, porque algumas requisições server-side e objetos de resposta tornarão sua vida muito mais fácil.

***

Paul M. Jones faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: http://paul-m-jones.com/archives/6416.