spastickyle Posted October 27, 2016 Share Posted October 27, 2016 (edited) 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 October 27, 2016 by spastickyle Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted October 27, 2016 Share Posted October 27, 2016 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); } Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted October 27, 2016 Share Posted October 27, 2016 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_FILEValue: 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. Quote Link to comment Share on other sites More sharing options...
spastickyle Posted October 27, 2016 Author Share Posted October 27, 2016 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 Quote Link to comment Share on other sites More sharing options...
spastickyle Posted October 27, 2016 Author Share Posted October 27, 2016 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. Quote Link to comment Share on other sites More sharing options...
NotionCommotion Posted October 27, 2016 Share Posted October 27, 2016 Looks like your form name was "attach1", however, something is wrong with your form as you received error 4 (UPLOAD_ERR_NO_FILE) Quote Link to comment Share on other sites More sharing options...
spastickyle Posted October 27, 2016 Author Share Posted October 27, 2016 (edited) 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 October 27, 2016 by spastickyle Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted October 27, 2016 Share Posted October 27, 2016 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.