Requests

Visão Geral

Flight encapsula a requisição HTTP em um único objeto, que pode ser acessado fazendo:

$request = Flight::request();

Compreendendo

As requisições HTTP são um dos aspectos principais a entender sobre o ciclo de vida HTTP. Um usuário realiza uma ação em um navegador web ou em um cliente HTTP, e eles enviam uma série de cabeçalhos, corpo, URL, etc. para o seu projeto. Você pode capturar esses cabeçalhos (a linguagem do navegador, que tipo de compressão eles podem lidar, o agente do usuário, etc.) e capturar o corpo e a URL que são enviados para a sua aplicação Flight. Essas requisições são essenciais para que o seu app entenda o que fazer em seguida.

Uso Básico

PHP possui vários super globais, incluindo $_GET, $_POST, $_REQUEST, $_SERVER, $_FILES e $_COOKIE. Flight abstrai esses em coleções práticas Collections. Você pode acessar as propriedades query, data, cookies e files como arrays ou objetos.

Nota: É ALTAMENTE desaconselhável usar esses super globais no seu projeto e eles devem ser referenciados através do objeto request().

Nota: Não há abstração disponível para $_ENV.

$_GET

Você pode acessar o array $_GET via a propriedade query:

// GET /search?keyword=something
Flight::route('/search', function(){
    $keyword = Flight::request()->query['keyword'];
    // ou
    $keyword = Flight::request()->query->keyword;
    echo "Você está procurando por: $keyword";
    // consultar um banco de dados ou algo mais com o $keyword
});

$_POST

Você pode acessar o array $_POST via a propriedade data:

Flight::route('POST /submit', function(){
    $name = Flight::request()->data['name'];
    $email = Flight::request()->data['email'];
    // ou
    $name = Flight::request()->data->name;
    $email = Flight::request()->data->email;
    echo "Você enviou: $name, $email";
    // salvar em um banco de dados ou algo mais com o $name e $email
});

Você pode acessar o array $_COOKIE via a propriedade cookies:

Flight::route('GET /login', function(){
    $savedLogin = Flight::request()->cookies['myLoginCookie'];
    // ou
    $savedLogin = Flight::request()->cookies->myLoginCookie;
    // verificar se foi realmente salvo ou não e se foi, fazer login automático
    if($savedLogin) {
        Flight::redirect('/dashboard');
        return;
    }
});

Para ajuda em definir novos valores de cookie, veja overclokk/cookie

$_SERVER

Há um atalho disponível para acessar o array $_SERVER via o método getVar():


$host = Flight::request()->getVar('HTTP_HOST');

$_FILES

Você pode acessar arquivos enviados via a propriedade files:

// acesso raw à propriedade $_FILES. Veja abaixo para a abordagem recomendada
$uploadedFile = Flight::request()->files['myFile']; 
// ou
$uploadedFile = Flight::request()->files->myFile;

Veja Uploaded File Handler para mais informações.

Processando Uploads de Arquivos

v3.12.0

Você pode processar uploads de arquivos usando o framework com alguns métodos auxiliares. Basicamente, isso se resume a extrair os dados do arquivo da requisição e movê-lo para um novo local.

Flight::route('POST /upload', function(){
    // Se você tivesse um campo de entrada como <input type="file" name="myFile">
    $uploadedFileData = Flight::request()->getUploadedFiles();
    $uploadedFile = $uploadedFileData['myFile'];
    $uploadedFile->moveTo('/path/to/uploads/' . $uploadedFile->getClientFilename());
});

Se você tiver múltiplos arquivos enviados, você pode iterar por eles:

Flight::route('POST /upload', function(){
    // Se você tivesse um campo de entrada como <input type="file" name="myFiles[]">
    $uploadedFiles = Flight::request()->getUploadedFiles()['myFiles'];
    foreach ($uploadedFiles as $uploadedFile) {
        $uploadedFile->moveTo('/path/to/uploads/' . $uploadedFile->getClientFilename());
    }
});

Nota de Segurança: Sempre valide e sanitize a entrada do usuário, especialmente ao lidar com uploads de arquivos. Sempre valide o tipo de extensões que você permitirá ser enviado, mas você também deve validar os "magic bytes" do arquivo para garantir que é realmente o tipo de arquivo que o usuário afirma que é. Há artigos e bibliotecas disponíveis para ajudar com isso.

Corpo da Requisição

Para obter o corpo raw da requisição HTTP, por exemplo ao lidar com requisições POST/PUT, você pode fazer:

