Hello

I am completely new to PHP, but have an email form script which work fine:

<?php

// User settings
$to = "my_email@yahoo.com";
$subject = "Proofreading Contact Form";

// Include extra form fields and/or submitter data?
// false = do not include
$extra = array(
	"form_subject"	=> true,
	"form_cc"		=> true,
	"ip"				=> true,
	"user_agent"	=> true
);

// Process
$action = isset($_POST["action"]) ? $_POST["action"] : "";
if (empty($action)) {
	// Send back the contact form HTML
	$output = "<div style='display:none'>
	<div class='contact-top'></div>
	<div class='contact-content'>
		<h1 class='contact-title'>Send us a message:</h1>
		<div class='contact-loading' style='display:none'></div>
		<div class='contact-message' style='display:none'></div>
		<form action='#' style='display:none'>
			<label for='contact-name'>*Name:</label>
			<input type='text' id='contact-name' class='contact-input' name='name' tabindex='1001' />
			<label for='contact-email'>*Email:</label>
			<input type='text' id='contact-email' class='contact-input' name='email' tabindex='1002' />";

if ($extra["form_subject"]) {
	$output .= "
		<label for='contact-subject'>Subject:</label>
		<input type='text' id='contact-subject' class='contact-input' name='subject' value='' tabindex='1003' />";
}

$output .= "
		<label for='contact-message'>*Message:</label>
		<textarea id='contact-message' class='contact-input' name='message' cols='40' rows='4' tabindex='1004'></textarea>
		<br/>";

if ($extra["form_cc"]) {
	$output .= "
		<label>&nbsp;</label>
		<input type='checkbox' id='contact-cc' name='cc' value='1' tabindex='1005' /> <span class='contact-cc'>Send me a copy</span>
		<br/>";
}

$output .= "
		<label>&nbsp;</label>
		<button type='submit' class='contact-send contact-button' tabindex='1006'>Send</button>
		<button type='submit' class='contact-cancel contact-button simplemodal-close' tabindex='1007'>Cancel</button>
		<br/>
		<input type='hidden' name='token' value='" . smcf_token($to) . "'/>
	</form>
</div>
</div>";

echo $output;
}
else if ($action == "send") {
	// Send the email
	$name = isset($_POST["name"]) ? $_POST["name"] : "";
	$email = isset($_POST["email"]) ? $_POST["email"] : "";
	$subject = isset($_POST["subject"]) ? $_POST["subject"] : $subject;
	$message = isset($_POST["message"]) ? $_POST["message"] : "";
	$cc = isset($_POST["cc"]) ? $_POST["cc"] : "";
	$token = isset($_POST["token"]) ? $_POST["token"] : "";

// make sure the token matches
if ($token === smcf_token($to)) {
	smcf_send($name, $email, $subject, $message, $cc);
	echo "Your message was successfully sent.";
}
else {
	echo "Unfortunately, your message could not be verified.";
}
}

function smcf_token($s) {
	return md5("smcf-" . $s . date("WY"));
}

// Validate and send email
function smcf_send($name, $email, $subject, $message, $cc) {
	global $to, $extra;

// Filter and validate fields
$name = smcf_filter($name);
$subject = smcf_filter($subject);
$email = smcf_filter($email);
if (!smcf_validate_email($email)) {
	$subject .= " - invalid email";
	$message .= "\n\nBad email: $email";
	$email = $to;
	$cc = 0; // do not CC "sender"
}

// Add additional info to the message
if ($extra["ip"]) {
	$message .= "\n\nIP: " . $_SERVER["REMOTE_ADDR"];
}
if ($extra["user_agent"]) {
	$message .= "\n\nUSER AGENT: " . $_SERVER["HTTP_USER_AGENT"];
}

// Set and wordwrap message body
$body = "From: $name\n\n";
$body .= "Message: $message";
$body = wordwrap($body, 70);

// Build header
$headers = "From: $email\n";
if ($cc == 1) {
	$headers .= "Cc: $email\n";
}
$headers .= "X-Mailer: PHP/SimpleModalContactForm";

// UTF-8
if (function_exists('mb_encode_mimeheader')) {
	$subject = mb_encode_mimeheader($subject, "UTF-8", "B", "\n");
}
else {
	// you need to enable mb_encode_mimeheader or risk 
	// getting emails that are not UTF-8 encoded
}
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-type: text/plain; charset=utf-8\n";
$headers .= "Content-Transfer-Encoding: quoted-printable\n";

// Send email
@mail($to, $subject, $body, $headers) or 
	die("Unfortunately, a server issue prevented delivery of your message.");
}

