PHP DO BÁSICO AO AVANÇADO – AULA 18 – cURL e E-Mail com PHP

Tempo de Leitura: 18 Minutos

Nesta aula, vamos dar continuidade as funções da cURL que é a biblioteca necessária para se comunicar com servidores externos e manipular diretamente conexões via protocolos como HTTP e HTTPS, na aula anterior falamos sobre como é feita a conexão, e as etapas para fazer a manipulação do conteúdo do corpo, autenticação, e cabeçalhos, e os possíveis valores de configuração aceitos pelo PHP. Agora vamos ver como montar as requisições passo a passo e como podemos tratar os dados recebidos.

Na aula anterior, vemos as funções curl_version(), curl_init() e curl_setopt(), neste ponto, vamos falar sobre as demais funções:
curl_setopt_array($handle, $arrOptions); – Define várias opções simultaneamente para uma sessão cURL. Esta função é útil para definir um grande número de opções cURL sem chamar curl_setopt() repetidamente, o array associativo $arrOptions é composto da estrutura array(CURLOPT_CONSTSANTE => ‘VALOR’, CURLOPT_CONSTANTE2 => valor); onde cada CURLOPT_CONSTANTE é um valor dos apresentados na aula passada, e o valor é o que será definido, de acordo com o seu tipo.

curl_close($handle); – Finaliza o handle informado, fechando a conexão e destruindo o handle. Deve sempre ser chamada para liberar a conexão e a respectiva comunicação/porta do servidor.

