0

I'm working on file attachment here. The mail function is working fine other than the file field is empty. I have tried using Content-Type: multipart/mixed and some other methods but unable to achieve the desired output. I have searched for a different answer and tried but am still facing the same issue. There seems to be a duplicate but I had tried all methods can anyone guide me the right direction as per my script what i missing here. How can I get the file attachment? Can anyone suggest me in the right direction what I'm missing here why other fields are not coming if I remove file attachment code then other fields are working fine and mail has come. HTML

<form class="test" action="contactMail.php" method="POST">
  <input type="hidden" name="formname" value="Form sent by About page">
  <select class="user-select">
    <option value="">Pick Job Role</option>
    <option>Web Developer</option>
    <option>Java Developer</option>
  </select>
  <input type="text" name="name" placeholder="Your Name">
  <input type="tel" name="phone" placeholder="Contact Number">
  <label for="file-upload" class="file-upload">Upload Image</label>
  <input type="file" id="file-upload" name="upload" required>
  <textarea name="message" placeholder="Your Message" rows="3">/textarea>
            <button type="submit" class="from-submit form-group form-fields">Submit</button>
    <div id="success_contact">                                               
        <h2>Request Sent!</h2>
    </div>
</form>
   `<?php
// Receiver mail id 
$mail_to = 'yourmail@gmail.com';

// Mail Subject 
$subject = 'Virtual Raasta';

$upload = $_FILES["upload"];
$path = 'assets/file';
$filename = 'myfile';

if ($_SERVER["REQUEST_METHOD"] == "POST") {

    if ( isset($_POST['name']) ) {
        $name = $_POST['name'];
    }

    if (isset($_POST['phone'])) {
        $phone = $_POST['phone'];
    }

    if (isset($_POST['company'])) {
        $company = $_POST['company'];
    }

    if(isset($_POST['message'])) {
        $message = $_POST['message'];
    }
    if(isset($_POST['industry'])) {
        $industry = $_POST['industry'];
    }
    if(isset($_POST['job'])) {
        $job = $_POST['job'];
    }
    if(isset($_FILES['upload'])) {
        $upload = $_FILES['upload'];
    }

    $reqBy = $_POST['formname'];

    // Message body

    $msg = '<html><body><p>';

    $msg .= '<b> Request Sent From : </b>' . $reqBy . '<br/>';

    $msg .= '<b> Name : </b>' . $name . '<br/>';

    if($_POST["phone"] != "") {
       $msg .= '<b> Phone : </b>' . $phone . '<br/>';
    }

    if($_POST["company"] != "") {
       $msg .= '<b> Company : </b>' . $company . '<br/>';
    }

    if($_POST["message"] != "") {
        $msg .= '<b> Message : </b>' . $message . '<br/>';
    }

    if($_POST["industry"] != "") {
        $msg .= '<b> Industry : </b>' . $industry . '<br/>';
    }

    if($_POST["job"] != "") {
        $msg .= '<b> Job Role : </b>' . $job . '<br/>';
    }

    if($_FILES["upload"] != "") {
        $msg .= '<b> Upload : </b>' . $upload . '<br/>';
    }

    $msg .= '</p>';
    $msg .= '</body></html>';
    var_dump($msg);

    $filename = $_FILES["upload"]["name"];
    //$content = file_get_contents( $_FILES['upload']['tmp_name'] );

    if(!empty($_FILES['upload']['tmp_name']) && file_exists($_FILES['upload']['tmp_name'])) {
        $content= addslashes(file_get_contents($_FILES['upload']['tmp_name']));
    }
    $content = chunk_split(base64_encode($content));
    $uid = md5(uniqid(time()));


    $replyto = 'test';
    $headers = "From: ".$subject." <".'yourmail@gmail.com'.">\r\n";
    $headers .= "Reply-To: ".$replyto."\r\n";
    $headers .= "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";

    $msg = "--".$uid."\r\n";
    $msg .= "Content-type:text/plain; charset=iso-8859-1\r\n";
    $msg .= "Content-Transfer-Encoding: 7bit\r\n\r\n";
    $msg .= $msg."\r\n\r\n";
    $msg .= "--".$uid."\r\n";
    $msg .= "Content-Type: application/octet-stream; name=\"".$filename."\"\r\n";
    $msg .= "Content-Transfer-Encoding: base64\r\n";
    $msg .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
    $msg .= $content."\r\n\r\n";
    $msg .= "--".$uid."--";

    if( mail( $mail_to, $subject, $msg, $headers )) {
        echo "Thank You!";
    } else {
        die("Error!");
    }
   }

 ?>`
