7.1. Post, Get e Request

Nesse capítulo você aprenderá como recuperar dados de formulários, seus tipos (POST, GET e REQUEST) e formulários que suportam envio de arquivos.

Recuperando dados de Formulários

Para recuperar dados vindo de um fomulário é preciso saber qual tipo de protocolo foi informado no formulário. Para formulário do tipo post as informações devem ser recebidas pela variável global de PHP do tipo $_POST[] e formulário do tipo get devem ser recebidos pela variável global $_GET[]. Existe um tipo especial que é o $_REQUEST[], que recebe tanto o tipo get quanto o tipo post, porém seu uso deve ser muito restrito (evitado).

Nota: Todas as vezes que sua aplicação receber dados de um formulário ou tiver interação com o usuário esses dados DEVEM ser tratados por meio de algumas funções do PHP.

Recuperando campos de texto via $_POST[].

  1. ..

  2. <h1>Formulário simples 1 (POST)</h1>

    1. <form action="<?= $_SERVER['PHP_SELF'] ?>"
  3. name="frmSimples1" id="frmSimples1" method="post">

  4. <input type="hidden" name="opc" value="1">

    1. <label>Nome:</label>
  5. <input type="text" name="nome" id="nome" maxlength="150" size="50">

    1. <br />
  6. <label>E-mail:</label>

  7. <input type="text" name="email" id="email" maxlength="150" size="50">

    1. <br /><br />
  8. <input type="submit" name="enviar">

  9. </form>

    1. <?php
  10. if (isset($_POST['opc']) == '1') :

  11. echo '<h2>Recuperando campos de texto do tipo post</h2>';

    1. echo 'Nome: ' . $_POST['nome'];
  12. echo '<br />E-mail: ' . $_POST['email'];

  13. endif;

  14. ?>

  15. ...

Salve em /home/seu_usuario/www/PHPBasico/Cap6/formSimples1.php, no browser digite http://localhost/PHPBasico/Cap6/formSimples1.php.

Nota: Todos os campos são recuperados da mesma forma, porém campos do tipo checkbox tem um comportamento um pouco diferente dos outros.

Recuperando campos de texto via $_GET[].

Salve o arquivo anterior como formSimples2.php e altere o method do formulário para o tipo get e substitua $_POST por $_GET. Digite no browser http://localhost/PHPBasico/Cap6/formSimples2.php.

Nota: Uma atenção especial deve ser dada ao se recuperar pelo método get, esse protocolo só aceita 255 caracteres.

Obs: links em modo geral são recuperados também com o $_GET[].

Recuperando campos do tipo checkbox e radiobutton.

  1. ...

  2. <h1>Formulário simples 3</h1>

    1. <form action="<?= $_SERVER['PHP_SELF'] ?>"
  3. name="frmSimples3" id="frmSimples3" method="post">

  4. <input type="hidden" name="opc" value="1">

    1. <label>Qual seu nível de conhecimento em PHP?<br /></label>
  5. <input type="radio" name='conhecimento' value='Não sei PHP'> Não sei PHP <br />

  6. <input type="radio" name='conhecimento' value='PHP Básico'> PHP Básico <br />

  7. <input type="radio" name='conhecimento' value='PHP Intermediário'> PHP Intermediário <br />

  8. <input type="radio" name='conhecimento' value='PHP Avançado'> PHP Avançado <br />

  9. <input type="radio" name='conhecimento' value='Jedi'> Jedi <br />

    1. <br />
  10. <label>Quais versão do PHP já utilizou?<br /></label>

  11. <input type="checkbox" name='versao[]' value='3.x'> 3.x <br />

  12. <input type="checkbox" name='versao[]' value='4.x'> 4.x <br />

  13. <input type="checkbox" name='versao[]' value='5.0'> 5.0 <br />

  14. <input type="checkbox" name='versao[]' value='5.3'> 5.3 <br />

  15. <input type="checkbox" name='versao[]' value='5.5'> 5.5 <br />

    1. <br /><br />
  16. <input type="submit" name="enviar">

  17. </form>

    1. <?php
  18. if (isset($_POST['opc']) == '1') :

  19. echo '<h2>Recuperando campos Checkbox e Radiobutton</h2>';

    1. echo 'Qual seu nível de conhecimento em PHP?<br />';
  20. echo 'R: ' . $_POST['conhecimento'] . '<br /><br />';

    1. echo 'Quais versão do PHP já utilizou?<br />';
  21. echo 'R: ' . $_POST['versao'][0] . '<br />'; //recupera o primeiro item selecionado

  22. var_dump($_POST['versao']); //Recupera todos os itens marcados

  23. endif;

  24. ?>

  25. ...