curl_errno($handle); – Retorna o código do ultimo erro ocorrido, ou zero em caso de sucesso. Os erros são:
1 – Protocolo Não Suportado
2 – O código de inicialização falhou precocemente. É provável que seja um erro ou problema interno, ou um problema de recurso em que algo fundamental não pôde ser feito no tempo de inicialização.
3 – URL Mal formada
4 – Um recurso, protocolo ou opção solicitado não foi encontrado. Significa que um recurso ou opção não foi habilitado ou desabilitado explicitamente quando o libcurl foi compilado.
5 – Não resolvido o proxy
6 – Host não resolvido
7 – Falha na conexão ao host ou ao proxy
8 – O servidor enviou dados que libcurl não conseguiu analisar
9 – O acesso ao recurso fornecido no URL foi negado. Para FTP, isso ocorre ao tentar mudar para o diretório remoto.
10 – Enquanto esperava que o servidor se conectasse novamente quando uma sessão de FTP ativa for usada, um código de erro foi enviado pela conexão de controle ou similar.
11 – Depois de enviar a senha do FTP ao servidor, libcurl espera uma resposta adequada. Este código de erro indica que um código inesperado foi retornado.
12 – Tempo limite de espera em uma conexão FTP
13 – falhou em obter um resultado razoável do servidor como uma resposta a um comando PASV ou EPSV. O servidor pode estar com problemas
14 – Os servidores FTP retornam 227 linhas em resposta a um comando PASV. Se libcurl falhar em analisar essa linha, este código de retorno será passado de volta.
15 – Uma falha interna ao pesquisar o host usado para a nova conexão.
16 – Foi detectado um problema na camada de enquadramento HTTP2. Isso é um tanto genérico e pode ser um dos vários problemas, consulte o buffer de erro para obter detalhes.
17 – Recebido um erro ao tentar definir o modo de transferência para binário ou ASCII
18 – Uma transferência de arquivo foi menor ou maior do que o esperado. Isso acontece quando o servidor primeiro relata um tamanho de transferência esperado e, em seguida, entrega os dados que não correspondem ao tamanho fornecido anteriormente.
19 – Esta foi uma resposta estranha a um comando ‘RETR’ ou uma transferência de zero byte completa.
21 – Ao enviar comandos “QUOTE” personalizados para o servidor remoto, um dos comandos retornou um código de erro 400 ou superior (para FTP) ou indicou uma conclusão malsucedida do comando.
22 – Isso será retornado se CURLOPT_FAILONERROR for definido como TRUE e o servidor HTTP retornar um código de erro> = 400.
23 – Ocorreu um erro ao gravar os dados recebidos em um arquivo local ou um erro foi retornado para libcurl a partir de um retorno de chamada de gravação.
25 – Falha ao iniciar o upload. Para FTP, o servidor normalmente negou o comando STOR. O buffer de erro geralmente contém a explicação do servidor para isso.
26 – Ocorreu um problema ao ler um arquivo local ou um erro retornado pelo retorno de leitura de leitura.
27 – Uma solicitação de alocação de memória falhou. Isso é uma anormalidade séria e as coisas ficam confusas se isso acontecer.
28 – Tempo limite de operação. O período de tempo limite especificado foi atingido de acordo com as condições.
30 – O comando FTP PORT retornou um erro. Isso acontece principalmente quando você não especificou um endereço bom o suficiente para o libcurl usar. Consulte CURLOPT_FTPPORT.
31 – O comando FTP REST retornou um erro. Isso nunca deve acontecer se o servidor estiver ok.
33 – O servidor não suporta ou aceita solicitações de intervalo.
34 – Este é um erro estranho que ocorre principalmente devido a confusão interna.
35 – Ocorreu um problema em algum lugar no handshake SSL / TLS. Você realmente quer o buffer de erro e ler a mensagem lá, pois ela aponta o problema um pouco mais. Podem ser certificados (formatos de arquivo, caminhos, permissões), senhas e outros.
36 – O download não pôde ser retomado porque o deslocamento especificado estava fora do limite do arquivo.
37 – Um arquivo fornecido com FILE: // não pôde ser aberto. Provavelmente porque o caminho do arquivo não identifica um arquivo existente. Você verificou as permissões do arquivo?
38 – O LDAP não pode ser vinculado. Falha na operação de ligação do LDAP.
39 – Falha de procura LDAP
41 – Função não encontrada. Uma função zlib necessária não foi encontrada.
42 – Abortado por retorno de chamada. Um retorno de chamada retornou “abort” para libcurl.
43 – Uma função foi chamada com um parâmetro incorreto
45 – Erro de interface. Uma interface de saída especificada não pôde ser usada. Defina qual interface usar para o endereço IP de origem das conexões de saída com CURLOPT_INTERFACE.
47 – Muitos redirecionamentos. Ao seguir redirecionamentos, libcurl atingiu a quantidade máxima. Defina seu limite com CURLOPT_MAXREDIRS.
48 – Uma opção passada para libcurl não é reconhecida / conhecida. Consulte a documentação apropriada. Este é provavelmente um problema no programa que usa libcurl. O buffer de erro pode conter informações mais específicas sobre a opção exata a que se refere.
49 – Uma string de opção telnet foi formatada ilegalmente.
52 – Nada foi retornado do servidor e, nessas circunstâncias, não receber nada é considerado um erro.
53 – O mecanismo de criptografia especificado não foi encontrado
54 – Falha ao definir o mecanismo de criptografia SSL selecionado como padrão!
55 – Erro no envido de dados
56 – Erro no recebimento de dados
58 -Problema com o certificado do cliente
59 – Não foi possível usar cifra especificada
60 – O certificado SSL do servidor remoto ou impressão digital SSH md5 não foi considerado OK. Este código de erro foi unificado com CURLE_SSL_CACERT desde 7.62.0. Seu valor anterior era 51.
61 – Codificação de transferência não reconhecida.
62 – URL LDAP Inválida
63 – Máximo de arquivos Excedido
64 – O nível de SSL de FTP solicitado falhou
65 – Ao fazer uma operação de envio, o curl teve que retransmitir os dados para retransmitir, mas a operação de retransmissão falhou.
66 – Falha ao iniciar o mecanismo SSL
67 – O servidor remoto negou curl para fazer login
68 – Arquivo não encontrado no servidor TFTP
69 – Problema de permissão no servidor TFTP
70 – Sem espaço em disco no servidor
71 – TFTP Operação Ilegal
72 – ID inexistente no TFTP
73 – O arquivo já existe e não será sobrescrito
74 – Este erro nunca deve ser retornado por um servidor TFTP funcionando corretamente
75 – Falha na conversão de Caracteres
76 – O chamador deve registrar retornos de conversão
77 – Problema ao ler o certificado SSL CA – Geralmente erro de caminho ou de permissão
78 – O recurso referenciado no URL não existe
79 – Ocorreu um erro não especificado durante a sessão SSH
80 – Falha ao desligar a conexão SSL
81 – O soquete não está pronto para envio / recebimento, espere até que esteja pronto e tente novamente. Este código de retorno só é retornado de curl_easy_recv e curl_easy_send
82 – Falha ao carregar um arquivo CRF
83 – Falha na verificação do emissor
84 – O servidor FTP não entende o comando PRET ou não suporta o argumento fornecido. Tenha cuidado ao usar CURLOPT_CUSTOMREQUEST, um comando LIST personalizado será enviado com PRET CMD antes do PASV também.
85 – Incompatibilidade de números RTSP CSeq.
86 – Incompatibilidade de identificadores de sessão RTSP
87 – Não foi possível analisar a lista de arquivos FTP (durante o download de caracteres curinga no FTP)
88 – Relato de erro em CHUNCK CALLBACK
89 – Nenhuma conexão disponível, a sessão será enfileirada
90 – Falha ao corresponder à chave fixada especificada com CURLOPT_PINNEDPUBLICKEY
91 – status retornou falha quando solicitado com CURLOPT_SSL_VERIFYSTATUS
92 – Erro de fluxo na camada de enquadramento HTTP / 2
93 – Uma função API foi chamada de dentro de um retorno de chamada.
94 – Uma função de autenticação retornou um erro
95 – Um problema foi detectado na camada HTTP / 3. Isso é um tanto genérico e pode ser um de vários problemas, consulte o buffer de erro para obter detalhes
96 – Erro de conexão QUIC. Este erro pode ser causado por um erro da biblioteca SSL. QUIC é o protocolo usado para transferências HTTP / 3