Ususipse
  • 303
  • 1
  • 9
Husna
  • 1,286
  • 4
  • 19
  • 48
  • See [How can I get useful error messages in PHP?](//stackoverflow.com/q/845021) to get something answerable instead of "not working". And [Send attachments with PHP Mail()?](//stackoverflow.com/q/12301358) for a more robust approach. – mario Sep 27 '19 at 06:51
  • @mario thanks for the reply. I had already on debugged mode true. – Husna Sep 27 '19 at 06:57
  • @Husna, file won't show in `$_POST`, you need to use `$_FILES` – Pragnesh Chauhan Sep 28 '19 at 06:56
  • @PragneshChauhan Thanks for your reply. I changed to $_FILES still only file is coming in the mail, not other fields. – Husna Sep 28 '19 at 06:57
  • Can you repost your code with new changes?, I think you have changed all `$_POST` to `$_FILES`, you just have to use `$_POST["upload"]` to `$_FILES['upload']` – Pragnesh Chauhan Sep 28 '19 at 07:02
  • @PragneshChauhan I updated my code can you please check now. – Husna Sep 28 '19 at 07:20
  • Is Your message really `7bit` encoded, try to change to `Content-Transfer-Encoding: 8bit`. For some further information: https://stackoverflow.com/questions/25710599/content-transfer-encoding-7bit-or-8-bit – ivion Sep 30 '19 at 12:13
  • @ivion Its is Base64 bit the above written same code I'm using. – Husna Sep 30 '19 at 12:25
  • By the way You are using the var `$msg` in two way. As Html part and as part of the message body. Your are initialising $msg as html, so it is 8-bit. The attachment is bas64. – ivion Sep 30 '19 at 12:37
  • @ivion okay. Can you please suggest what I have to change here I don't have more knowledge in php just start learning php. – Husna Sep 30 '19 at 12:43
  • To be honest, you should not continue on this topic. Your approach bad for security reasons: if you pick data directly from $_POST and use within content of an email etc. There a lot of lessons to be done ahead of you. Youre approaching your task badly, also your question does not provide [minimal example](https://stackoverflow.com/help/minimal-reproducible-example) to be asked swiftly – yergo Oct 03 '19 at 15:06
  • @yergo Thanks for suggesting I will learn more lessons about this topic. – Husna Oct 04 '19 at 05:06

4 Answers4

1

I hope it is just a typo. You are using the var $msg twice. Once for Your html-message and for the body of the message.

<?php

....

    // Message body

    $msg = '<html><body><p>';

    $msg .= '<b> Request Sent From : </b>' . $reqBy . '<br/>';

    $msg .= '<b> Name : </b>' . $name . '<br/>';

    if($_POST["phone"] != "") {
       $msg .= '<b> Phone : </b>' . $phone . '<br/>';
    }

    if($_POST["company"] != "") {
       $msg .= '<b> Company : </b>' . $company . '<br/>';
    }

    if($_POST["message"] != "") {
        $msg .= '<b> Message : </b>' . $message . '<br/>';
    }

    if($_POST["industry"] != "") {
        $msg .= '<b> Industry : </b>' . $industry . '<br/>';
    }

    if($_POST["job"] != "") {
        $msg .= '<b> Job Role : </b>' . $job . '<br/>';
    }

    if($_FILES["upload"] != "") {
        $msg .= '<b> Upload : </b>' . $upload . '<br/>';
    }

    $msg .= '</p>';
    $msg .= '</body></html>';
    var_dump($msg);

    $filename = $_FILES["upload"]["name"];
    //$content = file_get_contents( $_FILES['upload']['tmp_name'] );

    if(!empty($_FILES['upload']['tmp_name']) && file_exists($_FILES['upload']['tmp_name'])) {
        $content= file_get_contents($_FILES['upload']['tmp_name']); // No add_slashes()
    }
    $content = chunk_split(base64_encode($content));
    $uid = md5(uniqid(time()));


    $replyto = 'test';
    $headers = "From: ".$subject." <".'yourmail@gmail.com'.">\r\n";
    $headers .= "Reply-To: ".$replyto."\r\n";
    $headers .= "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: multipart/mixed; boundary=\"".$uid."\"\r\n\r\n";

Rename the var here and change Content-type and transfer-encoding as well:

    $msgBody = "--".$uid."\r\n";
    $msgBody .= "Content-type:text/html; charset=iso-8859-1\r\n";
    $msgBody .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
    $msgBody .= $msg."\r\n\r\n";

    if(isset($_Files['upload'])) // Only add attachment if uploaded
         $msgBody .= "--".$uid."\r\n";
         $msgBody .= "Content-Type: ".mime_content_type ( $_FILES['upload']['tmp_name'] )."; name=\"".$filename."\"\r\n";
         $msgBody .= "Content-Transfer-Encoding: base64\r\n";
         $msgBody .= "Content-Disposition: attachment; filename=\"".$filename."\"\r\n\r\n";
         $msgBody .= $content."\r\n\r\n";
    }
    $msgBody .= "--".$uid."--";

    if( mail( $mail_to, $subject, $msgBody, $headers )) {
        echo "Thank You!";
    } else {
        die("Error!");
    }
   }

 ?>
