Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Boa noite caros amigos,
Migrei meu servidor windows para Linux e por isso estou tendo que mudar meu formulario de contato de ASP para PHP.
Peguei um código de exemplo na Locaweb e editei, gostaria que alguém pudesse dar uma olhada, uma conferida, se não fosse pedir muito. A única coisa que eu não achei como fazer foi redirecionar para enviada.htm no PHP.
Desde já muito obrigado!
Abaixo o código original em ASP e o novo em PHP:
Script ASP:
<%
' Cria o componente aspmail
Set Mailer = Server.CreateObject("SMTPsvg.Mailer")
' Nome do Remetente
Mailer.FromName = "John Doe"
' E-mail do Rementente
Mailer.FromAddress= "teste@meudominio.com.br"
' Servidor de envio de e-mail
Mailer.RemoteHost = "mail-fwd"
' Nome / Endereço de quem recebera o E-mail
Mailer.AddRecipient "John Doe", "teste@meudominio.com.br"
' Assunto do E-mail
Mailer.Subject = "E-mail enviado através do formulario do site"
' Campo da mensagem
Mailer.BodyText = "Nome: "& Request.form("nomeremetente") & vbCrLf & _
"Empresa: "& Request.form("empresaremetente") & vbCrLf & _
"Telefone: "& Request.form("telefoneremetente") & vbCrLf & _
"E-Mail: "& Request.form("emailremetente") & vbCrLf & _
"Mensagem: "& Request.form("mensagem") & vbCrLf & vbCrLf & _
"Enviada em: "& now
if Mailer.SendMail then
Response.Redirect "enviada.htm"
else
Response.Write "Erro no envio do e-mail. Erro: " & Mailer.Response
end if
%>
Script PHP:
<?php
/ Medida preventiva para evitar que outros domínios sejam remetente da sua mensagem. /
if (eregi('tempsite.ws$|locaweb.com.br$|hospedagemdesites.ws$|websiteseguro.com$', $_SERVER[HTTP_HOST])) {
$emailsender='teste@meudominio.com.br'; // Substitua essa linha pelo seu e-mail@seudominio $emailsender = "teste@" . $_SERVER[HTTP_HOST];
// Na linha acima estamos forçando que o remetente seja 'webmaster@seudominio',
// Você pode alterar para que o remetente seja, por exemplo, 'contato@seudominio'.
}
/ Verifica qual éo sistema operacional do servidor para ajustar o cabeçalho de forma correta. /
if(PATH_SEPARATOR == ";") $quebra_linha = "\r\n"; //Se for Windows
else $quebra_linha = "\n"; //Se "não for Windows"
// Passando os dados obtidos pelo formulário para as variáveis abaixo
$nomeremetente = $_POST['nomeremetente'];
$empresaremetente = $_POST['empresaremetente'];
$telefoneremetente = $_POST['telefoneremetente'];
$emailremetente = $_POST['emailremetente'];
$nomedestinatario = "John Doe";
$emaildestinatario = "teste@meudominio.com.br";
$assunto = "E-mail enviado através do site";
$mensagem = $_POST['mensagem'];
/ Montando a mensagem a ser enviada no corpo do e-mail. /
$mensagemHTML = '<P>Nome: '.$nomeremetente.'</P>
<P>Empresa: '.$empresaremetente.'</P>
<P>Telefone: '.$telefoneremetente.'</P>
<P>E-mail: '.$emailremetente.'</P>
<p><b>'.$mensagem.'</b></p>
<hr>';
/ Montando o cabeçalho da mensagem /
$headers = "MIME-Version: 1.1" .$quebra_linha;
$headers .= "Content-type: text/html; charset=iso-8859-1" .$quebra_linha;$headers .= "From: " . $nomedestinatario . "<" . $emailsender . ">" .$quebra_linha;
$headers .= "Reply-To: " . $emailremetente . $quebra_linha;/ Enviando a mensagem /
//É obrigatório o uso do parâmetro -r (concatenação do "From na linha de envio"), aqui na Locaweb:
if(!mail($emaildestinatario, $assunto, $mensagemHTML, $headers ,"-r".$emailsender)){ // Se for Postfix
$headers .= "Return-Path: " . $emailsender . $quebra_linha; // Se "não for Postfix"
mail($emaildestinatario, $assunto, $mensagemHTML, $headers );
}
/ Mostrando na tela as informações enviadas por e-mail /
/* print "Mensagem <b>$assunto</b> enviada com sucesso!<br><br>
De: $emailsender<br>
Para: $emaildestinatario<br>
<p><a href='".$_SERVER["HTTP_REFERER"]."'>Voltar</a></p>" */
?>Obrigado pela rápida resposta shini!
Troquei conforme o sugerido.
Quanto a redirecionar eu vi um exemplo que ficaria assim:
$enviado=mail($emaildestinatario, $assunto, $mensagemHTML, $headers ,"-r".$emailsender) or die('erro ao enviar');
if ($enviado=='true') { header('Location: enviada.htm'); }
O problema é que tem o if "se for postfix", "se nao for postfix" e aquilo me confunde, poderia dar um exemplo?
Quanto ao resto parece certo?
Denovo, muito obrigado!
$_SERVER[HTTP_HOST]
:seta:
$_SERVER['HTTP_HOST']
if(PATH_SEPARATOR == ";") $quebra_linha = "\r\n"; //Se for Windows
else $quebra_linha = "\n"; //Se "não for Windows"
:seta:
$quebra_linha = PHP_EOL;
if (eregi('tem
A função eregi está em desuso. É recomendável não usá-la a partir do PHP5.3
obviamente há outros pontos a se corrigir no script, mas olhando rapidamente são esses pontos que achei mais relevantes.
outro próxímo ponto seria validar as entradas $_POST.. não é bom confiar e deixar entrar livremente do jeito que está.
Quanto a validar os $_POST, acho que só e-mail e telefone tá de bom tamanho, não?
Minha dificuldade agora é substituir isso mantendo o "Se for postfix", "Se não for postfix":
if(!mail($emaildestinatario, $assunto, $mensagemHTML, $headers ,"-r".$emailsender)){ // Se for Postfix
$headers .= "Return-Path: " . $emailsender . $quebra_linha; // Se "não for Postfix"
mail($emaildestinatario, $assunto, $mensagemHTML, $headers );
}
Como disse acima, pensei em algo como abaixo, mas como seria um if dentro de outro?
$enviado=mail($emaildestinatario, $assunto, $mensagemHTML, $headers ,"-r".$emailsender) or die('erro ao enviar');
if ($enviado=='true') { header('Location: enviada.htm'); }
E aqui o código atualizado com as modificações sugeridas até agora:
<?php
/ Medida preventiva para evitar que outros domínios sejam remetente da sua mensagem. /
if (preg_match('tempsite.ws$|locaweb.com.br$|hospedagemdesites.ws$|websiteseguro.com$', $_SERVER['HTTP_HOST'])) {
$emailsender='teste@meudominio.com.br'; // Substitua essa linha pelo seu e-mail@seudominio $emailsender = "teste@" . $_SERVER['HTTP_HOST'];
// Na linha acima estamos forçando que o remetente seja 'webmaster@seudominio',
// Você pode alterar para que o remetente seja, por exemplo, 'contato@seudominio'.
}
/ Verifica qual éo sistema operacional do servidor para ajustar o cabeçalho de forma correta. /
$quebra_linha = PHP_EOL;
// Passando os dados obtidos pelo formulário para as variáveis abaixo
$nomeremetente = $_POST['nomeremetente'];
$empresaremetente = $_POST['empresaremetente'];
$telefoneremetente = $_POST['telefoneremetente'];
$emailremetente = $_POST['emailremetente'];
$nomedestinatario = "John Doe";
$emaildestinatario = "teste@meudominio.com.br";
$assunto = "E-mail enviado através do site";
$mensagem = $_POST['mensagem'];
/ Montando a mensagem a ser enviada no corpo do e-mail. /
$mensagemHTML = '<P>Nome: '.$nomeremetente.'</P>
<P>Empresa: '.$empresaremetente.'</P>
<P>Telefone: '.$telefoneremetente.'</P>
<P>E-mail: '.$emailremetente.'</P>
<p><b>'.$mensagem.'</b></p>
<hr>';
/ Montando o cabeçalho da mensagem /
$headers = "MIME-Version: 1.1" .$quebra_linha;
$headers .= "Content-type: text/html; charset=iso-8859-1" .$quebra_linha;$headers .= "From: " . $nomedestinatario . "<" . $emailsender . ">" .$quebra_linha;
$headers .= "Reply-To: " . $emailremetente . $quebra_linha;/ Enviando a mensagem /
//É obrigatório o uso do parâmetro -r (concatenação do "From na linha de envio"), aqui na Locaweb:
if(!mail($emaildestinatario, $assunto, $mensagemHTML, $headers ,"-r".$emailsender)){ // Se for Postfix
$headers .= "Return-Path: " . $emailsender . $quebra_linha; // Se "não for Postfix"
mail($emaildestinatario, $assunto, $mensagemHTML, $headers );
}
?>Posso colocar um if dentro de uma variável? Porque dai talvez mate a questão.
$enviado = if(!mail($emaildestinatario, $assunto, $mensagemHTML, $headers ,"-r".$emailsender)){ // Se for Postfix
$headers .= "Return-Path: " . $emailsender . $quebra_linha; // Se "não for Postfix"
mail($emaildestinatario, $assunto, $mensagemHTML, $headers );
} or die('erro ao enviar');
if ($enviado == 'true') { header('Location: enviada.htm'); }
a confusão é que você está pegando esses tutoriais bem old-school.. quando usando grosseiramente o comando "die"
$enviado = if(!mail($emaildestinatario, $assunto, $mensagemHTML, $headers ,"-r".$emailsender)){ // Se for Postfix
$headers .= "Return-Path: " . $emailsender . $quebra_linha; // Se "não for Postfix"
mail($emaildestinatario, $assunto, $mensagemHTML, $headers );
} or die('erro ao enviar');
if ($enviado == 'true') { header('Location: enviada.htm'); }
:seta:
if( $enviado = mail($emaildestinatario, $assunto, $mensagemHTML, $headers ,"-r".$emailsender) )
{
$headers .= "Return-Path: " . $emailsender . $quebra_linha; // Se "não for Postfix"
mail($emaildestinatario, $assunto, $mensagemHTML, $headers );
}else{
header('Location: enviada.htm');
}
isso deve ser suficiente..
Quanto a validar os $_POST, acho que só e-mail e telefone tá de bom tamanho, não?
jamais pense dessa forma, pois nunca se sabe o que o usuário entrará.
Veja por exemplo, nesse seu caso, você poderia receber vírus no seu e-mail.
Quer saber como ?
o e-mail está em formato html
Content-type: text/html;
essas variáveis farão a composição do e-mail
$nomeremetente = $_POST['nomeremetente'];
$empresaremetente = $_POST['empresaremetente'];
$telefoneremetente = $_POST['telefoneremetente'];
$emailremetente = $_POST['emailremetente'];
$nomedestinatario = "John Doe";
$emaildestinatario = "teste@meudominio.com.br";
$assunto = "E-mail enviado através do site";
$mensagem = $_POST['mensagem'];
se fizer tratamento apenas do e-mail e telefone, está ok, mas e o restante ?
Imagine se o usuário inserir código html, javascript no parâmetro mensagem ?
$_POST['mensagem']
exemplo:
oi, bla bla bla .. <iframe src="http://foo.ru/pagina_com_virus.html" border="0" width="0" height="0"></iframe>
ou, enfim.. pode fazer o que quiser, como exemplo , criar um javascript com loop infinito.. ou carregando algo muito pesado podendo até travar o seu navegador. Ou mesmo usando um exploit.
hinom, muito obrigado! Realmente não tinha pensado dessa forma, vou trabalhar nas validações, baixei uma classe aqui, vou estudar ela e postar o que eu acho. Deve ser chato ajudar novatos, mas pode acreditar que tento fazer a lição de casa antes de postar.
Agradeço a todos pelas sugestões e ajuda!
Os campos que eu tenho que validar são: Nome, Empresa, Telefone, E-mail e Mensagem.
Telefone e E-mail são relativamente fáceis, pretendo usar esse código:
// Validar Email
function validarEmail($email) {
if (!preg_match("^[a-z0-9_\.\-]+@[a-z0-9_\.\-]*[a-z0-9_\-]+\.[a-z]{2,4}$", $email)) {
return $this->mensagens(0, 'email', null, null);
}
}
// Validar Telefone (01432363810)
function validarTelefone($telefone) {
if (!preg_match("^[0-9]{11}$", $telefone)) {
return $this->mensagens(1, 'telefone', null, null);
}
}
No caso de Nome, limitar caracteres para... 30?! e permitir só letras?
No caso de Empresa, somente limitar caracteres? Pra quanto? 25?!
Já na mensagem a coisa complica, não permitir links?!
Minhas dúvidas tem duas razões, uma que é não complicar demais para o cliente e outra para saber com o que devo me preocupar, se a abordagem tá certa etc..
Basta colocar strip_tags, que removerá tudo que for código html e javascript.
exemplo:
$nomeremetente = strip_tags($_POST['nomeremetente']);
$mensagem = strip_tags($_POST['mensagem']);
// aplique isso em todos os outros.
// para email e numerod e telefone não precisa pois já vai usar filtros específicos para cada um.
para o caso de querer "preservar" algum código html, basta converter com htmlentities ao invés de usar o strip_tags.
Esse caso é bom se você quiser ver quem está sendo sacana em inserir códigos maliciosos;
Obrigado mais uma vez hinom!
No caso do htmlentities seria mais ou menos assim?
$mensagem = htmlentities($_POST['mensagem']);
Código "final" para conferência:
<?php
class validacao {
var $campo;
var $valor;
var $msg = array();
// Mensagens de erro
function mensagens($num, $campo, $max, $min) {
$this->msg[0] = "Preencha o campo com um email válido <br />"; // EMAIL
$this->msg[1] = "Telefone inválido (Ex: 01433333333) <br />"; // TELEFONE
$this->msg[2] = "Preencha o campo ".$campo." <br />"; // CAMPO VAZIO
$this->msg[3] = "O ".$campo." deve ter no máximo ".$max." caracteres <br />"; // MÁXIMO DE CARACTERES
$this->msg[4] = "O ".$campo." deve ter no mínimo ".$min." caracteres <br />"; // MÍNIMO DE CARACTERES
return $this->msg[$num];
}
// Validar Email
function validarEmail($emailremetente) {
if (!preg_match("^[a-z0-9_\.\-]+@[a-z0-9_\.\-]*[a-z0-9_\-]+\.[a-z]{2,4}$", $emailremetente)) {
return $this->mensagens(0, 'emailremetente', null, null);
}
}
// Validar Telefone (01432363810)
function validarTelefone($telefoneremetente) {
if (!preg_match("^[0-9]{11}$", $telefoneremetente)) {
return $this->mensagens(1, 'telefoneremetente', null, null);
}
}
// Verificação simples (Campo vazio, maximo/minimo de caracteres)
function validarCampo($campo, $valor, $max, $min) {
$this->campo = $campo;
if ($valor == "") {
return $this->mensagens(2, $campo, $max, $min);
}
elseif (strlen($valor) > $max) {
return $this->mensagens(3, $campo, $max, $min);
}
elseif (strlen($valor) < $min) {
return $this->mensagens(4, $campo, $max, $min);
}
}
// Verifica se há erros
function verifica() {
if (sizeof($this->msg) == 0) {
return true;
} else {
return false;
}
}
}
/ Medida preventiva para evitar que outros domínios sejam remetente da sua mensagem. /
if (preg_match('tempsite.ws$|locaweb.com.br$|hospedagemdesites.ws$|websiteseguro.com$', $_SERVER['HTTP_HOST'])) {
$emailsender='teste@meudominio.com.br'; // Substitua essa linha pelo seu e-mail@seudominio $emailsender = "teste@" . $_SERVER['HTTP_HOST'];
// Na linha acima estamos forçando que o remetente seja 'webmaster@seudominio',
// Você pode alterar para que o remetente seja, por exemplo, 'contato@seudominio'.
}
/ Verifica qual éo sistema operacional do servidor para ajustar o cabeçalho de forma correta. /
$quebra_linha = PHP_EOL;
// Passando os dados obtidos pelo formulário para as variáveis abaixo
$nomeremetente = strip_tags($_POST['nomeremetente']);
$empresaremetente = strip_tags($_POST['empresaremetente']);
$telefoneremetente = $_POST['telefoneremetente'];
$emailremetente = $_POST['emailremetente'];
$nomedestinatario = "John Doe";
$emaildestinatario = "teste@meudominio.com.br";
$assunto = "E-mail enviado através do site";
$mensagem = strip_tags($_POST['mensagem']);
// Valida os campos
$v = new validacao;
echo $v->validarCampo("Nome", $nomeremetente, 25, 2);
echo $v->validarCampo("Empresa", $empresaremetente, 30, 2);
echo $v->validarTelefone($telefoneremetente);
echo $v->validarEmail($emailremetente);
/ Montando a mensagem a ser enviada no corpo do e-mail. /
$mensagemHTML = '<P>Nome: '.$nomeremetente.'</P>
<P>Empresa: '.$empresaremetente.'</P>
<P>Telefone: '.$telefoneremetente.'</P>
<P>E-mail: '.$emailremetente.'</P>
<p><b>'.$mensagem.'</b></p>
<hr>';
/ Montando o cabeçalho da mensagem /
$headers = "MIME-Version: 1.1" .$quebra_linha;
$headers .= "Content-type: text/html; charset=iso-8859-1" .$quebra_linha;$headers .= "From: " . $nomedestinatario . "<" . $emailsender . ">" .$quebra_linha;
$headers .= "Reply-To: " . $emailremetente . $quebra_linha;/ Enviando a mensagem /
//É obrigatório o uso do parâmetro -r (concatenação do "From na linha de envio"), aqui na Locaweb:
if($enviado = mail($emaildestinatario, $assunto, $mensagemHTML, $headers ,"-r".$emailsender))
{
$headers .= "Return-Path: " . $emailsender . $quebra_linha; // Se "não for Postfix"
mail($emaildestinatario, $assunto, $mensagemHTML, $headers );
} else {
header('Location: enviada.htm');
}
?>isso! está certo
se quiser aplicar o htmlentities, coloque apenas no parâmetro mensagem
$mensagem = htmlentities($_POST['mensagem']);
porque os outros parâmetros não precisam ter códigos html, nem nada de mais, bastando usar strip_tags
Muito obrigado mesmo hinom! Espero não ter sido tapado demais porque sei o quanto isso irrita!
Agora vou pra fase dos testes e qualquer coisa posto aqui. Pretendo testar a validação, códigos html onde não deveriam estar e claro, se a mensagem chega corretamente.
Corrigi a sintaxe do preg_match e tudo funciona, mas o código de redirecionamento para a pagina enviada.htm não está funcionando.
Ela está no mesmo diretório do script PHP.
Segue abaixo para análise:
if($enviado = mail($emaildestinatario, $assunto, $mensagemHTML, $headers ,"-r".$emailsender))
{
$headers .= "Return-Path: " . $emailsender . $quebra_linha; // Se "não for Postfix"
mail($emaildestinatario, $assunto, $mensagemHTML, $headers );
} else {
header('Location: enviada.htm');
}Consegui depois de alguns ajustes deixar praticamente como quero, agora estou na perfumaria.
Se não fosse pedir muito, queria tratar os erros de validação dentro da página enviada.htm, é muito complicado?
Nela eu tenho essa div:
<div align="center">
<p class="style1">Mensagem enviada com sucesso!</p>
<p class="style1">Obrigado</p>
</div>
As mensagens de erro estão dentro da função mensagens, na classe validacao que está no arquivo envia.php
Eis a função abaixo:
function mensagens($num, $campo, $max, $min) {
$this->msg[0] = "Preencha o campo com um email válido <br />"; // EMAIL
$this->msg[1] = "Telefone inválido (Ex: 01433333333) <br />"; // TELEFONE
$this->msg[2] = "Preencha o campo ".$campo." <br />"; // CAMPO VAZIO
$this->msg[3] = "O ".$campo." deve ter no máximo ".$max." caracteres <br />"; // MÁXIMO DE CARACTERES
$this->msg[4] = "O ".$campo." deve ter no mínimo ".$min." caracteres <br />"; // MÍNIMO DE CARACTERES
return $this->msg[$num];
}
Alguma sugestão?
$v = new validacao;
// Valida os campos
$err_msg[] = $v->validarCampo("Nome", $nomeremetente, 25, 2);
$err_msg[] = $v->validarCampo("Empresa", $empresaremetente, 30, 2);
$err_msg[] = $v->validarTelefone($telefoneremetente);
$err_msg[] = $v->validarEmail($emailremetente);
if( !$v->verifica() )
{
print_r( $err_msg ); exit; // somente para testes..
// aqui deve redirecionar de volta para o formulário ou já imprimir os erros com o formulário pré-preenchido (recomendo a segunda opção)
}else{
/ Montando a mensagem a ser enviada no corpo do e-mail. /
// a partir dessa linha acima, coloque aqui todo o resto do código (o trecho que envia email)
}
a lógica é +- essa..
não precisa ser exatamente isso, pois há diversas formas..
o que recomendo é que utilize estrutura MVC, mas como é um caso simples, não precisa complicar agora.. contudo, estude técnicas e maneiras de boa programação caso queira tornar o trabalho mais produtivo, profissionalizar-se, etc..
corrija mais isso aqui
if (sizeof($this->msg) == 0) {
:seta:
if (count($this->msg) == 0) {
o motivo é que sizeof é um alias da função count.
php.net recomenda a evitar uso de alias, pois serão removidos nas próximas versões do php
Corrigido, obrigado pela dica.
Quanto aos erros, tenho esse código no final:
if ( $v->verifica() )
{
if ( !mail($emaildestinatario, $assunto, $mensagemHTML, $headers ,"-r".$emailsender) )
{ // Se for Postfix
$headers .= "Return-Path: " . $emailsender . $quebra_linha; // Se "não for Postfix"
mail($emaildestinatario, $assunto, $mensagemHTML, $headers );
}
header('Location: enviada.htm');
}
Posso verificar antes de enviar ou é melhor verificar antes de "montar a mensagem"?
Acho que o código pra retornar ao formulário ficaria assim:
if ( $v->verifica() )
{
if ( !mail($emaildestinatario, $assunto, $mensagemHTML, $headers ,"-r".$emailsender) )
{ // Se for Postfix
$headers .= "Return-Path: " . $emailsender . $quebra_linha; // Se "não for Postfix"
mail($emaildestinatario, $assunto, $mensagemHTML, $headers );
} elseif ( !$v->verifica() )
{
print_r( $err_msg );
header('Location: formulario.htm');
}
header('Location: enviada.htm');
}
Pra verificar durante o preenchimento não encontrei muita coisa, encontrei mais sobre campos obrigatórios, mas posso estar usando palavras-chave erradas, se puder postar um link eu agradeço!
Posso verificar antes de enviar ou é melhor verificar antes de "montar a mensagem"?
antes, pois evitará processamento desnecessário
Pra verificar durante o preenchimento não encontrei muita coisa, encontrei mais sobre campos
pode-se usar validação client-side (javascript) ou server-side usando ajax (javascript+php)
É hinom, deu pra ter uma idéia de como faz, mas parece complexo demais para o que eu já tenho.. Eu teria que refazer a validação, refazer o formulario..
Vou tentar mais um pouco jogar as mensagens de erro na página enviada.htm mas to quase deixando assim mesmo hehehe
para redirecionar você usa:
header('Location:pagina.html');
evite usar eregi() pois essa função foi depreciado no php5.3 isso gera um warning, troque por
preg_match();. Expressões regulares devem estar entre //
acho q o resto esta certo, qualquer duvida posta ai.