Enviar formulário de contato com anexo em PHP

Recentemente precisei montar um formulário de contato em PHP com a possibilidade de enviar um arquivo anexado, e percebi que o PHP não suporta isso nativamente pela função mail(). Como eu não quis usar nenhuma biblioteca de terceiros pronta, vi que seria necessário alterar o header do e-mail e acrescentar nele o anexo. Para alcançar esse resultado, primeiramente precisei alterar o meu formulário. Este abaixo serve como exemplo, note o atributo enctype="multipart/form-data", sem ele não vai funcionar.

<!-- form.php -->
<form action="envio.php" method="post" enctype="multipart/form-data">
    <p>
        <label for="nome">Nome</label>
        <input type="text" name="nome" id="nome" required="" />
    </p>
    <p>
        <label for="email">Email</label>
        <input type="email" name="email" id="email" required="" />
    </p>
    <p>
        <label for="anexo">Anexo</label>
        <input type="hidden" name="MAX_FILE_SIZE" value="100000" />
        <input type="file" id="anexo" name='anexo' />
    </p>
</form>

No script que vai receber os dados para envio, verifico a existência do anexo, já que ele é opcional, e codifico ele no header do e-mail. Aproveito e também dou uma limpada nos textos enviados, para evitar o chamado Email injection, já que não devemos confiar em textos enviados pelo usuário.

<?php
// evitar email injection
function clean_string($string) {
    $bad = array(
        "content-type",
        "bcc:",
        "to:",
        "cc:",
        "href"
    );
    return str_replace($bad, "", $string);
}

//variáveis
$status = false;
$nome = clean_string($_POST['nome']);
$email = clean_string($_POST['email']);
$mensagem = "Enviado pelo <strong>formulário de contato</strong>";
$destino = "[email protected]";  //E-mail do destinatário
$assunto = "Contato"; // Assunto do E-mail

// se o nome temporário do arquivo estiver vazio, ele não foi enviado
if (empty($_FILES['anexo']['tmp_name'])) {
    //cabeçalho
    $headers = "Content-type: text/html; charset=utf-8\r\n";
    $headers .= "From: $nome <$email>\r\n"; //E-Mail do destinatário
    $headers .= "Reply-To: $email\r\n";
    //envio
    $status = mail ($destino, $assunto, $observacao, $headers);
} else {
    // inicialmente, abre o arquivo e converte ele para base64
    $file = $_FILES['anexo']['tmp_name'];
    $originalFile = $_FILES['anexo']['name'];
    $file_size = filesize($file);
    $handle = fopen($file, "rb");
    $content = fread($handle, $file_size);
    fclose($handle);
    $content = chunk_split(base64_encode($content));

    // separador aleatório necessário para enviar conteúdo mixed
    $separator = md5(time());

    // fim de linha (usando uma constante do PHP para fim de linha)
    $eol = PHP_EOL;

    // cabeçalho principal (multipart obrigatório)
    $headers = "From: $nome <$email>" . $eol;
    $headers .= "MIME-Version: 1.0" . $eol;
    $headers .= "Content-Type: multipart/mixed; boundary=\"" . $separator . "\"" . $eol . $eol;
    $headers .= "Content-Transfer-Encoding: 8bit" . $eol;
    $headers .= "This is a MIME encoded message." . $eol . $eol;

    // mensagem (apenas formato html aqui)
    $headers .= "--" . $separator . $eol;
    $headers .= "Content-Type: text/html; charset=\"utf-8\"" . $eol;
    $headers .= $mensagem . $eol . $eol;

    // anexo usando o nome do arquivo original
    $headers .= "--" . $separator . $eol;
    $headers .= "Content-Type: application/octet-stream; name=\"" . $originalFile . "\"" . $eol;
    $headers .= "Content-Transfer-Encoding: base64" . $eol;
    $headers .= "Content-Disposition: attachment" . $eol . $eol;
    $headers .= $content . $eol . $eol;
    $headers .= "--" . $separator . "--";

    // enviar email
    $status = mail($destino, $assunto, "", $headers);
}

if ($status) {
    echo "Envio com sucesso";
} else {
    echo "Ocorreu um erro no envio";
}

Pronto, com isso agora o formulário é capaz de enviar os anexos corretamente. Fontes