// Remove any un-safe values to prevent email injection
function smcf_filter($value) {
	$pattern = array("/\n/","/\r/","/content-type:/i","/to:/i", "/from:/i", "/cc:/i");
	$value = preg_replace($pattern, "", $value);
	return $value;
}

// Validate email address format in case client-side validation "fails"
function smcf_validate_email($email) {
	$at = strrpos($email, "@");

// Make sure the at (@) sybmol exists and  
// it is not the first or last character
if ($at && ($at < 1 || ($at + 1) == strlen($email)))
	return false;

// Make sure there aren't multiple periods together
if (preg_match("/(\.{2,})/", $email))
	return false;

// Break up the local and domain portions
$local = substr($email, 0, $at);
$domain = substr($email, $at + 1);


// Check lengths
$locLen = strlen($local);
$domLen = strlen($domain);
if ($locLen < 1 || $locLen > 64 || $domLen < 4 || $domLen > 255)
	return false;

// Make sure local and domain don't start with or end with a period
if (preg_match("/(^\.|\.$)/", $local) || preg_match("/(^\.|\.$)/", $domain))
	return false;

// Check for quoted-string addresses
// Since almost anything is allowed in a quoted-string address,
// we're just going to let them go through
if (!preg_match('/^"(.+)"$/', $local)) {
	// It's a dot-string address...check for valid characters
	if (!preg_match('/^[-a-zA-Z0-9!#$%*\/?|^{}`~&\'+=_\.]*$/', $local))
		return false;
}

// Make sure domain contains only valid characters and at least one period
if (!preg_match("/^[-a-zA-Z0-9\.]*$/", $domain) || !strpos($domain, "."))
	return false;	

return true;
}

exit;

?>

What I would like to do now is add another field to my form called 'attachments' (for Word docs and images), but what changes would I need to make please to the actually PHP script?

Many thanks for any advice.

