Página Inicial > Outros, PHP > Enviando emails via socket

Enviando emails via socket

Ola pessoal.

Estou aqui para postar uma classe minha, desenvolvida a algum tempo ja, que possui anexos, autenticação, e tudo mais.

Segue a classe e um exemplo de uso ok?

Bom aproveito.

<?php

    /**
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are met:
     *
     *     * Redistributions of source code must retain the above copyright
     *       notice, this list of conditions and the following disclaimer.
     *     * Redistributions in binary form must reproduce the above copyright
     *       notice, this list of conditions and the following disclaimer in the
     *       documentation and/or other materials provided with the distribution.
     *     * Neither the name of the University of California, Berkeley nor the
     *       names of its contributors may be used to endorse or promote products
     *       derived from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND ANY
     * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
     * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     *
     * Classe de manipulação do protocolo SMTP
     * @author Bruno Pitteli Gonçalves <scorninpc<at>gmail<dot>com>
     * @version 0.2
     * @license BSD license
     *
     * 0.1
     *        Classe inicial
     *
     * 0.2
     *        Possibilidade de envio de email HTML
     *
     * 0.3
     *        Suporte a varios TOs separados por;
     *
     * 0.4
     *        Suporte à mudança da codificação
     *
     */

    // Seta o tempo limite para 60 segundos
    set_time_limit(120);
   
    /**
     * SMTPMAIL
     * Escrito por Bruno Pitteli Gonçalves <scorninpc()gmail*com>
     * Classe que trata o protocolo SMTP
     */

    class SMTPMAIL {
        /**
         *    Variavel que armazena o endereço do servidor de email
         *    @access public
         */

        public $Servidor;
       
        /**
         *    Variavel que armazena a porta do servidor de email
         *    @access public
         */

        public $Porta = 25;
       
        /**
         *    Variavel que armazena a codificação
         *    @access public
         */

        public $Codificacao = 'ISO-8859-1';
       
        /**
         *    Variavel que armazena se o servidor é autenticado
         *    @access public
         */

        public $Autenticado;
       
        /**
         *    Variavel que armazena o usuario do servidor de email, caso autenticado
         *    @access public
         */

        public $Usuario;
       
        /**
         *    Variavel que armazena a senha do usuario do servidor de email, caso autenticado
         *    @access public
         */

        public $Senha;
       
        /**
         *    Variavel que armazena o email de quem está enviando
         *    @access public
         */

        public $EmailDe;
       
        /**
         *    Variavel que armazena o nome+email de quem está enviando, para aparecer no email
         *    @access public
         */

        public $EmailDeVisual;
       
       
        /**
         *    Variavel que armazena o email para quem vai
         *    @access public
         */

        public $EmailPara;
       
        /**
         *    Variavel que armazena o nome+email de quem está enviando, para aparecer no email
         *    @access public
         */

        public $EmailParaVisual;
       
        /**
         *    Variavel que armazena o assunto do email
         *    @access public
         */

        public $Assunto;
       
        /**
         *    Variavel que armazena a senha corpo do email
         *    @access public
         */

        public $Corpo;
       
        /**
         *    Vetor que armazena os arquivos para anexo
         *    @access private
         */

        private $Anexos = array();
       
        /**
         *    Variavel que armazena a situação do envio do email
         *    @access private
         */

        private $erros = FALSE;
   
        /**
         *    Construtor da classe
         *    @name __construct
         *    @access public
         */

        public function __construct() {
        } // __construct
   
        /**
         *    Método que anexa um arquivo ao vetor
         *    @name anexarArquivo
         *    @param string $path – Caminho do arquivo
         *    @access public
         */

        public function anexarArquivo($path) {
            $this->Anexos[] = $path;
        } // anexarArquivo
       
        /**
         *    Método que verifica se a classe esta pronta está pronta para o envio de email
         *    @name verificarIntegridade
         *    @access private
         *    @return boolean
         */

        private function verificarIntegridade() {
            // Verifica as pendencias se o servidor for autenticado
            if($this->Autenticado === TRUE) {
                if((empty($this->Usuario)) || (empty($this->Senha))) {
                    $this->erros = TRUE;
                    return FALSE;
                }
            }
           
            // Verifica se o servidor foi digitado
            if(empty($this->Servidor)) {
                $this->erros = TRUE;
                return FALSE;
            }
           
            // Verifica se os outros parametros são validos
            if((empty($this->EmailDe)) || (empty($this->EmailPara)) || (empty($this->Assunto)) || (empty($this->Corpo))) {
                $this->erros = TRUE;
                return FALSE;
            }
           
            return TRUE;
        } // verificarIntegridade
   
        /**
         *    Método que espera a resposta do servidor
         *    @name esperarResposta
         *    @access private
         *    @param integer $socket – Ponteiro para o socket
         *    @param integer $response – Codigo de resposta OK
         *    @return boolean
         */

        private function esperarResposta($socket, $response) {
            while (substr($server_response, 3, 1) != ' ') {
                if (!($server_response = fgets($socket, 256))) {
                    $this->erros = TRUE;
                    return FALSE;
                }
                if (!(substr($server_response, 0, 3) == $response)) {
                    $this->erros = TRUE;
                    return FALSE;
                }
//                echo '<font color="red">S</font> <- ' . $server_response . '
';
            }
            return TRUE;
        } // esperarResposta
       
        /**
         *    Método que envia uma string ao servidor
         *    @name enviaPacote
         *    @access private
         *    @param integer $socket – Ponteiro para o socket
         *    @param integer $data – String contendo as informações à serem enviadas
         *    @return boolean
         */
        private function enviaPacote($socket, $data) {
            if(!fputs($socket, $data . "\r\n")) {
                return FALSE;
            }
//            echo "<font color=\"blue\">C</font> -> " . $data . "
";
            return TRUE;
        } // enviaResposta
   
        /**
         *    Método que envia o email
         *    @name Enviar
         *    @access prublic
         *    @return boolean
         */
        function Enviar() {            
            $boundary = md5(date('
r', time()));
           
            // Verifica se esta pronto para iniciar o envio
            if(!$this->verificarIntegridade()) {
                return FALSE;
            }

            // Tenta conectar
            if(!$socket = fsockopen($this->Servidor, $this->Porta, $errno, $errstr, 30)) {
                $this->erros = TRUE;
                return FALSE;
            }
       
            // Espera por resposta
            $this->esperarResposta($socket, "220");
       
            // Se o servidor é autenticado
            if($this->Autenticado) {
                $this->enviaPacote($socket, "EHLO " . $this->Servidor);
                $this->esperarResposta($socket, "250");
           
                $this->enviaPacote($socket, "AUTH LOGIN");
                $this->esperarResposta($socket, "334");
               
                $this->enviaPacote($socket, base64_encode($this->Usuario));
                $this->esperarResposta($socket, "334");
           
                $this->enviaPacote($socket, base64_encode($this->Senha));
                $this->esperarResposta($socket, "235");
            } else {
                $this->enviaPacote($socket, "HELO " . $this->Servidor);
                $this->esperarResposta($socket, "250");
            }
           
            // Envia quem está mandando o email
            $this->enviaPacote($socket, "MAIL FROM: " . $this->EmailDe);
            $this->esperarResposta($socket, "250");
           
            // Envia quem esta recebendo o email
            $Emails = explode(';', $this->EmailPara);
            for($i=0;$i<count($Emails);$i++) {
                $this->enviaPacote($socket, "RCPT TO: " . $Emails[$i]);
                $this->esperarResposta($socket, "250");
            }
           
            // Diz ao servidor que estou pronto para enviar a mensagem
            $this->enviaPacote($socket, "DATA");
            $this->esperarResposta($socket, "354");

            // Cabeçalho do email
            if(strlen($this->EmailDeVisual) == 0) {
                $this->enviaPacote($socket, "From: " . $this->EmailDe);
            } else {
                $this->enviaPacote($socket, "From: " .  $this->EmailDeVisual . " <" .  $this->EmailDe . ">");
            }
           
            $To = 'To: ';
            $Emails = explode('
;', $this->EmailPara);
            for($i=0; $i<count($Emails); $i++) {
                if(empty($Emails[$i])) {
                    continue;
                }
                $To .= $Emails[$i] . '
, ';
            }

            $To = substr($To, 0, strrpos($To, ','));

            $this->enviaPacote($socket, $To);
           
            // Mando o assunto do email
            $this->enviaPacote($socket, "Subject: " . $this->Assunto);
           
            // Envia o cabeçalho
            $this->enviaPacote($socket, "Date: " . date("d M y H:i:s"));
            $this->enviaPacote($socket, "MIME-Version: 1.0");
            $this->enviaPacote($socket, "Content-Type: multipart/mixed; boundary=" . $boundary);
            $this->enviaPacote($socket, "–" . $boundary);
            $this->enviaPacote($socket, "Content-Type: text/html; charset=" . $this->Codificacao . "\r\n");
            $this->enviaPacote($socket, $this->Corpo);
            $this->enviaPacote($socket, "\r\n");
       
            // Verifica se existe arquivo para ser enviado junto
            if(count($this->Anexos) > 0) {
                for($i=0; $i<count($this->Anexos); $i++) {
                    $info = pathinfo($this->Anexos[$i]);

                    // Pega o tipo para o MIME TYPE
                    strtolower($info['extension']);
                    switch($tipo) {
                        case "jpeg":
                        case "jpg":
                            $Tipo = "image/jpeg";
                        break;
                        case "gif":
                            $Tipo = "image/gif";
                        break;
                        case "doc":
                            $Tipo = "application/msword";
                        break;
                        case "rar":
                            $Tipo = "application/rar";
                        break;
                        case "zip":
                            $Tipo = "application/zip";
                        break;
                        case "pdf":
                            $Tipo = "application/pdf";
                        break;
                        default:
                            $Tipo = "application/octet-stream";
                        break;
                    }
                   
                    // Envia os cabeçalhos do anexo
                    $this->enviaPacote($socket, "–" . $boundary);
                    $this->enviaPacote($socket, "Content-Type: " . $Tipo . "; name=\"". $info['
filename'] . "\"");
                    $this->enviaPacote($socket, "Content-Transfer-Encoding: base64");
                    $this->enviaPacote($socket, "Content-Disposition: attachment; filename=\"" . $info['
filename'] . "\"");
                    $this->enviaPacote($socket, "\r\n");
               
                    // Envia o arquivo codificado
                    $this->enviaPacote($socket, base64_encode(file_get_contents($this->Anexos[$i])));
                    $this->enviaPacote($socket, "\r\n");
                }
                $this->enviaPacote($socket, "–" . $boundary . "–");
            }
           
            // Avisa o o termino do envio
            $this->enviaPacote($socket, "\r\n\r\n.");
            $this->esperarResposta($socket, "250");
           
            // Sai do servidor e fecha o socket
            $this->enviaPacote($socket, "QUIT");
            fclose($socket);
       
            // Retorna FALSE se o email não foi enviado
            if($this->erros == TRUE) {
                return FALSE;
   
            // Ou TRUE se não houve erro
            } else {
                return TRUE;
            }
        } // Enviar
    }
?>

Classe
$Email = new SMTPMAIL() – Cria novo objeto

Atributos
$Email->Servidor – Servidor SMTP (não aceita SSL como gmail AINDA)
$Email->Autenticado – True se for autenticado, false se não for autenticado
$Email->Codificacao – Seta a codificação (UTF-8, ISO-8859-1, …)
$Email->Usuario – Usuario do servidor SMTP
$Email->Senha – Senha do servidor SMTP
$Email->EmailDe – Email de quem está enviando o email
$Email->EmailPara – Email de quem irá receber o email
$Email->Assunto – Assunto do email
$Email->Corpo – Mensagem do email

Métodos
$Email->Anexar() – Anexa um arquivo, pode ser usado varias vezes, retorna true se enviar ou false se tiver erro
$Email->Enviar() – Envia o email, retorna true se enviar ou false se tiver erro

<?php
    require_once('smtpmail.class.php');
   
    $smtp = new SMTPMAIL();
    $smtp->Servidor  ='smtp.mail.yahoo.com.br';
   
    $smtp->Autenticado = TRUE;
    $smtp->Usuario = "meu_usuario";
    $smtp->Senha = "minha_senha";
   
    $smtp->Codificacao = "UTF-8";

    $smtp->EmailDe = 'bruno0@gmail.com';
    $smtp->EmailDeVisual = 'Bruno Pitteli Gonçalves <bruno.goncalves@added.com.br>';

    $smtp->EmailPara = 'bruno1@gmail.com;bruno2@gmail.com';
   
    $smtp->Assunto = 'Email Teste';
   
    $smtp->Corpo = '<b>MEU CORPO HTML</b>';
   
    $smtp->anexarArquivo('D:\\Bruno\\Fotos&Videos\\Carros\\03-07-07_0916.jpg');
    $smtp->anexarArquivo('D:\\Bruno\\Fotos&Videos\\Carros\\Carro_11.jpg');
   
    if($smtp->Enviar()) {
        echo 'ok';
    } else {
        echo 'errado';
    }
?>
 

Categories: Outros, PHP Tags: , , ,
  1. Igor Carvalho de Paula
    18, setembro, 2009 em 08:23 | #1

    Muito interessante pena q nao funcionou em localhost….

  2. 18, setembro, 2009 em 08:31 | #2

    Igor, deveria funcionar. Se seu localhost tiver um servidor SMTP, irá funcionar! Caso não tenha, teria que utilizar um SMTP externo, como yahoo!.

  3. Raulino Nickel Junior
    13, outubro, 2009 em 15:47 | #3

    Buenas Bruno! Seguinte eu consigo enviar o e-mail com sucesso, aparece o assunto o icone de anexo e etc. O problema é que quando vou acessar o e-mail, o corpo do texto e o anexo não aparecem … você jah viu dessa loucura?

  4. 13, outubro, 2009 em 15:56 | #4

    Raulino, pode ser seu cliente de email que está bloqueando o anexo. Você está vendo esse email por onde? outlook?

  5. Raulino Nickel Junior
    13, outubro, 2009 em 16:22 | #5

    Olá Bruno! Tanto o Thunderbird qnto o Outlook tem esse problema! e o engraçado é que acessando o codigo fonte do e-mail pelo Thunderbird o corpo está identico a outros e-mails que recebo

  6. 13, outubro, 2009 em 16:28 | #6

    O anexo vai como se fosse um pedaço do corpo do email, é impossível o email ir e o corpo não. O que pode acontecer é o cliente de email excluir (ocultar) a parte do anexo pensando ser vírus ou o servidor de email o fazer.
    Já tentou acessar o email por um cliente Web para verificar se funciona? já tentou fazer um teste para outro email (outro domínio, gmail, uol, yahoo), já tentou colocar outro anexo?

  7. Raulino Nickel Junior
    13, outubro, 2009 em 17:01 | #7

    Olá Bruno Esse é o retorno quando vou nas propriedades da mensagem, O erro ocorreu no Yahoo! tambem … estou postando a fonte do e-mail … espero q ajude! :)

    EDITADO

  8. 13, outubro, 2009 em 17:20 | #8

    Tente enviar um para mim dar uma olhada: scorninpc cadastrado no gmail domínio com

  9. Raulino Nickel Junior
    13, outubro, 2009 em 17:44 | #9

    E-mail Enviando bruno

  1. Nenhum trackback ainda.