Mais Tráfego
Desenvolvimento => Desenvolvimento => PHP => Tópico iniciado por: muiomuio em 24/Mai/2012 13:04
-
Boas,
Estou a tratar de um formulário simples de envio de email em PHP.
Ocasionalmente ocorre o seguinte erro:
Warning: mail() [function.mail </pt/function.mail> ]:
SMTP server response: 550 5.7.1 Unable to relay for <email removido>
in\\nas41ent\Domains\l\cliente\user\htdocs\common\send-mail.php
<smb://nas41ent/Domains/l/cliente/user/htdocs/common/send-mail.php> on
line71
Nota: <email removido> e /Domains/l/cliente/user fui eu que alterei por motivos de confidencialidade.
Aqui está o código do send-mail.php
function send_mail($to, $body, $subject, $fromaddress, $fromname, $attachments=false)
{
$eol="\r\n";
$mime_boundary=md5(time());
# Common Headers
$headers = "From: ".$fromname." <".$fromaddress.">".$eol;
$headers .= "Reply-To: ".$fromname." <".$fromaddress.">".$eol;
$headers .= "Return-Path: ".$fromname." <".$fromaddress.">".$eol; // these two to set reply address
$headers .= "Message-ID: <".time()."-".$fromaddress.">".$eol;
$headers .= "X-Mailer: PHP v".phpversion().$eol; // These two to help avoid spam-filters
# Boundry for marking the split & Multitype Headers
$headers .= 'MIME-Version: 1.0'.$eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"".$mime_boundary."\"".$eol.$eol;
# Open the first part of the mail
$msg = "--".$mime_boundary.$eol;
$htmlalt_mime_boundary = $mime_boundary."_htmlalt"; //we must define a different MIME boundary for this section
# Setup for text OR html -
$msg .= "Content-Type: multipart/alternative; boundary=\"".$htmlalt_mime_boundary."\"".$eol.$eol;
# Text Version
$msg .= "--".$htmlalt_mime_boundary.$eol;
$msg .= "Content-Type: text/plain; charset=iso-8859-1".$eol;
$msg .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
$msg .= strip_tags(str_replace("<br>", "\n", substr($body, (strpos($body, "<body>")+6)))).$eol.$eol;
# HTML Version
$msg .= "--".$htmlalt_mime_boundary.$eol;
$msg .= "Content-Type: text/html; charset=iso-8859-1".$eol;
$msg .= "Content-Transfer-Encoding: 8bit".$eol.$eol;
$msg .= $body.$eol.$eol;
//close the html/plain text alternate portion
$msg .= "--".$htmlalt_mime_boundary."--".$eol.$eol;
if ($attachments !== false)
{
for($i=0; $i < count($attachments); $i++)
{
if (is_file($attachments[$i]["file"]))
{
# File for Attachment
$file_name = substr($attachments[$i]["file"], (strrpos($attachments[$i]["file"], "/")+1));
$handle=fopen($attachments[$i]["file"], 'rb');
$f_contents=fread($handle, filesize($attachments[$i]["file"]));
$f_contents=chunk_split(base64_encode($f_contents)); //Encode The Data For Transition using base64_encode();
$f_type=filetype($attachments[$i]["file"]);
fclose($handle);
# Attachment
$msg .= "--".$mime_boundary.$eol;
$msg .= "Content-Type: ".$attachments[$i]["content_type"]."; name=\"".$file_name."\"".$eol; // sometimes i have to send MS Word, use 'msword' instead of 'pdf'
$msg .= "Content-Transfer-Encoding: base64".$eol;
$msg .= "Content-Description: ".$file_name.$eol;
$msg .= "Content-Disposition: attachment; filename=\"".$file_name."\"".$eol.$eol; // !! This line needs TWO end of lines !! IMPORTANT !!
$msg .= $f_contents.$eol.$eol;
}
}
}
# Finished
$msg .= "--".$mime_boundary."--".$eol.$eol; // finish with two eol's for better security. see Injection.
# SEND THE EMAIL
ini_set("sendmail_from",$fromaddress); // the INI lines are to force the From Address to be used !
$mail_sent = mail($to, $subject, $msg, $headers);
ini_restore("sendmail_from");
return $mail_sent;
}
No formulário estou a passar os seguintes paramentos:
ini_set('sendmail_from',$senderEmail); // the INI lines are to force the From Address to be used !
ini_restore('sendmail_from');
send_mail($dest,$contents,"Mensagem Online (PT)",$senderEmail,$senderName);
As variáveis têm todas valores. O erro não ocorre sempre mas provavelmente em 50% das vezes. Já pesquisei no Google mas não consigo intender o motivo concreto disto, talvez pela minha falta de experiência em programação.
As minhas dúvidas são simples:
- O que está a causar isto?
- Como posso resolver esta questão sem ter de autenticar via SMTP?
Agradeço ajuda.
Mário
-
Estás a enviar os emails através do teu PC ?
-
Não, é através de outro servidor online.
-
Eu uso o Swiftmailer para enviar emails "simples" e em massa também.
Mas no teu código não deverias de ter isto
ini_set('SMTP', 'mail.o-teu-dominio.com');
-
Quando coloco isso, com a alteração para o servidor de email do domínio dá outro erro:
Warning: mail() [function.mail]: SMTP server response: 504 <envisage253>: Helo command rejected: need fully-qualified hostname in \\nas41ent\Domains\l\cliente\user\htdocs\common\send-mail.php on line 72
-
Pois isso acontece porque tens de te autenticar no servidor de email.
Eu prefiro enviar emails por SMTP, mas como disseste que não "pretendes"... o que te posso aconselhar é usar uma class de envio de emails.
O swiftmailer por exemplo podes enviar emails sem ser por SMTP, através do sendmail do php, e pode ser que resolva esse problema..
-
Bom decidi tentar o SwiftMailer no entanto ainda sem sucesso.
Este é o código que utilizo para utilizar o SwiftMailer:
$transport = Swift_SmtpTransport::newInstance('localhost', 25);
$mailer = Swift_Mailer::newInstance($transport);
$message = Swift_Message::newInstance()
->setSubject('Contacto via site (PT)')
->setFrom(array($senderEmail => $senderName))
->setTo(array('umemail@dominio.com' => 'Mario Andrade'))
->setBody($contents)
->setReplyto($senderEmail)
->setContentType('text/html')
;
if($mailer->send($message, $failures)) {
echo "O email foi enviado com sucesso. " . date("H:i:s");
} else {
echo "Ocorreu um erro. O seu email não foi enviado. Tente novamente. \n";
print_r($failures);
}
Nesta situação não ocorrem erros. Aparece a mensagem a dizer "O email foi enviado com sucesso". No entanto com testes efectuados há praticamente 12h atrás ainda não recebi os emails.
Quando troco localhost pelo endereço do mail server fornecido pela empresa de hosting ocorre um erro. Os MX records dizem que a porta 25 é a porta correcta.
Any suggestions?
-
Já agora, outra situação curiosa.
Tenho 2 contas de Gmail que estou a utilizar para fazer testes. Uma das contas recebe emails através de redireccionamento da outra.
Os emails estão a ir para o SPAM da conta que recebe os redireccionamentos mas não para a conta para onde é enviado o email.
-
Mas queres enviar por SMTP, pelo sendmail ou pelo mail() do PHP?
É que é diferente.
Um pouco de código de um class que fiz para me auxiliar no envio de emails para um CMS que desenvolvi
// Smtp protocol ?
//
if ( $protocol == 'smtp' ):
// Initiate the Swift Smtp Transport.
//
$SwiftTransport = Swift_SmtpTransport::newInstance($smtp_host, $smtp_port)->setUsername($smtp_user)->setPassword($smtp_pass);
// Sendmail protocol ?
//
elseif( $protocol == 'sendmail' ):
// Initiate the Swift Sendmail Transport.
//
$SwiftTransport = Swift_SendmailTransport::newInstance('/usr/sbin/sendmail -bs');
// PHP mail()
//
else:
// Initiate the Swift Mail Transport.
//
$SwiftTransport = Swift_MailTransport::newInstance();
endif;
// Initiate the Swift Mailer.
//
$this->SwiftMailer = Swift_Mailer::newInstance($SwiftTransport);
No teu código estas a tentar enviar por SMTP
$transport = Swift_SmtpTransport::newInstance('localhost', 25);
Talvez assim:
$transport = Swift_MailTransport::newInstance();
Eu como prefiro usar SMTP sei que o meu código funciona bem, por acaso nunca experimentei com outro "protocolo".
Edit:
Os emails irem para a pasta SPAM, isso já me aconteceu, algumas vezes era dos headers que enviava, outras do próprio assunto do email, pois sei que no hotmail não ia para o spam mas no gmail ia...
-
Eu tentei utilizar o método para enviar por sendmail e por mail mas esses davam-me sempre erro.
No caso do MailTransport mostrava:
Array ( [0] => omeuemail@gmail.com )
No caso do Sendmailtransport
Notice: Undefined variable: pipes in \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\StreamBuffer.php on line 296
Warning: proc_open() has been disabled for security reasons in \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\StreamBuffer.php on line 296
Notice: Undefined variable: pipes in \\nas41ent\Domains\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\StreamBuffer.php on line 297
Warning: stream_set_blocking(): supplied argument is not a valid stream resource in \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\StreamBuffer.php on line 297
Notice: Undefined variable: pipes in \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\StreamBuffer.php on line 298
Warning: stream_get_contents() expects parameter 1 to be resource, null given in \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\StreamBuffer.php on line 298
Fatal error: Uncaught exception 'Swift_TransportException' with message 'Expected response code 220 but got code "", with message ""' in \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\AbstractSmtpTransport.php:422 Stack trace: #0 \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\AbstractSmtpTransport.php(315): Swift_Transport_AbstractSmtpTransport->_assertResponseCode('', Array) #1 \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\AbstractSmtpTransport.php(123): Swift_Transport_AbstractSmtpTransport->_readGreeting() #2 \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\SendmailTransport.php(57): Swift_Transport_AbstractSmtpTransport->start() #3 \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Mailer.php(79): Swift_Transport_SendmailTransport->start() #4 \\nas41ent\Domains\l\cliente\user\htdocs\pt\inc\contact.inc. in \\nas41ent\Domains\l\cliente\user\htdocs\common\Swift-4.1.7\lib\classes\Swift\Transport\AbstractSmtpTransport.php on line 422
-
Alguém já passou pelo mesmo problema? Como posso resolver isto?
Já solicitei um user e password ao cliente mas até ele me enviar o formulário não vai funcionar correctamente.
-
Alguém já passou pelo mesmo problema? Como posso resolver isto?
Já solicitei um user e password ao cliente mas até ele me enviar o formulário não vai funcionar correctamente.
Desculpa, não tinha reparado que tinhas respondido..
Eu mais logo vou fazer uns tens a enviar email sem ser por smtp e já te digo algo..
-
O SwiftMailer é um componente, acaba sempre por enviar por smtp o email (nem é possível enviar emails de outra forma).
O servidor não permite relay(o que é normal), portanto ou usas autenticação, ou te permitem relay através do ip.
-
O SwiftMailer é um componente, acaba sempre por enviar por smtp o email (nem é possível enviar emails de outra forma).
Não, ao usar o Swift_MailTransport ele usa a função mail(), não sendo necessário nenhum servidor SMTP, não é tão viável como o SMTP, dai eu ter dito que é preferível usar SMTP, sempre.
-
Não, ao usar o Swift_MailTransport ele usa a função mail(), não sendo necessário nenhum servidor SMTP, não é tão viável como o SMTP, dai eu ter dito que é preferível usar SMTP, sempre.
E a função mail() não usa o SMTP server? Então como é que envia o email?
-
por magia :)
-
E a função mail() não usa o SMTP server? Então como é que envia o email?
Sim usa SMTP, mas usa o servidor que está no PHP.ini e sendo assim não precisas de ser tu a definir um, era isso que eu queria dizer, mas pelos vistos não me consegui explicar bem, whatever...
Agora se o servidor onde o site/script, está instalado não estiver configurado correctamente os emails não são enviados.
Em windows até bastava ( não sei se ainda funciona ) ter localhost como SMTP que os emails geralmente eram enviados.
O problema aqui é que ele não quer definir nenhum servidor SMTP, e sim usar o "default", mas pelos vistos não está a ter sucesso..
Mas um aparte, já que percebes tanto do assunto, e que percebes dessas linguagens todas de programação, és um "webmaster", podes sempre dar umas ajudas.. não sei digo eu..
por magia :)
Também é possível..