Salve em /home/seu_usuario/www/PHPBasico/Cap6/formSimples3.php, no browser digite http://localhost/PHPBasico/Cap6/formSimples3.php.

Tratamento de dados recuperados de formulário

É altamente recomendado tratar e validar quais quer dado que venha de um formulário, isso vai garantir um pouco mais de segurança em seu site. Abordarei aqui as principais e mais comuns funções de tratamento e validação. O Exercício a seguir mostrará como aplicar essas validações.

Tratamento de formulário com trim(), addslashes(), htmlspecialchars() e htmlentities()

  1. ...

  2. <h1>Tratando form 1</h1>

    1. <form action="<?= $_SERVER['PHP_SELF'] ?>"
  3. name="frmTrata1" id="frmTrata1" method="post">

  4. <input type="hidden" name="opc" value="1">

    1. <label>Nome:</label>
  5. <input type="text" name="nome" id="nome" maxlength="150" size="50">

    1. <br />
  6. <label>E-mail:</label>

  7. <input type="text" name="email" id="email" maxlength="150" size="50">

    1. <br /><br />
  8. <input type="submit" name="enviar">

  9. </form>

    1. <?php
  10. if (isset($_POST['opc']) == '1') :

  11. echo '<h2>Recuperando e tratando campos de texto do tipo post</h2>';

  12. echo 'Nome: ' . addslashes($_POST['nome']);

  13. echo '<br /><br />Nome: ' . htmlspecialchars(trim($_POST['nome']), ENT_COMPAT); //padrão

  14. echo '<br />E-mail: ' . htmlspecialchars(trim($_POST['email']), ENT_QUOTES);

  15. echo '<br /><br />Nome: ' . htmlentities(trim($_POST['nome']));

  16. echo '<br />E-mail: ' . htmlentities(trim($_POST['email']));

  17. echo '<br /><br />Nome: ' . htmlspecialchars(addslashes(trim($_POST['nome'])));

  18. echo '<br />E-mail: ' . htmlentities(addslashes(trim($_POST['email'])));

  19. endif;

  20. ?>

  21. ...

Salve em /home/seu_usuario/www/PHPBasico/Cap6/tratandoForm1.php, no browser digite http://localhost/PHPBasico/Cap6/tratandoForm1.php.

Tratamento de formulário com nl2br()

  1. ...

  2. <h1>Tratando form 2</h1>

    1. <form action="<?= $_SERVER['PHP_SELF'] ?>"
  3. name="frmTrata2" id="frmTrata2" method="post">

    1. <label>Nome:</label>
  4. <input type="text" name="nome" id="nome" maxlength="150" size="50">

    1. <br />
  5. <label>E-mail:</label>

  6. <input type="text" name="email" id="email" maxlength="150" size="50">

    1. <br />
  7. <label>Comentário:</label>

  8. <textarea name="comentario" id="comentario" cols="63" rows="10"></textarea>

    1. <br /><br />
  9. <input type="submit" name="enviar">

  10. </form>

    1. <?php
  11. if ($_POST) :

  12. echo '<br /><br />Nome: ' . htmlspecialchars(addslashes(trim($_POST['nome'])));

  13. echo '<br />E-mail: ' . htmlentities(addslashes(trim($_POST['email'])));

  14. echo '<br /><br />Nome: ' . addslashes(nl2br(trim($_POST['comentario'])));

  15. endif;

  16. ?>

  17. ...