curl_error ( $handle ); – Retorna uma mensagem de erro em forma de texto, em inglês, com os erros acima.

curl_strerror($handle); – Retorna uma string, que pode ser uma das constantes definidas no PHP ou em outras implementaçãoes especificando um dos erros anteriores, por exemplo CURLE_OK é retornado quando o valor do erro é 0;

curl_escape($handle, $strURL); – Codifica a STRING data para ser transmitida por URL, de maneira similar a urlencode() porém seguindo o formato cURL especificado pela RFC

curl_unescape($handle, $strURLcoded); – Descodifica a STRING data recebida no formato URL ENCODED

curl_getinfo($handle, $opt); – Obtenha informações sobre uma transferência específica, $OPT pode ser uma das seguintes constantes: CURLINFO_EFFECTIVE_URL – Último URL efetivo
CURLINFO_HTTP_CODE – Último código HTTP recebido
CURLINFO_FILETIME – Horário remoto do documento recuperado, se -1 for retornado, o horário do documento é desconhecido
CURLINFO_TOTAL_TIME – Tempo total da transação em segundos para a última transferência
CURLINFO_NAMELOOKUP_TIME – Tempo em segundos até a resolução do nome ser concluída
CURLINFO_CONNECT_TIME – Tempo em segundos que levou para estabelecer a conexão
CURLINFO_PRETRANSFER_TIME – Tempo em segundos desde o início até um pouco antes do início da transferência do arquivo
CURLINFO_STARTTRANSFER_TIME – Tempo em segundos até que o primeiro byte esteja prestes a ser transferido
CURLINFO_REDIRECT_COUNT – Número de redirecionamentos
CURLINFO_REDIRECT_TIME – Tempo em segundos de todas as etapas de redirecionamento antes do início da transação final
CURLINFO_SIZE_UPLOAD – Número total de bytes enviados
CURLINFO_SIZE_DOWNLOAD – Número total de bytes baixados
CURLINFO_SPEED_DOWNLOAD – Velocidade média de download
CURLINFO_SPEED_UPLOAD – Velocidade média de upload
CURLINFO_HEADER_SIZE – Tamanho total de todos os cabeçalhos recebidos
CURLINFO_HEADER_OUT – A string de solicitação enviada. Para que isso funcione, adicione a opção CURLINFO_HEADER_OUT ao identificador chamando curl_setopt ()
CURLINFO_REQUEST_SIZE – Tamanho total das solicitações emitidas, atualmente apenas para solicitações HTTP
CURLINFO_SSL_VERIFYRESULT – Resultado da verificação da certificação SSL solicitada pela configuração
CURLOPT_SSL_VERIFYPEER CURLINFO_CONTENT_LENGTH_DOWNLOAD – comprimento do conteúdo do download, lido do campo Comprimento do conteúdo
CURLINFO_CONTENT_LENGTH_UPLOAD – Tamanho de upload especificado
CURLINFO_CONTENT_TYPE – Content-Type: do documento solicitado, NULL indica que o servidor não enviou um Content-Type: cabeçalho válido

