Jump to content

Allow ability to NOT attach file in PHP mail form


spastickyle

Recommended Posts

I am trying to create a simple mail form with multiple attachments for our HR department. When I choose not to attach a file, or in the case of allowing multiple attachments, not attaching a second file, I get the following error. I'm assuming that the foreach is looking for the file extension and seeing null in the array (hense the blank when displaying the $ext in the error message when die is called). The HR department wants to have multiple attachments in case an applicant wants to submit a cover letter and resume. But my code so far won't allow an applicant to submit a resume without a cover letter. 

Notice: Undefined index: extension in C:\inetpub\wwwroot\MultipleEmailAttachments.php on line 18 File has the extensions which is not allowed

 

 

I'm not a proficient PHP programmer, but I want to expand my knowledge. How can I prevent null values (in this case, no file attachment) from adding to the array? 

 

Thanks in advance.

 

Here's the php code:

<?php


 error_reporting(E_ALL);
 ini_set('display_errors', 1);
 ini_set("SMTP","123.456.789.123");
 ini_set("smtp_port","25");


if(isset($_FILES) && (bool) $_FILES) {
  
     $allowedExtensions = array("pdf","doc","docx","gif","jpeg","jpg","png","rtf","txt");


     $files = array();
     foreach($_FILES as $name=>$file) {
        $file_name = $file['name']; 
        $temp_name = $file['tmp_name'];
        $file_type = $file['type'];
        $path_parts = pathinfo($file_name);
        $ext = $path_parts['extension'];
        if(!in_array($ext,$allowedExtensions)) {
           die("File $file_name has the extensions $ext which is not allowed");
        }
        array_push($files,$file);
     }


     // email fields: to, from, subject, and so on
     $to = "mail@example.com";
     $from = "webmaster@example.com"; 
     $subject ="test attachment"; 
     $message = "this is a simple test message";
     $headers = "From: $from";


     // boundary 
     $semi_rand = md5(time()); 
     $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x"; 


     // headers for attachment 
     $headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . " boundary=\"{$mime_boundary}\""; 


     // multipart boundary 
     $message = "This is a multi-part message in MIME format.\n\n" . "--{$mime_boundary}\n" . "Content-Type: text/plain; charset=\"iso-8859-1\"\n" . "Content-Transfer-Encoding: 7bit\n\n" . $message . "\n\n"; 
     $message .= "--{$mime_boundary}\n";


     // preparing attachments
     for($x=0;$x<count($files);$x++){
        $file = fopen($files[$x]['tmp_name'],"rb");
        $data = fread($file,filesize($files[$x]['tmp_name']));
        fclose($file);
        $data = chunk_split(base64_encode($data));
        $name = $files[$x]['name'];
        $message .= "Content-Type: {\"application/octet-stream\"};\n" . " name=\"$name\"\n" . 
        "Content-Disposition: attachment;\n" . " filename=\"$name\"\n" . 
        "Content-Transfer-Encoding: base64\n\n" . $data . "\n\n";
        $message .= "--{$mime_boundary}\n";
     }
     // send

     $ok = mail($to, $subject, $message, $headers); 
     if ($ok) { 
        echo "<p>mail sent to $to!</p>"; 
     } else { 
        echo "<p>mail could not be sent!</p>"; 
     } 
} 

?>

<html>
<body>
<form method="post" action="MultipleEmailAttachments.php" enctype="multipart/form-data">
<input type="file" name="attach1"/>
<input type="file" name="attach2"/>
<input type="submit" value="submit"/>
</form>
</body>
</html>

 

 

 
 

 

 

Edited by spastickyle
Link to comment
Share on other sites

Hi spastickyle,

 

While not a direct answer, the following will show you what the problem is.  I typically start off with print_r() and the pre tags as I showed unless I am working with json in which I don't use the pre tags.  Sometimes, you want more information, and should use var_dump() instead of print_r().

 

Try this, and display what it prints out.

     $files = array();
     echo('<pre>'.print_r($_FILES,1).'</pre>');
     foreach($_FILES as $name=>$file) {
        $file_name = $file['name'];
        $temp_name = $file['tmp_name'];
        $file_type = $file['type'];
        $path_parts = pathinfo($file_name);
        echo('<pre>'.print_r($path_parts,1).'</pre>');
        $ext = $path_parts['extension'];
        if(!in_array($ext,$allowedExtensions)) {
           die("File $file_name has the extensions $ext which is not allowed");
        }
        array_push($files,$file);
     }

 