Salve em /home/seu_usuario/www/PHPBasico/Cap6/tratandoForm2.php, no browser digite http://localhost/PHPBasico/Cap6/tratandoForm2.php.

Envio (upload) de arquivo

O upload de arquivos é muito comum em um site. Mas para que ele funcione seu formulário precisa informar ao HTML que ele será ser usado com a finalidade de upload, para isso basta utilizar o atributo enctype="multipart/form-data" na tag form.

Envio de dados com PHP e validação

  1. ...

  2. <h1>Upload de arquivo e validação</h1>

    1. <form action="<?= $_SERVER['PHP_SELF'] ?>"
  3. name="frmUpload" id="frmUpload" method="post" enctype="multipart/form-data">

    1. <label>Selecione uma magem:<br /></label>
  4. <input type="file" name="img" id="img" accept="image/*">

    1. <br /><br />
  5. <label>Selecione um Documento:<br /></label>

  6. <input type="file" name="doc" id="doc">

    1. <br /><br />
  7. <input type="submit" name="enviar">

  8. </form>

    1. <?php
    1. if ($_POST) :
  9. var_dump($_FILES['img']);

  10. var_dump($_FILES['doc']);

    1. function validaNomeCampo($nomeCampo = null)
  11. {

  12. if ($nomeCampo) {

  13. return true;

  14. } else {

  15. echo '<strong>Erro: O nome do campo deve ser informado!</strong>';

  16. exit;

  17. }

    1. }
    1. function verificaCampoVazio($nomeCampo = nul, array $campo = null)
  18. {

  19. if ($_FILES[$nomeCampo]['size'] !== 0) {

  20. return true;

  21. } else {

  22. echo '<strong> - Nenhum arquivo <em>'. $nomeCampo .'</em> para ser enviado!<br /></strong>';

  23. }

    1. }
    1. function validaCampo(array $campo = null)
  24. {

  25. if (is_array($campo)) {

  26. return true;

  27. } else {

  28. echo '<strong>Erro: O Campo deve ser um array!</strong>';

  29. exit;

  30. }

    1. if ($campo) {
  31. return true;

  32. } else {

  33. echo '<strong>Erro: O Campo deve ser informado!</strong>';

  34. exit;

  35. }

  36. }

    1. function upload($nomeCampo = null, array $campo = null)
  37. {

  38. $dir = __DIR__ . '/upload/';

    1. if (validaNomeCampo($nomeCampo)) {
  39. if (validaCampo($campo)) {

  40. $arquivo = $uploadfile = $dir . basename($_FILES[$nomeCampo]['name']);

    1. if (move_uploaded_file($_FILES[$nomeCampo]['tmp_name'], $uploadfile)) {
  41. echo "Arquivo válido e enviado com sucesso.<br />\n";

  42. } else {

  43. echo "Não foi possível gravar oarquivo<br />\n";

  44. }

  45. }

  46. }

  47. }

    1. if (verificaCampoVazio('img', $_FILES['img'])) {
  48. //verificando se upload é uma imagem

  49. if (!empty($_FILES['img']) && ($_FILES['img']['type'] == 'image/jpeg' ||

  50. $_FILES['img']['type'] == 'image/jpg' ||

  51. $_FILES['img']['type'] == 'image/png' ||

  52. $_FILES['img']['type'] == 'image/gif')) :

  53. echo 'Grava a imagem no servidor ou banco. Para isso é necessário

  54. utilizar $_FILES["img"]["tmp_name"] e ter permissão de escrita no

  55. servidor.<br /><br />';

    1. upload('img', $_FILES['img']);
    1. else :
  56. echo 'Erro: Arquivo enviado não é uma imagem.<br /><br />';

  57. endif;

  58. }

    1. if (verificaCampoVazio('doc', $_FILES['doc'])) {
  59. //verificando se upload é um documento ou planílha ODF ou PDF

  60. if ($_FILES['doc']['type'] == 'application/vnd.oasis.opendocument.spreadsheet' ||

  61. $_FILES['doc']['type'] == 'application/vnd.oasis.opendocument.text' ||

  62. $_FILES['doc']['type'] == 'application/pdf') :

  63. echo 'Grava a imagem no servidor ou banco. Para isso é necessário

  64. utilizar $_FILES["doc"]["tmp_name"] e ter permissão de escrita no

  65. servidor.<br /><br />';

    1. upload('doc', $_FILES['doc']);
    1. else :
  66. echo 'Erro: Arquivo enviado não documento ou planílha ODF ou PDF.<br /><br />';

  67. endif;

  68. }

    1. endif;
  69. ?>

  70. ...