curl_file_create(); – Cria um OBJETO tipo FILE para ser usado em uma conexão cURL, veja um exemplo que uma função que faz o UPLOAD de um arquivo, como se fosse um FORM HTML

uploadFile($name,$i=0){
    $postField = array();
    $tmpfile = $_FILES[$name]['tmp_name'][$i];
    $filename = basename($_FILES[$name]['name'][$i]);
    $postField['files'] =  curl_file_create($tmpfile, $_FILES[$name]['type'][$i], $filename);
    $headers = array("Content-Type" => "multipart/form-data");
    $curl_handle = curl_init();
    curl_setopt($curl_handle, CURLOPT_URL, 'Put here curl API');
    curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl_handle, CURLOPT_POST, TRUE);
    curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $postField);
    curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, TRUE);
    $returned_fileName = curl_exec($curl_handle);
    curl_close($curl_handle);
    return json_decode($returned_fileName);
}

curl_copy_handle($handle); – Copia o HANDLE com as configurações atuais chiando outro handle, como $handle2 = curl_copy_handle($handle);

curl_pause($handle); – Pause e retoma uma conexão, usando esta função, você pode marcar explicitamente uma conexão em execução para ser pausada e pode retomar uma conexão que foi pausada anteriormente. Uma conexão pode ser pausada usando esta função ou permitindo que os retornos de chamada de leitura ou gravação retornem o código de retorno mágico apropriado (CURL_READFUNC_PAUSE e CURL_WRITEFUNC_PAUSE). Um retorno de chamada de gravação que retorna sinais de pausa para a biblioteca de que ela não poderia cuidar de nenhum dado e que os dados serão entregues novamente ao retorno de chamada quando a gravação for retomada posteriormente.

curl_reset($handle); –  Reinicia todas as opções de um controlador de sessão libcurl, retornando paraos valores padrão, ou seja, afeta todos os recursos setados por curl_setopt() e curl_setopt_array()

curl_exec($handle); – Execute a sessão cURL fornecida. Esta função deve ser chamada após inicializar uma sessão cURL e todas as opções para a sessão estarem definidas. Ela que efetiva a conexão dentro dos parâmetros especificados em curl_setopt.

curl_multi_init(); – Cria um recurso $MultHandle para executar múltiplas conexões de maneira conjunta, abaixo vamos exemplificar as outras funções para execução de multi conexões

curl_multi_add_handle( $MultHandle, $handle); – Adiciona a conexão criada em $handle e seus parametros atuais para execução múltipla

curl_multi_remove_handle($MultiHandle, $handle); – Remove a conexão definida em $handle da execução múltipla

curl_multi_select($MultiHandle, $timout); – Espera $timout de tempo em segundos (ou fração de segundos) por uma atividade das $handles dentro da $MultiHandle, deixa o sistema parado (bloqueado) até que haja atividade em qualquer uma das conexões curl_multi ou que $timeout seja atingido. Em caso de sucesso, retorna o número dos descritores contidos nos conjuntos de descritores. Em caso de falha, esta função retornará -1 em uma falha de seleção ou tempo limite.

curl_multi_setopt ( $multhandle , $option , $value ); – de maneira analoga a curl_setopt, ela define um valor usando uma das constantes da função setopt, porém, define o mesmo valor para todas as $handles existentes na $multiHandle

curl_multi_strerror($multHandle); – Retorna o erro em formato string, em inglês, de maneira analoga a strerror, porém, de qualquer uma das conexões existentes no $multHandler

curl_multi_errno($multiHandle); -Retorna o erro em formato numérico, de qualquer uma das conexões existente no $multHandle

curl_multi_exec($multHandle); – Executa as conexões existentes em $multHandle

curl_multi_getcontent($handle); – Retorna o conteúdo da Handle especificada

