Tenho visto que muitos webmasters tem tido dificuldades para enviar algum informativo (newsletter) devido ao limite de envio de emails imposto por alguns hosts, normalmente o limite fica entre 100 e 400 emails por hora.
Este problema acaba gerando um grande desconforto, pois, imagine você que nosso site possua 1000 assinantes se você tivesse que enviar tudo isso manualmente (existe essa possibilidade?) iria demorar várias horas se não dias.
Os hosts que possuem este limite fazem isso justamente para evitar envio de emails em massa comumente conhecido como SPAM, que nada mais é do que envio de email não solicitado. Apesar do limite imposto alguns usuários talvez até sem saber acabam enviando emails acima do limite, então os emails que ultrapassam o limite são barrados, algumas empresas devolvem o email ao remetente outras apenas cancelam o envio e notificam o remetente. Algumas vezes os administradores do host chegam a decisões extremas como cancelamento da conta de hospedagem quando o envio é continuo.
Pois bem, pensando numa solução para o problema criei um pequeno e simples script em PHP/MySQL que se encarrega de enviar os emails dentro do limite imposto pelo host (ou servidor).
Antes de tudo gostaria de destacar que este material foi criado com intuito de resolver o problema, sendo assim estou me baseando na idéia de que você tenha no mínimo conhecimentos básicos em PHP e MySQL.
Primeiramente crie esta tabela em seu banco MySQL para que você possa utilizar o script.
CREATE TABLE newsletter (
id INT(4) NOT NULL AUTO_INCREMENT,
nome VARCHAR(60) NOT NULL,
email VARCHAR(120) NOT NULL,
codStatus INT(1) NOT NULL DEFAULT 0,
PRIMARY KEY(id)
);
Esta tabela possui quatro campos (id, nome, email e codStatus) estes campos são responsáveis pelo armazenamento e organização dos dados contidos na tabela, a organização consiste em:
- ID
Este campo serve apenas para identificar cada registro como único.
- NOME
Este campo é responsável por armazenar o nome de nosso assinante.
- EMAIL
Este campo é responsável por armazenar o endereço eletrônico (email) de nosso assinante.
- CODSTATUS
Este campo possui papel importante no envio, através dele é que o script identificará pra quem já foi enviado a newsletter. Isso é possível devido ao tipo de campo inteiro tamanho 1, sendo que o valor 0 representa emails que ainda não foram enviados e 1 representa a emails que já foram enviados.
Bom, eu criei a estrutura da tabela, mas, não irei disponibilizar os registros para que a tabela seja populada, sendo assim, você terá que criar ai seus próprios registros.
Tendo nossa tabela criada vamos então (finalmente) ver o tal script.
// DADOS DE ACESSO AO BANCO MYSQL
$host = "HOST";
$banco = "BANCO";
$usuario = "USUARIO";
$senha = "SENHA";
Adicionamos aqui os dados necessários para a conexão com nosso servidor MySQL não há nada extraordinário aqui, se você não sabe quais são estes dados entre em contato com seu servidor de hospedagem para solicita-los.
// NOME DA TABELA
$tabela = "newsletter";
// CAMPOS UTILIZADOS PARA A CONSULTA
$campos = "id, nome, email";
// NUMERO MÁXIMO DE ENVIO
$quant = 10;
// TEMPO ENTRE UM PROCESSO DE ENVIO E OUTRO
$seg = 36;
Na segunda linha informamos o nome da tabela onde se encontram os emails de nossos assinantes, eu criei a variável “$tabela” somente para facilitar as coisas pra quem está utilizando uma tabela com nome diferente.
Na quarta linha informamos os campos que vão ser utilizados no processo do envio. O campo id precisa ser informado pois é através dele que vamos informar qual email acaba de ser enviado.
O campo nome e email (nem precisa falar) são obrigatórios pois vão informar ao script o nome e email do destinatário.
Na sexta linha informamos a quantidade de emails que deve ser enviado por vez. Note que eu adicionei o valor “10″ você pode alterar este valor se quiser.
Na oitava linha informamos o tempo (em segundos) que deve ser aguardado entre um processo de envio e outro.
// DADOS DO EMAIL A SER ENVIADO
$assunto = "Envio de newslleter";
$msg = "Meu primeiro email enviado por pacotes em PHP/MySQL";
$nome_remetente = "Nome Remetente";
$email_remetente = "Email Remetente";
Na segunda linha informamos o título do email a ser enviado, este título corresponde ao assunto do email.
Na terceira linha informamos a mensagem do email, ou seja, a informação que deve ser enviada ao destinatário.
Na quarta e quinta linha informamos o nome e email do remetente (pessoa que envia), este ponto é importante, sempre que possível adicione um email verdadeiro pois é através dele que seu usuário poderá respondê-lo e também por que alguns servidores não permitem o envio de emails via PHP a menos que o campo “remetente” seja um email verdadeiro e principalmente existente no servidor, sendo assim, se seu site chama-se “site.com” seu email deve ser “algumacoisa@site.com”.
// ADICIONA AO CABEÇALHO DO EMAIL AS INFORMAÇÕES DO REMETENTE (QUEM ENVIA)
$cabecalho = "From: ". $nome_remetente ." <". $email_remetente .">";
// ADICIONA O CABEÇALHO PARA ENVIAR FORMATAÇÃO HTML
$cabecalho .= “MIME-Version: 1.0\r\n”;
$cabecalho .= “Content-type: text/html; charset=iso-8859-1\r\n”;
// CONECTA COM O SERVIDOR MYSQL
mysql_connect($host,$usuario,$senha);
// SELECIONA O BANCO
mysql_select_db($banco);
// RESGATA O VALOR DA GLOBAL INICIO
$inicio = $_GET["inicio"];
// ATRIBUI O RESULTADO DA SOMA ENTRE INICIO E QUANT
$fim = $inicio + $quant;
Nestas linhas fazemos (nesta ordem):
- Adicionamos as informações do remetente ao cabeçalho do email para que seja usado posteriormente.
- Adicionamos as informações para que o email aceite formatação HTML.
- Conectamos com o servidor MySQL, utilizando os dados de usuário, senha e host informados no inicio do script.
- Resgatamos o valor de uma variável global que será responsável por informar em qual registro deve ser iniciado o processo de envio dos emails.
- Atribuímos variável “$fim” o resultado da soma entre as variáveis “$inicio” e “$quant”.
// VERIFICA SE FOI ATRIBUIDO VALOR A VARIAVEL "INICIO"
if($inicio == ""){
// ATRIBUI O VALOR 0 CASO NÃO EXISTA VALOR ATRIBUIDO
$inicio = 0;
}else{
// ATRIBUI O VALOR DA GLOBAL INICIO CASO JA EXISTA VALOR ATRIBUIDO
$inicio = $_GET["inicio"];
}
- Verificamos se o valor da variável “$inicio” é igual a nada.
- Caso a verificação retorne verdadeiro, a variável “$inicio” passe a possuir o valor 0 (zero), indicando que ainda não foi enviado nenhum email, ou seja, o processo de envio ainda não começou.
- Caso a verificação retorne falso (o valor da variável pode ser qualquer coisa), ou seja, indica que o processo de envio já foi iniciado então a variável “$inicio” passe a possuir o valor que existir na global inicio.
// EXECUTA A CONSULTA OU INFORMA UM ERRO CASO OCORRA
$sql = mysql_query("SELECT ". $campos ." FROM ". $tabela ." WHERE codStatus = 0 LIMIT ". $inicio .",". $quant)or die(mysql_error());
- Montamos a consulta SQL necessária para retornar os dados solicitados pelo script.
- Adicionamos através das variáveis “$campos”, “$tabela”, “$inicio” e “$quant” os valores aos campos que vão ser utilizados no envio, nome da tabela onde encontram-se os dados dos assinantes, o valor que identifica de onde deve iniciar o envio e o valor que informa a quantidade máxima a ser enviada
// VERIFICA SE AINDA EXISTEM EMAILS A SEREM ENVIADOS
if(mysql_num_rows($sql) == 0){
// ALTERANDO O VALOR DO CAMPO CODSTATUS PARA 0
@mysql_query(“UPDATE “. $tabela .” SET codStatus = 0″);
// INFORMO O TÉRMINO DO PROCESSO
echo “Fim do processo de envio!”;
}else{
// CONTINUA EFETUANDO O ENVIO
echo “<meta http-equiv=\”refresh\” content=\”" . $seg . “,URL=?inicio=”. $fim .”\”>”;
}
Esta é uma parte importante no sistema.
- Verificamos se a quantidade de registros retornados é 0 (zero), ou seja, nenhum registro encontrado.
- Caso a quantidade de registros retornados seja 0 (zero), o script atualiza todos os registros existentes na tabela informada na variável “$tabela” (no meu exemplo “newsletter”), note que a atualização informa que o valor do campo codStatus deve ser alterado para 0. Você deve ter lido isso no início deste artigo.
- Após finalizar a atualização de todos os registros exibimos a mensagem informando o término do processo.
- Caso a quantidade de registros não seja 0 (zero), ou seja, foi encontrado um ou mais registros é “impresso” a meta refresh, está meta atualiza a página a cada intervalo de segundos, no nosso caso ela será atualizada a cada 10 segundos que foram informados através da variável $seg.
- Note que a meta refresh possui dois paramentos content que é o tempo em segundos que devem ser aguardados antes de atualizar a página e URL que é o endereço da página que deve ser carregada após o tempo informado em content, em nosso caso adicionei a parâmetro de url “inicio” que receberá o valor da variável “$fim”, esta variável informa em que número foi finalizado o último processo de envio.
- Se o item anterior foi executado o script irá aguardar o tempo informado e depois continuará enviando os emails.
// CRIA O LAÇO REPETITIVO
while($r = mysql_fetch_array($sql)){
// ADICIONAMOS OS PADRÕES DE DESTINATÁRIO
$para = $r["nome"] .”<”. $r["email"] .”>”;
// ENVIA O EMAIL PARA O DESTINATÁRIO
if(mail($para, $assunto, $msg, $cabecalho)){
// INFORMA SE A MENSAGEM FOI ENVIADA
echo “Mensagem enviada para:
\r”. $para;
// ALTERO O CODSTATUS PARA 1
@mysql_query(“UPDATE”. $tabela .” SET codStatus = 1 WHERE id = “. $id);
}else{
// INFORMO SE A MENSAGEM NÃO FOI ENVIADA
echo “Mensagem não enviada para:
\r”. $para;
}
}
- Criamos um laço repetitivo que será responsável por transferir os valores retornados na consulta SQL realizada anteriormente.
- Com os dados do destinatário, tentamos enviar o email
- Caso o envio seja bem sucedido é exiba a mensagem informando para quem foi enviado e em seguida atualizamos o registro referente ao email que acabamos de enviar, note que agora atualizamos o campo “codStatus” para conter o valor 1 (Email enviado).
- Caso a mensagem não seja enviada o script exibe a mensagem informando pra quem não foi possível enviar.
// LIBERA MEMORIA USADA NA CONSULTA
mysql_free_result($sql);
// FECHA A CONEXÃO COM O BANCO
mysql_close($conexao);
- Depois de ter realizado a consulta liberamos a memória utilizada no processo. Isso é necessário apenas para grandes consultas, ou para quem tem limite de processamento (CPU).
- Fechamos a conexão que haviamos criado anteriormente.
Bom, espero que isso seja útil para você (Demorei muito tempo digitando isso aqui e explicando tudo
).
Para aqueles que queiram saber mais sobre as funções utilizadas aqui disponibilizo aqui os links para tais.
mysql_connect()
mysql_close()
mysql_select_db()
mysql_fetch_array()
mysql_free_result()
mysql_query()
mysql_num_rows()
while()
mail()
E por fim disponibilizo aqui o script completo para quem quiser testa-lo ou utiliza-lo.
<?PHP
############################
# O CONTEÚDO DESTE NÃO FOI
# CRIADO COM O INTUITO DE
# DISTRIBUIR SPAM, OBRIGADO.
############################
// DADOS DE ACESSO AO BANCO MYSQL
$host = “HOST”;
$banco = “BANCO”;
$usuario = “USUARIO”;
$senha = “SENHA”;
// NOME DA TABELA
$tabela = “newsletter”;
// CAMPOS UTILIZADOS PARA A CONSULTA
$campos = “id, nome, email”;
// NUMERO MÁXIMO DE ENVIO
$quant = 10;
// TEMPO ENTRE UM PROCESSO DE ENVIO E OUTRO
$seg = 36;
// DADOS DO EMAIL A SER ENVIADO
$assunto = “Envio de newslleter”;
$msg = “Meu primeiro email enviado por pacotes em PHP/MySQL”;
$nome_remetente = “Nome Remetente”;
$email_remetente = “Email Remetente”;
// ADICIONA AO CABEÇALHO DO EMAIL AS INFORMAÇÕES DO REMETENTE (QUEM ENVIA)
$cabecalho = “From: “. $nome_remetente .” <”. $email_remetente .”>”;
// ADICIONA O CABEÇALHO PARA ENVIAR FORMATAÇÃO HTML
$cabecalho .= “MIME-Version: 1.0\r\n”;
$cabecalho .= “Content-type: text/html; charset=iso-8859-1\r\n”;
// CONECTA COM O SERVIDOR MYSQL
mysql_connect($host,$usuario,$senha);
// SELECIONA O BANCO
mysql_select_db($banco);
// RESGATA O VALOR DA GLOBAL INICIO
$inicio = $_GET["inicio"];
// VERIFICA SE FOI ATRIBUIDO VALOR A VARIAVEL “INICIO”
if($inicio == “”){
// ATRIBUI O VALOR 0 CASO NÃO EXISTA VALOR ATRIBUIDO
$inicio = 0;
}else{
// ATRIBUI O VALOR DA GLOBAL INICIO CASO JA EXISTA VALOR ATRIBUIDO
$inicio = $_GET["inicio"];
}
// ATRIBUI O RESULTADO DA SOMA ENTRE INICIO E QUANT
$fim = $inicio + $quant;
// EXECUTA A CONSULTA OU INFORMA UM ERRO CASO OCORRA
$sql = mysql_query(“SELECT “. $campos .” FROM “. $tabela .” WHERE codStatus = 0 LIMIT “. $inicio .”,”. $quant)or die(mysql_error());
// VERIFICA SE AINDA EXISTEM EMAILS A SEREM ENVIADOS
if(mysql_num_rows($sql) == 0){
// ALTERANDO O VALOR DO CAMPO CODSTATUS PARA 0
@mysql_query(“UPDATE “. $tabela .” SET codStatus = 0″);
// INFORMO O TÉRMINO DO PROCESSO
echo “Fim do processo de envio!”;
}else{
// CONTINUA EFETUANDO O ENVIO
echo “<meta http-equiv=\”refresh\” content=\”" . $seg . “,URL=?inicio=”. $fim .”\”>”;
}
// CRIA O LAÇO REPETITIVO
while($r = mysql_fetch_array($sql)){
// ADICIONAMOS OS PADRÕES DE DESTINATÁRIO
$para = $r["nome"] .”<”. $r["email"] .”>”;
// ENVIA O EMAIL PARA O DESTINATÁRIO
if(mail($para, $assunto, $msg, $cabecalho)){
// INFORMA SE A MENSAGEM FOI ENVIADA
echo “Mensagem enviada para:
\r”. $para;
// ALTERO O CODSTATUS PARA 1
@mysql_query(“UPDATE”. $tabela .” SET codStatus = 1 WHERE id = “. $id);
}else{
// INFORMO SE A MENSAGEM NÃO FOI ENVIADA
echo “Mensagem não enviada para:
\r”. $para;
}
}
// LIBERA MEMORIA USADA NA CONSULTA
mysql_free_result($sql);
// FECHA A CONEXÃO COM O BANCO
mysql_close($conexao);
?>