Salve em /home/seu_usuario/www/PHPBasico/Cap6/formUpload.php, no browser digite http://localhost/PHPBasico/Cap6/formUpload.php.

Evitando o CSRF (Cross Site Request Forgery)

Como já foi falado várias vezes durante o curso, segurança é um ponto que devemos sempre estar atento. Nesse tópico abordaremos mais ponto de segurança, o CSRF, popularmente conhecido como token de formulário. Para facilitar o entendimento e testes, faremos os exercícios em várias etapas e dividiremos em 2 arquivos.

  1. ...

  2. <h1>Evitando o CSRF (Cross Site Request Forgery)</h1>

    1. <form action="recebeDados.php"
  3. name="frmCSRF" id="frmCSRF" method="post">

    1. <label>Nome:</label>
  4. <input type="text" name="nome" id="nome" maxlength="150" size="50">

    1. <br />
  5. <label>E-mail:</label>

  6. <input type="email" name="email" id="email" maxlength="150" size="50">

    1. <br />
  7. <label>Comentário:</label>

  8. <textarea name="comentario" id="comentario" cols="63" rows="10"></textarea>

    1. <br /><br />
  9. <input type="submit" name="enviar">

  10. </form>

  11. ...

Salve em /home/seu_usuario/www/PHPBasico/Cap6/formEvitandoCSRF.php, no browser digite http://localhost/PHPBasico/Cap6/formEvitandoCSRF.php.

Continuando a edição do arquivo criado anteriormente. Nesse momento faremos as principais validações e recuperação dos dados enviados pelo formulário no PHP. Abra o arquivo home/seu_usuario/www/PHPBasico/Cap6/formEvitandoCSRF.php e edite logo abaixo da tag <body>.

  1. ...

  2. <body>

  3. <?php

  4. //inicializando variáveis do form

  5. $nome = $email = $comentario = null;

  6. $erros = [];

    1. function exibeErros($campo = null, array $erros = null)
  7. {

  8. if (isset($erros[$campo])) {

  9. echo $erros[$campo];

  10. unset($erros[$campo]);

  11. }

  12. }

  13. //verifica se houve subimit

  14. if ($_POST) {

  15. extract($_POST);

    1. if (trim($nome) == "") {
  16. $erros['nome'] = '<br /><div><strong>Erro:</strong> O Campo <strong>nome</strong> deve ser preenchido.</div>';

  17. }

    1. if (trim($email) == "") {
  18. $erros['email'] = '<br /><div><strong>Erro:</strong> O Campo <strong>e-mail</strong> deve ser preenchido.</div>';

  19. }

    1. if (trim($comentario) == "") {
  20. $erros['comentario'] = '<br /><div><strong>Erro:</strong> O Campo <strong>comentário</strong> deve ser preenchido.</div>';

  21. }

    1. //Se não houver erro exibe os dados na tela
  22. if (empty($erros)) {

  23. echo 'Nome: ' . addslashes(trim($nome)) . '<br />';

  24. echo 'E-mail: ' . addslashes(trim($email)) . '<br />';

  25. echo 'Comentário:<br /><br />' . addslashes(trim(nl2br($comentario))) . '<br />';

  26. }

  27. }

  28. ?>

  29. <h1>Evitando o CSRF (Cross Site Request Forgery)</h1>

  30. ...

Salve em /home/seu_usuario/www/PHPBasico/Cap6/formEvitandoCSRF.php, no browser digite http://localhost/PHPBasico/Cap6/formEvitandoCSRF.php.