curl_multi_close($multHandle); – Fecha todas as conexões contidas no $multHandle

curl_multi_info_read($multHandle, $iMsg); – Pergunta ao multi-identificador se existem mensagens ou informações das transferências individuais. As mensagens podem incluir informações como um código de erro da transferência ou apenas o fato de que a transferência foi concluída. Chamadas repetidas para esta função retornarão um novo resultado a cada vez, até que um falso seja retornado como um sinal de que não há mais nada a ser obtido neste ponto. O número inteiro apontado com $iMSG conterá o número de mensagens restantes depois que esta função foi chamada.

curl_share_init(); – Retorna um resource do tipo “Controlador de Compartilhamento de cURL” (“cURL Share Handle”).

curl_share_setopt ($sh, $option , $value); – $sh criada anteriormente, e seta um valor setopt nas conexões compartilhadas

curl_share_errno ($sh); – Retorna um dos código de erros de curl para as conexões compartilhadas

curl_share_strerror($sh); – Retorna uma das mensagens de erro de curl para as conexões compartilhadas

curl_share_close ($sh); – Fecha as conexões compartilhadas.

Envio de E-MAIL com PHP

O PHP possui algumas classes como a PHPMAILER (que pode ser visto aqui) que permite a comunicação direta com um servidor SMTP/POP3 remoto para o envio e recebimento de emails, em máquinas remotas, que suporta autenticação e diversos parâmetros específicos para isso. Além de possuir extensões PEAR como a extensão:

MAIL PEAR que define uma interface para a implementação de remetentes de correio sob a hierarquia PEAR. Ele também fornece funções de suporte úteis para vários back-ends de mailer. Os back-ends atualmente suportados incluem: função mail () nativa do PHP, sendmail e SMTP e também fornece uma classe de utilitário de validação de lista de endereços de e-mail pela RFC822.

MAIL QUEUE que permite lidar com o gerenciamento da fila de mensagens e pode carregar, salvar e enviar e-mails salvos em segundo plano e também fazer backup de alguns e-mails. A classe Mail_Queue coloca os emails em um contêiner temporário, esperando para serem alimentados ao MTA (Agente de Transporte de Correio) e os envia mais tarde (por exemplo, uma certa quantidade de emails a cada poucos minutos) por crontab ou outra maneira, sendo ideal para grandes volumes de mensagens.

Porém, para situações mais simples, onde o volume de emails é baixo, e ocorre de maneira simplificada, a função mail() nativa faz o gerenciamento básico, sua principal função é o envio de mensagens para  notificações e neste primeiro momento vamos falar e utilizar ela para nosso cadastro de usuários.

A assinatura da função é mail( $to , $subject , $message, $additional_headers , $additional_parameters) e retorna true em caso de sucesso ou false em caso de erro. $to é o destinatário ou destinatários do email, seguindo o padrão RFC, $subject é o texto colocado no assunto do email e deve ser limitado a 70 caracteres, para atender ao padrão RFC porém o php e o sendmail dos sistemas unix permite valores maiores. $message é o corpo do email, e pode ser texto puro ou html, lembre-se que caso vá utilizar html é necessário alguns parâmetros opcionais, e pelo padrão definido na RFC caso existam classes e styles css estes não podem ser importados e devem estar escritos dentro do corpo do email. Já os 2 parâmetros seguintes são opcionais e $additional_headers são os cabeçalhos enviados no email, e eles podem mudar ou adicionar algum parâmetro, como definir que o conteúdo é HTML, definir conteúdos alternativos em texto, caso a visualização HTML não esteja disponível, mascara de endereçamento do remetente ou destinatário, anexos, entre outros. Por fim $additional_parameters são parâmetros opcionais do comando sendmail do unix, que é usado para fazer o envio em sistemas posix. Este ultimo parâmetro deve ser tomado muito cuidado, e os valores dele devem ser tratados de maneira correta, para evitar que conteúdos indesejados possam ser executados na console do servidor, já que este parametro é literalmente adicionado a execução do comando sendmail.

