2009-05-05 12 views
22

Imagine un usuario que desea poner un formulario en su sitio web que permita a un visitante del sitio web cargar un archivo y un mensaje simple, que se enviará por correo electrónico inmediatamente (es decir, el archivo no se almacena en el servidor, o solo temporalmente) como archivo adjunto con la nota en el cuerpo del mensaje.Formulario PHP simple: Adjunto al correo electrónico (código de golf)

Ver más detalles en http://a2zsollution.com/php-secure-e-mail/

¿Cuál es la forma más sencilla de lograr esto?

más simple en términos de:

  • Tamaño (campo de código)
  • Facilidad de aplicación (lo ideal es todo en un solo archivo, necesita pocos o ningún recursos externos)
  • no ofuscado por el bien de la ofuscación (soluciones de compromiso para el tamaño están bien)
  • Auto ejemplo contenía (si se llama sin un post forma, se muestra la forma)

Esto es casi el reverso de: How to get email and their attachments from PHP. Casi podría haber sido respondida en Compiling email with multiple attachments in PHP, pero en realidad no muestra el código.

+0

Ofrecería mi propia solución, pero a juzgar por las competiciones anteriores de golf de código, ¡sería derrotado! –

Respuesta

68

Simplemente por diversión, pensé que lo iba a tocar. Terminó siendo más complicado de lo que pensaba porque no entendía completamente cómo funcionaba la parte límite, eventualmente me di cuenta de que el inicio y el final '-' eran significativos y no funcionaban. Realmente

<?php 
    if(isset($_POST['submit'])) 
    { 
     //The form has been submitted, prep a nice thank you message 
     $output = '<h1>Thanks for your file and message!</h1>'; 
     //Set the form flag to no display (cheap way!) 
     $flags = 'style="display:none;"'; 

     //Deal with the email 
     $to = '[email protected]'; 
     $subject = 'a file for you'; 

     $message = strip_tags($_POST['message']); 
     $attachment = chunk_split(base64_encode(file_get_contents($_FILES['file']['tmp_name']))); 
     $filename = $_FILES['file']['name']; 

     $boundary =md5(date('r', time())); 

     $headers = "From: [email protected]\r\nReply-To: [email protected]"; 
     $headers .= "\r\nMIME-Version: 1.0\r\nContent-Type: multipart/mixed; boundary=\"_1_$boundary\""; 

     $message="This is a multi-part message in MIME format. 

--_1_$boundary 
Content-Type: multipart/alternative; boundary=\"_2_$boundary\" 

--_2_$boundary 
Content-Type: text/plain; charset=\"iso-8859-1\" 
Content-Transfer-Encoding: 7bit 

$message 

--_2_$boundary-- 
--_1_$boundary 
Content-Type: application/octet-stream; name=\"$filename\" 
Content-Transfer-Encoding: base64 
Content-Disposition: attachment 

$attachment 
--_1_$boundary--"; 

     mail($to, $subject, $message, $headers); 
    } 
?> 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
<title>MailFile</title> 
</head> 

<body> 

<?php echo $output; ?> 

<form enctype="multipart/form-data" action="<?php echo $_SERVER['PHP_SELF'];?>" method="post" <?php echo $flags;?>> 
<p><label for="message">Message</label> <textarea name="message" id="message" cols="20" rows="8"></textarea></p> 
<p><label for="file">File</label> <input type="file" name="file" id="file"></p> 
<p><input type="submit" name="submit" id="submit" value="send"></p> 
</form> 
</body> 
</html> 

Muy barebones, y obviamente el uso de CSS en línea para ocultar la forma es un poco barato y es casi seguro que querría un poco más de información al usuario! Además, probablemente me demore un poco más en averiguar cuál es el tipo de contenido real para el archivo, en lugar de copiar y usar la aplicación/octet-stream, pero esa parte es tan interesante.

+5

Esta es la mejor respuesta hasta ahora en mi opinión, ya que usted es el único que proporciona el código completo (que la pregunta específicamente solicita). +1. – pix0r

+3

Está bien usar md5 para el límite para el golf, pero para la producción debe verificar que el límite no ocurra en el archivo adjunto codificado. Algunas codificaciones son más seguras, por ejemplo, Base64 nunca coincidirá accidentalmente con un límite que tenga '_' en él –

+0

¿Hay alguna forma de adjuntar varios archivos? –

16

Una combinación de este http://www.webcheatsheet.com/PHP/send_email_text_html_attachment.php#attachment