Vamos agora testar nosso formulário e veremos como ainda está vulnerável a ataques. Abra o terminal (CTRL+T) e digite o seguinte comando: curl -d 'nome=qualquer nome&email=qualquer email&comentario=qualquer comentário' http://localhost/CursoPHP/PHPBasico/Cap6/formEvitandoCSRF.php e veja que os valores digitados foram enviados e exibidos na tela. Isso indica o quão vulnerável ainda está seu formulário.

Dando continuidade ao exercício proposto criaremos um arquivo para fazer as funções de validações contra o CSRF.

  1. <?php

    1. function geraToken()
  2. {

  3. return $_SESSION['token'] = base64_encode(openssl_random_pseudo_bytes(32));

  4. }

    1. function verificaToken($token)
  5. {

  6. if (isset($_SESSION['token']) && $token === $_SESSION['token']) {

  7. unset($_SESSION['token']);

  8. return true;

  9. }

    1. return false;
  10. }

  11. //essa linha vazia tem que existir.

Salve em /home/seu_usuario/www/PHPBasico/Cap6/protecaoContraCSRF.php.

Continuando a edição do arquivo ormEvitandoCSRF.php. Nesse momento faremos a validação necessária para que a proteção contra o CSRF funcione. Abra o arquivo home/seu_usuario/www/PHPBasico/Cap6/formEvitandoCSRF.php e edite o arquivo logo na primeira linha.

  1. <?php

  2. session_start();

  3. require_once 'protecaoContraCSRF.php';

  4. ?>

Salve em /home/seu_usuario/www/PHPBasico/Cap6/formEvitandoCSRF.php.

Continue editando o arquivo formEvitandoCSRF.php. Posicione o cursor depois do comentário 'if ($_POST) {', e envolva todo o código PHP com a validação contra o CSRF, como no exercício abaixo.

  1. ...

  2. //verifica se houve subimit

  3. if ($_POST) {

  4. if (verificaToken(isset($_POST['token']))) {

  5. extract($_POST);

    1. if (trim($nome) == "") {
  6. ...

  7. }// fim do if (verificaToken())

  8. ...

  9. }// fim do if ($_POST)

  10. ?>

  11. ...

Salve em /home/seu_usuario/www/PHPBasico/Cap6/formEvitandoCSRF.php.

Agora para finalizar, crie um campo do tipo hidden com o nome token. Esse campo pode ser o primeiro campo do formulário.

  1. ...

  2. <h1>Evitando o CSRF (Cross Site Request Forgery)</h1>

    1. <form action="" name="frmCSRF" id="frmCSRF" method="post">
  3. <input type="hidden" name="token" value="<?= geraToken() ?>" />

    1. <label>Nome:</label>
  4. ...

Salve em /home/seu_usuario/www/PHPBasico/Cap6/formEvitandoCSRF.php, no browser digite http://localhost/PHPBasico/Cap6/formEvitandoCSRF.php.

Vamos agora testar nosso formulário novamente. Abra o terminal (CTRL+T) e digite o seguinte comando: curl -d 'nome=qualquer nome&email=qualquer email&comentario=qualquer comentário' http://localhost/CursoPHP/PHPBasico/Cap6/formEvitandoCSRF.php e veja que os valores digitados não são exibidos na tela. Isso indica que se alguém tentar enviar dados sem ser pelo site não conseguirá.

Resumo do Capítulo

Nesse capítulo aprendemos como recuperar dados passados através de formulários pelos métodos POST e GET, como recuperar dados de campos checkbox, tratamento e validações dos dados recebidos, upload de arquivos e como tonar seus formulários mais seguros contra o CSRF.

Exercícios

  1. Crie um formulário de cadastro básico de cliente contendo os campos: Nome, Sobrenome, data de nascimento, senha e-mail e cpf;

  2. Faça as validações necessárias para aplicar a segurança e evitar o CSRF;

  3. Se as validações tiverem certas, exibir os dados na tela para o usuário.

results matching ""

    No results matching ""