O formato dos destinatários $to podem ser os seguintes:
[email protected] – indica um único email
[email protected], [email protected] – Indica mais de um destinatário, onde cada um está separado por virgula, lembre-se que usando dessa maneira, todos os destinatários podem ver todos os emails da lista
User <[email protected]> – Formato usado para mascarar o email com um NOME, seguindo o padrão RFC para deixar o destinatário mais legível ou amigável
User <[email protected]>, Another User <[email protected] – Uma lista de emails similar a anterior, porém com todos os nomes mascarados para um padrão RFC amigável
[email protected], User Test <[email protected]> – Um misto dos dois separadores também pode ser usado

Vamos escrever o código e a view usadas para a criação de um novo usuário, e acrescentar ao nosso control login, para que você possa entender como funciona o envio de emails simples com o PHP usando a função MAIL, neste exemplo, vamos também acrescentar uma função do nosso framework que faz a leitura de um conteúdo de um arquivo e o envia, substituindo as variáveis passadas pelo conteúdo, vamos aos códigos.

No nosso diretório _framework, criamos um arquivo com as funções responsáveis pelo tratamento e envio de email, e seu conteúdo é:

<?php
/**
 * BRASAP FRAMEWORK START FILE
 *  php version 7.4.3
 * 
 * @category BRASAP
 * @package  BRASAP/MailSender
 * @author   Romeu Gomes de Sousa <[email protected]>
 * @license  GNU GPL 3.0 - Livre uso e Distribuição
 * @version  GIT:  
 * @link     https://brasap.com.br
 */

/**
 * Envia um email de um arquivo HTML estático
 * 
 * @param $email     = URL - email_do_destinatario
 * @param $assunto   = String - Assunto do email
 * @param $file_html = basename - nome de um arquivo do diretório de emails
 * @param $valores   = Array de variaveis para substituir o conteúdo de dentro do
 *                   do html pelos valores passados em $vals
 * 
 * @return BOOLEAN - true para enviado / false para falha
 */
function eMail($email, $assunto, $file_html, $valores = array())
{
    $email = filter_var($email, FILTER_SANITIZE_EMAIL);
    $header  = "MIME-Version: 1.0\r\n";
    $header .= "Content-type: text/html; charset=utf-8\r\n";
    $header .= "From: ".EMAIL_FROM."\r\n";
    $html=file_get_contents(__DIR__."/_framework/_mailfile/$file_html");
    $vars = array_keys($valores);
    foreach ($vars as &$v) {
        //adiciona COLCHETES, retira ESPAÇOS e coloca VALORES EM MAIUSCULO
        $v = '['.str_replace(' ', '_', strtoupper(trim($v))).']';
    }
    $vals = array_values($valores);
    $html = str_replace($vars, $vals, $html);
    if (mail($email, $assunto, $html, $header, "-f ".EMAIL)) {
        return true;
    } else {
        return false;
    }
}

Esta função, basicamente recebe o destinatário do email, o assunto desejado, o nome do arquivo HTML do conteúdo e um array associativo, que contém as chaves nomes de variáveis existentes no conteúdo HTML e valores para essas variáveis, se as variáveis forem encontradas são substituídas pelo conteúdo passado. As variáveis devem estar setadas entre colchetes e com valores sem espaço, usando SNAKE_CASE para se concatenar, similar a: [NOME_DO_CONTATO]

Criamos também a tela de cadastro, que é basicamente um HTML, onde os valores dos campos são passados pelo control, para poder ser feita a validação no PHP, sei que não é o método mais eficiente, porém, quero usa-lo para poder exemplificar o uso de algumas funções de manipulação de string e de expressões regulares, vamos ao código:

<?php
/**
 * BRASAP FRAMEWORK VIEW - TELA DE CRIAR SUA CONTA
 *  View com o formulário de login
 *  php version 7.4.3
 * 
 * @category PHP_SimplifiedFrameworkNoOOP
 * @package  BRASAP_LOGIN
 * @author   Romeu Gomes de Sousa <[email protected]>
 * @license  GNU GPL 3.0 - Livre uso e Distribuição
 * @version  GIT:  
 * @link     https://brasap.com.br
 */
$data = $_SESSION['data'];
?>