ivion
  • 567
  • 1
  • 9
  • 14
  • yeah, i tried file is coming and fields also but the fields are coming with the html tags like

    Name here

    why this happen what is not working here. And when I downloaded the file type is file and an empty file is coming.

    – Husna Oct 01 '19 at 05:27
  • Did You remove the `AddSlashes()` from `file_get_contents()`? Try to add a space in `Content-Type: text/html`. – ivion Oct 01 '19 at 06:30
  • Your filename is always myfile. Try `$filename = $_FILES["upload"]["name"];` – ivion Oct 01 '19 at 06:36
  • yeah. I got it :) And now why the empty file is coming I upload pdf file with some content but when I download file type is file and the file is empty. – Husna Oct 01 '19 at 06:37
  • Try `"Content-Type: ".mime_content_type ( $_FILES['upload']['tmp_name'] )."; name=\"".$filename."\"\r\n";` in Your attachment. – ivion Oct 01 '19 at 06:41
  • After add this `$msgBody .= "Content-Type: ".mime_content_type ( $_FILES['upload']['tmp_name'] )."; name=\"".$filename."\"\r\n";` i'm getting trhis error `mime_content_type(): Can only process string or stream arguments` – Husna Oct 01 '19 at 06:56
  • Did You upload a File. I edited the answer to check if file uploaded. – ivion Oct 01 '19 at 07:11
  • Yes file upload and getting mail also. when i downloaded the file and open inside file this content is coming `Content-Type: ; name=""` – Husna Oct 01 '19 at 07:13
  • Did the attachment work? Is it presented as the correct file type? – ivion Oct 01 '19 at 07:26
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/200220/discussion-between-ivion-and-husna). – ivion Oct 01 '19 at 07:35
0

To better handle emails with PHP you can use this library:

https://github.com/PHPMailer/PHPMailer

There is also the availability to make the minimal installation:

At the very least you will need src/PHPMailer.php. If you're using SMTP, you'll need src/SMTP.php, and if you're using POP-before SMTP, you'll need src/POP3.php.

user2342558
  • 5,567
  • 5
  • 33
  • 54
  • Yeah but I don't want to use PHPMailer using php send mail I want to do because due to some client requirement. – Husna Sep 27 '19 at 07:36
  • @Husna Please do understand that sending mail on your own can be easily flagged as spam by most email clients. Using an option like the one mentioned above or a 3rd-party like SendGrid would solve this issue. – Chris Oct 06 '19 at 13:14
0

update your form opening tag with

<form class="test" action="contactMail.php" method="POST" enctype="multipart/form-data">

add below code before starting for if condition

if ($_FILES['upload']['error'] == 0) {
   $filename = $_FILES["upload"]["name"];
   $content = file_get_contents( $_FILES['upload']['tmp_name'] );
   $content = chunk_split(base64_encode($content));
   $uid = md5(uniqid(time()));
}
Pragnesh Chauhan
  • 8,363
  • 9
  • 42
  • 53
0

There are several issues here. The primary issue is that this code is a security nightmare and should never be deployed anywhere.

The second issue is checking if your arguments are populated before trying to use them to instantiate other variables. When you assign $upload and then make a check for $_POST data and only then see if the $_POST argument was even set in the first place, it suggests you need to re-read the isset() documentation and even the fundamentals of conditional statements.

Ususipse
  • 303
  • 1
  • 9