Steve

    Assuming you know how to code the HTML for a file upload, you can handle the upload with a single statement:

    // Variables for convenience...
    $path = "/where/to/put/file";
    $file_name = $_FILES["file"]["name"];
    $temp_file = $_FILES["file"]["tmp_name"];
    
    // The single statement...
    move_uploaded_file($temp_file, $path.$file_name);

    This takes the uploaded file and moves it to a permanent location. Remember that any file you don't move out of the temporary upload folder gets deleted automatically after the next page loads.

    Of course, there's some validation you should be doing as well. For example, make sure the file was actually uploaded:

    if(isset($_FILES["file"]) && file_exists($_FILES["file"]["tmp_name"])) {...

    Make sure the file is within a certain size limit:

    $limit = 20000000;  // (2 MB limit)
    if($_FILES["file"]["size"] < $limit) {...

    Check to see if the file move was successful:

    if(file_exists($path.$file_name)) {...

    And of course, you may want to limit which file types people can upload, which means detecting the mime-type of the file. How you do that may depend on your PHP version.

      Hello ixalmida

      Many thanks for your post and comprehensive reply!! It will take me some time to get my head round that!

      I get an 'error on page' message at the bottom of the screen if I just copy and paste your additions to what I have - possible because I haven't chaged the form itself yet.

      I'll try that now.

      Thanks again.

      Steve

        Don't forget also that your form "enctype" has to change and a "file" input:

        <form enctype="multipart/form-data" name="myform" action="processing_page.php">
          <input name="file" type="file" />
        </form>

        In my example above, the $FILE array contained the name "file" because that was the name of my input box in my form. If your file box was called "file1", then on the processing page, you'd refer to the array, $FILE["file1"]. You can allow multiple file uploads on a page using different input names, i.e. - "file1", "file2", "file3", etc.

        If you have a dynamic number of files to upload, you could also use an array:

        <input name="files[]" type="file" />

        Then you'd want to find out how many files were actually uploaded so you can cycle through and move them:

        $num_files = count($_FILE["files"]);
        for($x = 0; $x < $num_files; $x++)
          move_uploaded_file($_FILE["files"][$x], $path.$name);

          Hello ixalmida

          Thanks again for your very comprehensive post - I'm still trying to come to terms with your script!

          This is what I have so far:

          <?php
          
          // User settings
          $to = "myEmail@wherever.com";
          $subject = "Proofreading Contact Form";
          
          // Include extra form fields and/or submitter data?
          // false = do not include
          $extra = array(
          "form_subject"	=> true,
          "form_cc"		=> true,
          [B]"form_attachment" => true,[/B] [B]<--Added this[/B]
          "ip"	               	=> true,
          "user_agent"	=> true
          );
          
          // Process
          $action = isset($_POST["action"]) ? $_POST["action"] : "";
          if (empty($action)) {
          	// Send back the contact form HTML
          	$output = "<div style='display:none'>
          	<div class='contact-top'></div>
          	<div class='contact-content'>
          		<h1 class='contact-title'>Send us a message:</h1>
          		<div class='contact-loading' style='display:none'></div>
          		<div class='contact-message' style='display:none'></div>
          
          
          <form action='#' style='display:none'>
          			<label for='contact-name'>Name:</label>
          			<input type='text' id='contact-name' class='contact-input' name='name' tabindex='1001' />
          			<label for='contact-email'>Email:</label>
          			<input type='text' id='contact-email' class='contact-input' name='email' tabindex='1002' />";
          
          if ($extra["form_subject"]) {
          	$output .= "
          		<label for='contact-subject'>Subject:</label>
          		<input type='text' id='contact-subject' class='contact-input' name='subject' value='' tabindex='1003' />";
          }
          
          $output .= "
          		<label for='contact-message'>Message:</label>
          		<textarea id='contact-message' class='contact-input' name='message' cols='40' rows='4' tabindex='1004'></textarea>
          		<br/>";
          
          
          [B]if ($extra["form_attachment"]) {
          $output .= "
           <label for='contact-email'>Attachment:</label>
          <input type='text' id='contact-attachment' class='contact-input' name='attachment' tabindex='1001' />";
          }[/B] [B]<--Added this,/B]
          
          
          
          if ($extra["form_cc"]) {
          	$output .= "
          		<label>&nbsp;</label>
          		<input type='checkbox' id='contact-cc' name='cc' value='1' tabindex='1005' /> <span class='contact-cc'>Send me a copy</span>
          		<br/>";
          }
          
          $output .= "
          		<label>&nbsp;</label>
          		<button type='submit' class='contact-send contact-button' tabindex='1006'>Send</button>
          		<button type='submit' class='contact-cancel contact-button simplemodal-close' tabindex='1007'>Cancel</button>
          		<br/>
          		<input type='hidden' name='token' value='" . smcf_token($to) . "'/>
          	</form>
          
          
          </div>
          	</div>";
          
          echo $output;
          }
          else if ($action == "send") {
          	// Send the email
          	$name = isset($_POST["name"]) ? $_POST["name"] : "";
          	$email = isset($_POST["email"]) ? $_POST["email"] : "";
          	$subject = isset($_POST["subject"]) ? $_POST["subject"] : $subject;
          	$message = isset($_POST["message"]) ? $_POST["message"] : "";
          	$cc = isset($_POST["cc"]) ? $_POST["cc"] : "";
          	$token = isset($_POST["token"]) ? $_POST["token"] : "";
          
          // make sure the token matches
          if ($token === smcf_token($to)) {
          	smcf_send($name, $email, $subject, $message, $cc);
          	echo "Your message was successfully sent.";
          }
          else {
          	echo "Unfortunately, your message could not be verified.";
          }
          }
          
          function smcf_token($s) {
          	return md5("smcf-" . $s . date("WY"));
          }
          
          ?>

          I get a yellow error message in the bottom left hand corner of my screen - can you see anything in bold that should not be there?

          Thanks.

          Steve

            I don't see where you are moving or getting the contents of the uploaded file. At a minimum, you need the following bit of code to create the attachment:

            $attachment = chunk_split(base64_encode(file_get_contents($tmp_path.$_FILE["tmp_name"])));

            Here's the rest of the output for an email attachment:

              $output = "
            --PHP-mixed-$random_hash; 
            Content-Type: multipart/alternative; boundary='PHP-alt-$random_hash'
            --PHP-alt-$random_hash
            Content-Type: text/plain; charset='iso-8859-1'
            Content-Transfer-Encoding: 7bit
            
            Hello World!
            This is the simple text version of the email message.
            
            --PHP-alt-$random_hash 
            Content-Type: text/html; charset='iso-8859-1'
            Content-Transfer-Encoding: 7bit
            
            <h2>Hello World!</h2>
            <p>This is the <b>HTML</b> version of the email message.</p>
            
            --PHP-alt-$random_hash--
            
            --PHP-mixed-$random_hash
            Content-Type: application/zip; name=myfile.zip
            Content-Transfer-Encoding: base64 
            Content-Disposition: attachment 
            
            $attachment
            --PHP-mixed-$random_hash--";
            
              echo @mail($to, $subject, $output, $headers);
              Write a Reply...