<script>
$(function () {
  $('[data-toggle="tooltip"]').tooltip();
});
</script>
<div class="container h-100">
    <div class="d-flex justify-content-center h-100">
        <div class="user_card">
            <div class="d-flex justify-content-center">
                <div class="brand_logo_container">
                    <img src="<?php echo URL; ?>resources/logo/logo-full.png" 
                        class="brand_logo" alt="Logo ServJa">
                </div>
            </div>
            <div class="d-flex justify-content-center form_container">
                <form method="POST" action="<?php echo URL; ?>login/criaconta" onsubmit="spinner.show();">
                    <div class="input-group mb-3" data-toggle="tooltip" 
                        data-placement="bottom" 
                        title="Preencha com seu nome e sobrenome, da maneira que 
                        gostaria de ser chamado ou visualizado em nosso sistema!">
                        <div class="input-group-append">
                            <span class="input-group-text">
                                <i class="far fa-address-card"></i>
                            </span>
                        </div>
                        <input type="email" name="nome" id="nome" 
                        value="<?php echo $data['nome'];?>"
                        class="form-control input_user"
                        placeholder="Nome Completo" required >
                    </div>
                    <div class="input-group mb-3" data-toggle="tooltip" 
                        data-placement="bottom" 
                        title="Preencha com um e-mail válido, e que possa ser 
                        verificado, pois será necessário validar seu email para ter
                        acesso ao nosso sistema.">
                        <div class="input-group-append">
                            <span class="input-group-text">
                                <i class="fas fa-user"></i>
                            </span>
                        </div>
                        <input type="email" name="login" id="login" 
                        class="form-control input_user" 
                        value="<?php echo $data['login'];?>" 
                        placeholder="username (e-mail)" required >
                    </div>
                    <div class="input-group mb-2" data-toggle="tooltip" 
                        data-placement="bottom" 
                        title="Utilize uma senha segura, preferivelmente com letras, 
                        números, simbolos e caracteres especiais.">
                        <div class="input-group-append">
                            <span class="input-group-text">
                                <i class="fas fa-key"></i>
                            </span>
                        </div>
                        <input type="password" name="passw" id="passw" 
                        class="form-control input_pass" 
                        value="<?php echo $data['passw'];?>" 
                        placeholder="password" required>
                    </div>
                    <div class="d-flex justify-content-center mt-3 login_container">
                        <button type="submit" name="button" 
                            class="btn login_btn">Fazer Cadastro
                        </button>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
<?php
unset($data);
unset($_SESSION['data'];
?>

Note, que é um conteúdo muito similar ao da tela de login, tendo somente o campo nome e os tooltips de diferença, e o objetivo aqui é o conteúdo em PHP e não o CSS, o JS (java script) e o HTML em sí, e o atributo “VALUE” dos campos que recebem um conteúdo vindo do nosso control, pelo HTML.

Para finalizar, vamos criar no nosso CONTROL um case responde a chamada de login/cadastro para isso, vamos inserir após o bloco do case 'minhaconta': ...... break; o que se você vem acompanhando as aulas próximo a linha 94, o seguintes códigos:

case 'cadastro':
    // se chamou a tela de CADASTRO, verifica se não está logado e libera
    if ($_SESSION['logado'] != '0') {
        $_SESSION['view']='minhaconta';
        $_SESSION['erro_no'] = ALERT;
        $_SESSION['erro'] = 'Você já está logado no sistema!';
        return;
    } else {
        $data=array(
            'NOME'=>'',
            'LOGIN'=>'',
            'PASSW'=>''
        );
        $_SESSION['title'] = SISTEMA.' - CRIE SUA CONTA';
        $_SESSION['view']='criaconta';
        return;
    }
    break;

Esta parte do control é extremamente simples, e simplesmente, define como vazio os campos que vão aparecer na view, basicamente, estes campos são o Nome do Usuário, o email usado no login e uma senha, que propositalmente não vamos fazer nenhuma pré-checagem, pois vamos usar o PHP para fazer isso, usando algumas funções de manipulação de expressões regulares, fiz novamente da maneira mais simples, poderia ter usado somente 1 chamada, que faria todas as checagens, porém, o objetivo é começar mais básico e depois evoluir até um nível avançado.

Na próxima aula, vamos estudar com exemplos outras muitas funções do PHP que vão auxiliar no desenvolvimento, e a manipulação de dados, arrays, bancos de dados, e outras ferramentas importantes para o desenvolvimento de sistemas baseados em internet.