Link to comment
Share on other sites

you should use an array name for the form field, with the array index being a unique name if you need to identify which field a file was selected for. if you leave the index value out, you will get integer indexes, starting at 0.

next, you MUST test if a file was successfully uploaded before you can reference any of the file information. if a file wasn't selected, the ['error'] element of the uploaded file information will be - 
 

UPLOAD_ERR_NO_FILE

Value: 4; No file was uploaded.


the ['error'] element will be - UPLOAD_ERR_OK if the file was successfully uploaded. see example #3 at this link - http://php.net/manual/en/features.file-upload.post-method.php for how you can define the form field and loop over the file information.

Link to comment
Share on other sites

 

Hi spastickyle,

 

While not a direct answer, the following will show you what the problem is.  I typically start off with print_r() and the pre tags as I showed unless I am working with json in which I don't use the pre tags.  Sometimes, you want more information, and should use var_dump() instead of print_r().

 

Try this, and display what it prints out.

     $files = array();
     echo('<pre>'.print_r($_FILES,1).'</pre>');
     foreach($_FILES as $name=>$file) {
        $file_name = $file['name'];
        $temp_name = $file['tmp_name'];
        $file_type = $file['type'];
        $path_parts = pathinfo($file_name);
        echo('<pre>'.print_r($path_parts,1).'</pre>');
        $ext = $path_parts['extension'];
        if(!in_array($ext,$allowedExtensions)) {
           die("File $file_name has the extensions $ext which is not allowed");
        }
        array_push($files,$file);
     }

Thanks for the suggestion. I got the following output which confirms what I suspected. null is in the array and null is not one of the accepted files. Which got me to test a rather dirty fix. I added "" to $allowedExtensions and now it works when I choose not to attach a file. The obvious issue with this is malicious files with no extensions. 

 

Array

(

[attach1] => Array

(

[name] =>

[type] =>

[tmp_name] =>

[error] => 4

=> 0

)

 

)

Notice: Undefined index: extension in C:\inetpub\wwwroot\jobcontactmail.php on line 19 File has the extensions which is not allowed

 

Link to comment
Share on other sites

you should use an array name for the form field, with the array index being a unique name if you need to identify which field a file was selected for. if you leave the index value out, you will get integer indexes, starting at 0.

 

next, you MUST test if a file was successfully uploaded before you can reference any of the file information. if a file wasn't selected, the ['error'] element of the uploaded file information will be - 

 

the ['error'] element will be - UPLOAD_ERR_OK if the file was successfully uploaded. see example #3 at this link - http://php.net/manual/en/features.file-upload.post-method.php for how you can define the form field and loop over the file information.

 

Thanks Mac_gyver. The code in example 3 requires an upload path which I'm trying to avoid. My reasoning may seem frivolous but I want this to be as idiot proof as possible and directory structures and permissions seem like another element for my client to screw up. 

Link to comment
Share on other sites

Looks like your form name was "attach1", however, something is wrong with your form as you received error 4 (UPLOAD_ERR_NO_FILE)

 

Yes, that's correct. When i attach a file, it worked great, no problems. But when i choose to not attach a file, I get the error. I want the ability to submit my contact information without having to attach a file if I don't have one. Attach1 is the name of the first attachment input. There is UPLOAD_ERR_NO_FILE because there is no file by choice. 

Edited by spastickyle
Link to comment
Share on other sites

 

the ['error'] element will be - UPLOAD_ERR_OK if the file was successfully uploaded. see example #3 at this link - http://php.net/manual/en/features.file-upload.post-method.php for how you can define the form field and loop over the file information.

 

Thanks Mac_gyver. The code in example 3 requires an upload path which I'm trying to avoid. My reasoning may seem frivolous but I want this to be as idiot proof as possible and directory structures and permissions seem like another element for my client to screw up. 

 

it requires nothing. it's just a dang example and this stuff is called software for a reason. if it doesn't do what you want, you can change it so that it does.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.