con el ejemplo de carga de archivos php funcionaría. En el ejemplo de carga de archivos en lugar de utilizar move_uploaded_file para moverlo de la carpeta temporal que acaba de abrirlo:

$attachment = chunk_split(base64_encode(file_get_contents($tmp_file))); 

donde $tmp_file = $_FILES['userfile']['tmp_name'];

y enviarlo como archivo adjunto al igual que el resto del ejemplo.

Todo en un solo archivo/autónomo:

<? if(isset($_POST['submit'])){ 
//process and email 
}else{ 
//display form 
} 
?> 

Creo que es un ejercicio rápido para obtener lo que necesita trabajar sobre la base de los dos ejemplos anteriores disponibles.

P.S. Necesita ser cargado en algún lugar antes de que Apache lo pase a PHP para hacer lo que quiera con él. Esa sería la carpeta temporal de tu sistema por defecto a menos que se haya cambiado en el archivo de configuración.

4

Este artículo "How to create PHP based email form with file attachment" presenta instrucciones paso a paso sobre cómo cumplir con sus requisitos.

Cita:

este artículo se muestra cómo crear un formulario de correo electrónico basado en PHP que soporta archivo adjunto. El artículo también mostrará cómo validar el tipo y el tamaño del archivo cargado.

Se compone de los siguientes pasos:

  • El formulario HTML con caja de carga de archivos
  • Conseguir el archivo cargado en el PHP guión
  • Validar el tamaño y la extensión del la subida archivo
  • Copie el archivo cargado
  • Enviando el Email

Todo el código de ejemplo se puede descargar here

1

PEAR::Mail_Mime? Claro, la dependencia PEAR de (mínimo) 2 archivos (solo mail_mime en sí mismo si lo edita para eliminar las dependencias pear), pero funciona bien. Además, la mayoría de los servidores tienen PEAR instalado en cierta medida, y en el mejor de los casos tienen Pear/Mail y Pear/Mail_Mime. Algo que no se puede decir de la mayoría de las otras bibliotecas que ofrecen la misma funcionalidad.

También puede considerar buscar en PHP IMAP extension. Es un poco más complicado y requiere más configuración (no está habilitado o instalado por defecto), pero es más eficiente para compilar y enviar mensajes a un servidor con capacidad IMAP.

4

Para agregar el archivo al correo electrónico como un archivo adjunto, es que se almacenará brevemente en el servidor. Sin embargo, es trivial colocarlo en una ubicación tmp y luego eliminarlo después de que hayas terminado con él.

En cuanto al envío de correos electrónicos, Zend Mail tiene una interfaz muy fácil de usar para manejar archivos adjuntos de correo electrónico. Funcionamos con todo el Zend Framework instalado, pero estoy bastante seguro de que podría instalar la biblioteca Zend_Mail sin necesidad de otros módulos para las dependencias.

Con Zend_Mail, el envío de un correo electrónico con un archivo adjunto es tan simple como:

$mail = new Zend_Mail(); 
$mail->setSubject("My Email with Attachment"); 
$mail->addTo("[email protected]"); 
$mail->setBodyText("Look at the attachment"); 
$attachment = $mail->createAttachment(file_get_contents('/path/to/file')); 
$mail->send(); 

Si usted está buscando un uno-archivo-paquete para hacer todo esto forma/correo electrónico/archivo adjunto, no he No he visto uno. Pero los componentes individuales están ciertamente disponibles y son fáciles de montar. Lo más complicado de todo el grupo es el archivo adjunto de correo electrónico, que la recomendación anterior hace muy simple.

4

No he probado la parte del correo electrónico de esto (mi cuadro de prueba no envía correo electrónico) pero creo que va a funcionar.

<?php 
if ($_POST) { 
$s = md5(rand()); 
mail('[email protected]', 'attachment', "--$s 

{$_POST['m']} 
--$s 
Content-Type: application/octet-stream; name=\"f\" 
Content-Transfer-Encoding: base64 
Content-Disposition: attachment 

".chunk_split(base64_encode(join(file($_FILES['f']['tmp_name']))))." 
--$s--", "MIME-Version: 1.0\r\nContent-Type: multipart/mixed; boundary=\"$s\""); 
exit; 
} 
?> 
<form method="post" enctype="multipart/form-data" action="<?php echo $_SERVER['PHP_SELF'] ?>"> 
<textarea name="m"></textarea><br> 
<input type="file" name="f"/><br> 
<input type="submit"> 
</form> 
+1

Me gusta el tuyo por pequeño y simple y desearía haberles dado la recompensa a ambos. –

Cuestiones relacionadas