Flight::route('POST /users/xml', function(){
    $xmlBody = Flight::request()->getBody();
    // faça algo com o XML que foi enviado.
});

Corpo JSON

Se você receber uma requisição com o tipo de conteúdo application/json e os dados de exemplo {"id": 123} ele estará disponível na propriedade data:

$id = Flight::request()->data->id;

Cabeçalhos da Requisição

Você pode acessar os cabeçalhos da requisição usando o método getHeader() ou getHeaders():


// Talvez você precise do cabeçalho Authorization
$host = Flight::request()->getHeader('Authorization');
// ou
$host = Flight::request()->header('Authorization');

// Se você precisar pegar todos os cabeçalhos
$headers = Flight::request()->getHeaders();
// ou
$headers = Flight::request()->headers();

Método da Requisição

Você pode acessar o método da requisição usando a propriedade method ou o método getMethod():

$method = Flight::request()->method; // na verdade populado pelo getMethod()
$method = Flight::request()->getMethod();

Nota: O método getMethod() primeiro puxa o método de $_SERVER['REQUEST_METHOD'], então ele pode ser sobrescrito por $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] se existir ou $_REQUEST['_method'] se existir.

Propriedades do Objeto Request

O objeto request fornece as seguintes propriedades:

  • body - O corpo raw da requisição HTTP
  • url - A URL sendo requisitada
  • base - O subdiretório pai da URL
  • method - O método da requisição (GET, POST, PUT, DELETE)
  • referrer - A URL de referência
  • ip - Endereço IP do cliente
  • ajax - Se a requisição é uma requisição AJAX
  • scheme - O protocolo do servidor (http, https)
  • user_agent - Informações do navegador
  • type - O tipo de conteúdo
  • length - O comprimento do conteúdo
  • query - Parâmetros da string de query
  • data - Dados POST ou dados JSON
  • cookies - Dados de cookie
  • files - Arquivos enviados
  • secure - Se a conexão é segura
  • accept - Parâmetros HTTP accept
  • proxy_ip - Endereço IP proxy do cliente. Escaneia o array $_SERVER por HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR, HTTP_X_FORWARDED, HTTP_X_CLUSTER_CLIENT_IP, HTTP_FORWARDED_FOR, HTTP_FORWARDED nessa ordem.
  • host - O nome do host da requisição
  • servername - O SERVER_NAME de $_SERVER

Métodos Auxiliares

Há alguns métodos auxiliares para juntar partes de uma URL, ou lidar com certos cabeçalhos.

URL Completa

Você pode acessar a URL completa da requisição usando o método getFullUrl():

$url = Flight::request()->getFullUrl();
// https://example.com/some/path?foo=bar

URL Base

Você pode acessar a URL base usando o método getBaseUrl():

// http://example.com/path/to/something/cool?query=yes+thanks
$url = Flight::request()->getBaseUrl();
// https://example.com
// Note, sem barra no final.

Análise de Query

Você pode passar uma URL para o método parseQuery() para analisar a string de query em um array associativo:

$query = Flight::request()->parseQuery('https://example.com/some/path?foo=bar');
// ['foo' => 'bar']

Negociar Tipos de Conteúdo Aceitos

v3.17.2

Você pode usar o método negotiateContentType() para determinar o melhor tipo de conteúdo para responder com base no cabeçalho Accept enviado pelo cliente.


// Exemplo de cabeçalho Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
// O abaixo define o que você suporta.
$availableTypes = ['application/json', 'application/xml'];
$typeToServe = Flight::request()->negotiateContentType($availableTypes);
if ($typeToServe === 'application/json') {
    // Sirva resposta JSON
} elseif ($typeToServe === 'application/xml') {
    // Sirva resposta XML
} else {
    // Padrão para algo mais ou lance um erro
}

Nota: Se nenhum dos tipos disponíveis for encontrado no cabeçalho Accept, o método retornará null. Se não houver cabeçalho Accept definido, o método retornará o primeiro tipo no array $availableTypes.

Veja Também

Solução de Problemas

  • request()->ip e request()->proxy_ip podem ser diferentes se o seu servidor web estiver atrás de um proxy, balanceador de carga, etc.

Changelog

  • v3.17.2 - Adicionado negotiateContentType()
  • v3.12.0 - Adicionada capacidade de lidar com uploads de arquivos através do objeto request.
  • v1.0 - Lançamento inicial.