PHP mailer Script help

Hi,

I have a php mailer script (not phpmailer!) and it successfully sends an email… however I need to attach a file to the email rather than a generic ‘attachment.txt.’ file.

I have a html form that the user can enter an email address, file_name and message - the message and email both work ok. My problem is that the file_name does not work.

Here is my current code;-
[php]<?php
if (isset($_POST[‘submit’]))
{
$file_name = $_POST[‘file_name’];
$doc_email = $_POST[‘doc_email’];
$doc_message = $_POST[‘doc_message’];

//define the receiver of the email
$to = $_POST[‘doc_email’];

//define the subject of the email
$subject = ‘Email with attachment’;

//create a boundary string. It must be unique
//so we use the MD5 algorithm to generate a random hash
$random_hash = md5(date(‘r’, time()));

//define the headers we want passed. Note that they are separated with \r\n
$headers = “From: [email protected]\r\nReply-To: [email protected]”;

//add boundary string and mime type specification
$headers .= “\r\nContent-Type: multipart/mixed; boundary=“PHP-mixed-”.$random_hash.”"";

//read the atachment file contents into a string,
//encode it with MIME base64,
//and split it into smaller chunks
$attachment = chunk_split(base64_encode(file_get_contents(‘uploads/$_POST[$file_name’])));

//define the body of the message.
ob_start(); //Turn on output buffering
?>

–PHP-mixed-<?php echo $random_hash; ?>
Content-Type: multipart/alternative; boundary=“PHP-alt-<?php echo $random_hash; ?>”

–PHP-alt-<?php echo $random_hash; ?>
Content-Type: text/plain; charset=“iso-8859-1”
Content-Transfer-Encoding: 7bit

Hello World!!!
This is simple text email message.

User wrote:-

<?php echo $doc_message; ?>

–PHP-alt-<?php echo $random_hash; ?>
Content-Type: text/html; charset=“iso-8859-1”
Content-Transfer-Encoding: 7bit

Hi there

,

This is something with HTML formatting.

User wrote:-

<?php echo $doc_message; ?>

–PHP-alt-<?php echo $random_hash; ?>–

–PHP-mixed-<?php echo $random_hash; ?>
Content-Type: application/txt; name=“attachment.txt”
Content-Transfer-Encoding: base64
Content-Disposition: attachment

<?php echo $attachment; ?>

–PHP-mixed-<?php echo $random_hash; ?>–

<?php //copy current buffer contents into $message variable and delete current output buffer $message = ob_get_clean(); //send the email $mail_sent = @mail( $to, $subject, $message, $headers ); //redirect user after success header("Location: index.php"); } ?>[/php]

the $_POST[file_name] would be something like ’ 123.pdf’ within a sub folder called uploads.

Any ideas please?

Well, it might be because you told the code to expect an application file not a text file.
All filetypes have a specail MIME value assigned to them. Therefore…

Try changing:
Content-Type: application/txt; name=“attachment.txt”

To:
Content-Type: text/plain; name=“attachment.txt”

Here is a link to a full list of just about all MIME Content=Types…
http://webdesign.about.com/od/multimedia/a/mime-types-by-file-extension.htm

Hope that works for you…

Hi, thanks for your help… I’ve changed two lines of code based on your comment to get the mailer function to work. Here’s what I’ve changed;-

[php]$attachment = chunk_split(base64_encode(file_get_contents(‘uploads/$file_name’))); [/php]

[php]Content-Type: application/pdf; name=“uploads/’$file_name’” [/php]

The mailer sends me an email that now has an attachment called " uploads’$file_name’ " but no file extension etc and certainly not the file I wanted to attach and send.

Any thoughts?

Well, you got what you coded for… LOL You have to remember you are mixing your email text with your
PHP code. So, you currently have this line:
[php]Content-Type: application/pdf; name=“uploads/’$file_name’” [/php]

Try this instead:
[php]Content-Type: application/pdf; name="<?PHP echo $file_name; ?>" [/php]

This basically uses the PHP side to insert the file name into your email text. Hope that helps…

Hi ErnieAlex, thanks for the update - it now manages to send through a pdf file with the same title however it is just that… a pdf with the same title, the file size is a few bytes and is blank. Do you know where I am going wrong?

Dan, well, you first were talking about sending a text file, then you showed code for a PDF file.
If you want to send a PDF file, then your code should do that. PDF files must be opened by Acrobat
Reader (Adobe). The code I originally helped you with was for a text file. Perhaps you should show us
your new latest code.

Remember if you have a PDF file, it is formatted to be opened by Adobe AR. It is NOT available as text.
UNLESS, you use a library or code that pulls out the text from the PDF file and you insert that into a .txt
file to send as the attachment. Is that what you want to do? Perhaps I am unclear on what you need.

Let us know and post your latest code again…

Hi ErnieAlex,

Apologies if I’ve not explained myself properly, my code is supposed to allow a user to select a file and email it to someone. Each file on my server has a custom display page which details the files location, name, size etc and it also has a form on the same page where the user can enter a email address and personal message - the files location is pre-populated.

This info is passed onto my mailer.php code which is supposed to take the file name, email & message and process. This is where my code is failing - at the moment it will send an email with a message and reference an attachment with the file name but not the actual file located on my server.

Here’s my current code…

[php]<?php
if (isset($_POST[‘submit’]))
{
$file_name = $_POST[‘file_name’];
$doc_email = $_POST[‘doc_email’];
$doc_message = $_POST[‘doc_message’];

//define the receiver of the email
$to = $_POST[‘doc_email’];

//define the subject of the email
$subject = ‘Email with attachment’;

//create a boundary string. It must be unique
//so we use the MD5 algorithm to generate a random hash
$random_hash = md5(date(‘r’, time()));

//define the headers we want passed. Note that they are separated with \r\n
$headers = “From: [email protected]\r\nReply-To: [email protected]”;

//add boundary string and mime type specification
$headers .= “\r\nContent-Type: multipart/mixed; boundary=“PHP-mixed-”.$random_hash.”"";

//read the atachment file contents into a string,
//encode it with MIME base64,
//and split it into smaller chunks
$attachment = chunk_split(base64_encode(file_get_contents(‘uploads/$file_name’)));

//define the body of the message.
ob_start(); //Turn on output buffering
?>

–PHP-mixed-<?php echo $random_hash; ?>
Content-Type: multipart/alternative; boundary=“PHP-alt-<?php echo $random_hash; ?>”

–PHP-alt-<?php echo $random_hash; ?>
Content-Type: text/plain; charset=“iso-8859-1”
Content-Transfer-Encoding: 7bit

Hello World!!!
This is simple text email message.

User wrote:-

<?php echo $doc_message; ?>

–PHP-alt-<?php echo $random_hash; ?>
Content-Type: text/html; charset=“iso-8859-1”
Content-Transfer-Encoding: 7bit

Hi there

,

This is something with HTML formatting.

User wrote:-

<?php echo $doc_message; ?>

–PHP-alt-<?php echo $random_hash; ?>–

–PHP-mixed-<?php echo $random_hash; ?>
Content-Type: application/pdf; name="<?PHP echo $file_name; ?>"
Content-Transfer-Encoding: base64
Content-Disposition: attachment

<?php echo $attachment; ?>

–PHP-mixed-<?php echo $random_hash; ?>–

<?php //copy current buffer contents into $message variable and delete current output buffer $message = ob_get_clean(); //send the email $mail_sent = @mail( $to, $subject, $message, $headers ); //redirect user after success header("Location: index.php"); } ?>[/php]

Well, in that case, you should set up a routine that reads the .ext of the file so you know the filetype.
Then, you need to use the filetype to adjust the content depending on the extension that was found.
You would need to alter this line of your code:

Content-Type: application/pdf; name="<?PHP echo $file_name; ?>" Content-Transfer-Encoding: base64 Content-Disposition: attachment
I did a little more research on this. It seems that you can use code like this: [php] $filetype = $_FILES["uploads/" . $file_name . ]["type"]; [/php] This will grab the content type for you from the filename. ( Not tested, just off top of my head. ) Then, you can just store it inside the Content-Type: and you would not need to do any compares. If you do this, you should make sure that the file types are limited to just the types you want to allow to upload. Other filetypes can do damage to your server, such as .exe , .com , .vbs and others. You can limit the files they are allowed to upload by setting limits. Since this can not really be done inside of HTML, I will explain a bit. You can use as an example. This tells the browser to only allow those two image types. (You would need to enter all the ones you want to allow uploading) BUT, the user can say *.* and select others such as executeables. Therefore, you really need to use your PHP code to check the filetype and if not in your list of valid ones, throw out a validation error to the user that that file type is not allowed.

Hope that makes sense and helps… Out of town for a few days, so will check in when I get back to see
if you got it working… Good luck!

Hi ErnieAlex,

Sorry for the delay I’ve been working on other errors on my site, I’ve used your code but altered slightly as I kept receiving a blank page on running the script.

So far I am able to send an email with an attachment, the attachment is the correct file name and file type however it isnt the actual file from the uploads location… I can feel I am close to a solution.

Here’s my code;-
[php]<?php
if (isset($_POST[‘submit’]))
{
$file_name = $_POST[‘file_name’];
$doc_email = $_POST[‘doc_email’];
$doc_message = $_POST[‘doc_message’];
$filetype = $_POST[‘type’];

//define the receiver of the email
$to = $_POST[‘doc_email’];

//define the subject of the email
$subject = ‘Email with attachment’;

//create a boundary string. It must be unique
//so we use the MD5 algorithm to generate a random hash
$random_hash = md5(date(‘r’, time()));

//define the headers we want passed. Note that they are separated with \r\n
$headers = “From: [email protected]\r\nReply-To: [email protected]”;

//add boundary string and mime type specification
$headers .= “\r\nContent-Type: multipart/mixed; boundary=“PHP-mixed-”.$random_hash.”"";

//read the atachment file contents into a string,
//encode it with MIME base64,
//and split it into smaller chunks
$attachment = chunk_split(base64_encode(file_get_contents(‘uploads/$file_name’)));

//define the body of the message.
ob_start(); //Turn on output buffering
?>

–PHP-mixed-<?php echo $random_hash; ?>
Content-Type: multipart/alternative; boundary=“PHP-alt-<?php echo $random_hash; ?>”

–PHP-alt-<?php echo $random_hash; ?>
Content-Type: text/plain; charset=“iso-8859-1”
Content-Transfer-Encoding: 7bit

Hello World!!!
This is simple text email message.

User wrote:-

<?php echo $doc_message; ?>

–PHP-alt-<?php echo $random_hash; ?>
Content-Type: text/html; charset=“iso-8859-1”
Content-Transfer-Encoding: 7bit

Hi there

,

This is something with HTML formatting.

User wrote:-

<?php echo $doc_message; ?>

–PHP-alt-<?php echo $random_hash; ?>–

–PHP-mixed-<?php echo $random_hash; ?>
Content-Type: application/<?php echo $filetype; ?>; name="<?PHP echo $file_name; ?>"
Content-Transfer-Encoding: base64
Content-Disposition: attachment

<?php echo $attachment; ?>

–PHP-mixed-<?php echo $random_hash; ?>–

<?php //copy current buffer contents into $message variable and delete current output buffer $message = ob_get_clean(); //send the email $mail_sent = @mail( $to, $subject, $message, $headers ); //redirect user after success header("Location: index.php"); } ?>[/php]

Any thoughts?

Also ErnieAlex for some reason once the scrpt has run it does not re-direct to index.php anymore? I just get a blank screen and then the test email comes through? Weird

Dan,
On your line #63 you have
Content-Type: application/<?php echo $filetype; ?>; name="<?PHP echo $file_name; ?>"

As you seen you are telling the code that you are sending them an EXE or COM file. You are saying
that the content type is an application or in other words, a file that can be executed. What did you test
with, an executable file or a PDF or TXT file?

Did you look at the headers sent to you in the email and see what they are? I bet you will find you have a
bad content type something like “application/image/jpeg” if an picture was uploaded. You need to remove
the “application/” part from line #63.

Also, your code for finding the file type of a file will not work. The code I gave you:
$filetype = $_FILES[“uploads/” . $file_name . ][“type”];
will pull the file type from the file itself. The type of the file is inside the $_FILES array not the $_POST array!
When you use a input field of type “file”, all of the info on the file that is uploaded is stored inside the files
array, not the posted array. Therefore, your line at #7 ( $filetype = $_POST[‘type’]; ) will not pull the real
info for the filename. I suggest you use my line as it should get you the correct values.

How did you debug this? Try adding this in line #8 to debug what data was entered by the user…
[php]
echo "
file name: " . $file_name;
echo "
file type: " . $filetype;
echo “
file type from $_FILES: " . $_FILES[$file_name . ][“type”];
die(”
*** DONE ***);
[/php]
This will show the three lines of data and kill the page. Then, you can see first if the filename is correct.
And, if YOUR code shows the correct filetype and if my version shows the correct filetype. Run the page
uploading a JPEG, a TXT and a PDF file to see if the correct content type’s are pulled for each of those three.
If not figure out why. If so, use the correct version that is showing your target filetype for the email code.

Let us know if that works…

I actually dealt with this situation today, this will resolve the correct mime type:
OOP use.
[php]

<?php $fileName = "email.php"; $finfo = new finfo(FILEINFO_MIME_TYPE); echo $finfo->file($fileName); [/php]

Hi ErnieAlex,

Sorry I’ve just got back from holiday, thanks for your comments. I tried to echo the ‘file_name’, ‘filetype’ but all that displayed was the ‘file_name’ - I used [php]$filetype = $_FILES["/uploads/’.$file_name.’"][“type”];[/php] but it hasn’t done the trick, could I be pointing to the wrong url? the uploads folder is within the same directory as index.php, mailer.php etc

Again just to refresh the email sends through with the message and an attachment (pdf format) which is labelled as the file I want to send but its a blank file.

Also when the script runs it goes to a blank page (even through the script has worked), it should re-direct after - this is equally frustrating as the above!

thanks for your help

Well, Dan, step one is to solve why you are not showing your filetype. You can’t send out an attachment
if it is not set up correctly. It will send the attachment, but, the other end (email client) will not know what
to do with it.

So, one issue might be the file itself. Are you sure that you moved the file to the “uploads” folder when
the user submits a file? Perhaps the file is not really there. To debug that part, upload a file so you know
the exact name of it. Then, look at your server inside the “uploads” folder and see if your file is actually
there. If not, fix your upload sections. If there, let us know… (If not there, it isn’t this code in error!)

Let us know…

Dan, also… I was just thinking about your system. You should make sure that the file is marked somehow
to not allow dups. If two people upload the same named file, one will overwrite the other. Just a thought!

Hi ErnieAlex,

I’ve just double checked to see if the file exists on my server and it does, I can view it through a web browser… I may have spotted something though, the url for the file is as follows;-

http://www.example.com/fms/documents/uploads/_375538354.pdf

The index.php, mailer.php are all located in the ‘documents’ directory - does my current code mean I am trying to point it to;- http://www.example.com/uploads/_375538354.pdf instead? Obviously the file doesn’t exist here.

thanks

Good, we found the issue… So, yes, you have to steer your code to the correct folder.

Just alter the pointer to the correct location. You just told me originally that it was in “uploads” folder, so
of course, I assumed that folder was in your root folder and I used it in our discussions…

Now, remember that the line echo "
file type from $_FILES: " . $_FILES[$file_name . ][“type”];
that I suggested to use for displaying the filetype was after you posted an upload. It takes the filename
and file info such as filetype from the $_FILES[] array that is posted to your code. This has nothing to do
with the live code that is looking into the wrong place.

SO, yes, fix where the code points at the uploads folder and I think you might have solved it.

Good luck, let us know…

Hi ErnieAlex,

I’m trying to debug and sort my code, I’ve attempted to echo all the values to check them;-

This is my code;-
[php]<?php
if (isset($_POST[‘submit’]))
{
$file_name = $_POST[‘file_name’];
$doc_email = $_POST[‘doc_email’];
$server_name = $_SERVER[‘SERVER_NAME’];
$doc_message = $_POST[‘doc_message’];
$filetype = $_FILES[‘http://$server_name/fms/documents/uploads/$file_name’][‘type’];
$username = $_POST[‘username’];
$company = $_POST[‘company’];
}
?>

<?php echo $file_name; ?>
<?php echo $filetype; ?>
<?php echo "
file type from $_FILES: " . $_FILES[$file_name . ]["type"]; ?>
<?php echo $doc_email; ?>
<?php echo $doc_message; ?>
<?php echo $username; ?>
<?php echo $company; ?>
<?php echo "http://$server_name/fms/documents/uploads/$file_name"; ?>[/php]

It successfully returns the file name, message, email, username and company but not the file type, I know I am close but can you help and put me out of my misery please?

Also when I enter your line of code [php]<?php echo "
file type from $_FILES: " . $_FILES[$file_name . ]["type"]; ?>


[/php] it does not work and I get a blank page??

That is a lot of code to echo something:

[php]
if ( isset ( $_POST ) ){
foreach( $_POST as $k => $v ) {
echo “$k : $v
”;
}
}[/php]

That snippet works for any global array, $_GET, $_POST, $_FILE.

This is wrong, should be:
[php] $_FILES: " . $_FILES[“the value in the name field”][“type”][/php] The filename is a value, not a key in the array. It also fails because you have a trailing period after the variable.

Thanks Astonecipher, I will bear in mind your code. I was just debugging mine and wont be keeping it long term.

I’ve changed my code to [php]<?php echo " $_FILES: " . $_FILES["file_name"]["type"] ; ?>[/php] The input box on my form has name=“file_name” . The above code just returns " Array: "? Can you tell me where am I going wrong please?

Sponsor our Newsletter | Privacy Policy | Terms of Service