SCRIPTING:

Devon Aoki
MAILNOW: A CLASS TO EMAIL MESSAGES AND ATTACHMENTS WITHOUT ANY CONFIGURATION NEEDED. LEARN ABOUT INTERNET MAIL HEADERS (REQUEST FOR COMMENTS RFC 2046)
A Php class that sends email from an HTML form with the nearly unique advantage that it needs no configuration at all: you put the html form online on your server and this script as the pointed one by the html form, and you will be immediately able to receive emails and attachments without any other configuration.
Configurations are possible but entirely optional. Default setting are the ones you probably meant.
I developed it alone, not with a team, and offer it for free: so please feel free to email me in case you found problems.
May 2005
{ @ }
The model above is Devon Aoki
LOADS OF DEVON AOKI ON THE NET


PREMISES
What can this class do and why it could be good

A David La Chapelle artwork
A David La Chapelle artwork
«In the beginning was the Word, and the Word was with God, and the Word was God.
The same was in the beginning with God.
All things were made by him; and without him was not any thing made that was made.
In him was life; and the life was the light of men.
And the light shineth in darkness; and the darkness comprehended it not


[Gospel, st. John]

Are out there better php classes to perform mail submissions? The answer is: definitely yes (just think of the http://www.phpguru.org/ email tools) - and I could have been supposed to declare otherwise or to stay silent on the topic.

So, why you may want this class rather than another?
Because this php mailer will allow you to send emails and include attachments with an extra advantage: it requires no configuration whatsoever, whereas many other classes do indeed (no longer or necessarily referring to the class mentioned above now).

Of course, I am to provide you also with explanations about the possibilities to configure it or custom it, but the point is: these are additional options, once you have the script it can run without any further intervention by you.

So what you basically need is an html form. The form must submit to the php file where you will include the code of this class: in this latter file you just have to instantiate a class instance, namely being the name of the class mailNow it would suffice (being foofoo a placeholder for aby variable name):
$foofoo=new mailNow();

Once the form is submitted to the class, if no recipient is provided it will email, along with attachments if the html form allowed for them, to an email address in the shape of info@yourdomain.com whereas yourdomain.com will be derived from your server address via a php command. Of course, if you want to address another email address, that you can custom, editing just one line in the class, or letting the surfer specify it in the html form, or passing it as a constructor as an argument.

The html form requires a few specific names for the html fields meant to hold the email data.
Yet if for any reason you just don't like those names, you can include in your mark up (html) your own form names and then just specify them in the php class too as you'll see: this is required only if you don't like the default ones, and this class has the great advantage that this caveat applies only to the html form fields names not meant to allow for the attachments (that is, whatever name you give to possible fields meant to upload attachments, it will be fine).
I guess you know at least that by form fields that allow attachments I am referring to the html tags in the shape of <input type="file" name="whatever">
In fact as for these latter html fields, whatever name you may assign to any of the attach file form fields (ranging from individual names to even php arrays names in the shape of name="aname[]" namely with the ending square brackets - or even whatever mix of the two approaches) the php script will go on running without any need to custom it in order to detect those variations.

For your convenience here is the code of a possible and suited html form already set up. It supposes that in the same server directory you have loaded this form as an html file, you have also loaded this php class in a php file named mailtest2.php and that within it, as said, you have also set a class instance via the trivial command:
$foofoo=new mailNow();


That would look like (colors aside):
Send To:
show/hide: cc field bcc field

From (optional):
Subject Line:




A Tom Wesselmann painting
A Tom Wesselmann painting

Now, once said this about the html form, a few caveats about the php script:
  • Trying to submit with localhost tests may produce server errors in the shape of:
    SMTP server response: 550 5.7.1 Unable to relay for webmaster@localhost
    Such is not a class issue but an antispam limitation that your localhost may have. This won't happen with online tests onto your server, of course as long as your server allows for php scripts (you may want to call your server to ask about it namely if they allow for php scripts to send to you emails with attachments).
  • You may have server issues that do not depend from this class.
    If your email fails to be sent, check if the server print errors: if these errors talk of server, this is not a class issue.
    In fact servers may forbid attachments above a certain size (there could even be a very low and strict limit) or with certain extensions (arguably .exe), or may have a malformed php.ini file, or may exclude the possibility to include in your emails Cc and Bcc headers, again as an antispam measure.
    You have to ask your server administrator for this possibility or for the others, or, as far as the Cc and Bcc fields are concerned, you can just exclude from the html form the possibility to include Cc and Bcc data - by the way if the class sees none of such html fields, no class related problem would ensue.
  • This php class is provided as follows: I have tested it on a Windows server running Php 4.1.1 and it works. You try it and if it works for you too, that's yours for free as long as you keep the website comments in it. If it doesn't for your own server specific settings, you have wasted nothing but a couple of minutes!

    You have to understand I developed it entirely alone, with no team or assistance whatsoever, being paid by none, and that I am not a rich guy who can afford testing on a plurality of client/server/smtp environments.

    Yet of course if you want to provide feedback or suggestions you can do it via email and if necessary I will quote in this file your name and contribution, and will add it also as a comment in the class if your contribution helps solving an issue that my limited testing grounds didn't allow me to be aware of.


TECH STUFF
Geek trivia

A Keith Haring painting
A Keith Haring painting
This is a more technical section about a bit of mail headers tech data: feel free to skip it if uninterested.

When at programming, in the beginning there is the word.
Even all the softwares that you use everyday, the whole of them, have been written by programmers as mere text files and they exist only insofar as they exist as such, as words; and your whole software isn't but a set of mere text files brimming with mysterious words, nothing else but words stored in nothing else than immense text scrolls, and no software or program that was made, was ever made without the mere use of mere words.

Once these text files get parsed by an interpreter arranged to ascribe particular meanings to particular (key)words, then those words get turned into your living software.
But when you program whatever, in the beginning there is always the word.

When you send an email and you want to instruct it so that email softwares will parse it ascribing to it the right addresses, the right sender and "reply-to" fields, the right subject and body fields, and showing in them the right attachments, showing them either as such or as inline contents, you instruct this all by following a codified standard set of keywords just written down in plain text and which, once arrived into the clutches of an email software awaiting on the listening end, will get turned into the email they were supposed to be.

These text words are defined in an immense set of proposals. These proposals are called RFC (an acronym for: Request For Comments) and the one I mostly used to consult here was this: the RFC 2046.

That specification is long and yet the most amazing fact, the one that drives most programmers crazy, is that one of the main keyword that such standards considers are... carriage return and new line feeds.
In programming language the end of a line is called a carriage return: its text symbol is: "\r", and the beginning of a new line is called the line feed: its text symbol is: "\n".
Joining them it produces:
"\r\n"
which is so often called CRLF (Carriage Return (and) Line Feed).

Now, needless to say that the fact such chars are critical keywords, is doomed to do what it actually does: make scripters become crazy because carriage returns and the alike are so volatile entities to human eyes, that it becomes so easy and natural to assume quite wrongly that the presence of one more or one less of them would have been the same.
But they are, for email headers specifications, as much critical as, say, a misspelling in php a function name like str_replace with the wrong strreplace could be: they look similar, but similar is not precise enough for a computer.

If you fail to follow the guidelines of the RFC specifications considering also CRLF as mission critical keywords that cannot just be scattered randomly, you easily end up with email headers than rather than being translated into what they were supposed to be by the above mentioned "interpreters", may show up as meaningless cleartext contents of the email itself! Blame the CRLF then, more likely.
An instance for all:
«The boundary delimiter MUST occur at the beginning of a line, i.e., following a CRLF, and the initial CRLF is considered to be attached to the boundary delimiter line rather than part of the preceding part. The boundary may be followed by zero or more characters of linear whitespace. It is then terminated by either another CRLF and the header fields for the next part, or by two CRLFs, in which case there are no header fields for the next part. If no Content-Type field is present it is assumed to be "message/rfc822" in a "multipart/digest" and "text/plain "otherwise.

NOTE: The CRLF preceding the boundary delimiter line is conceptually attached to the boundary so that it is possible to have a part that does not end with a CRLF (line break). Body parts that must be considered to end with line breaks, therefore, must have two CRLFs preceding the boundary delimiter line, the first of which is part of the preceding body part, and the second of which is part of the encapsulation boundary.

Boundary delimiters must not appear within the encapsulated material, and must be no longer than 70 characters, not counting the two leading hyphens.»

[from RFC 2046]
Go figure why scripters may fail: that's a digest of admonitions!
That very same document is well aware of these issues, in fact it also says:
«Several of the mechanisms described in this set of documents may seem somewhat strange or even baroque at first reading.
 
(...) The previous four definitions are clearly circular. This is unavoidable, since the overall structure of a MIME message is indeed recursive
 
Though the prohibition against using content-transfer-encodings on composite body data may seem overly restrictive, it is necessary to prevent nested encodings»
At any rate, once stressed the importance of CRLF sets, and their full dignity as fully valid critical keywords, other keywords (things like Priority, Content and the alike) that are used for email headers are listed at files such as: Common Internet Message Header Fields .
I won't reproduce them here for they can be so many and that digest is, though long (ah, what a bore these comments about files being "too" long; if you want a good thing, can't always be said within half a line), very good too.

As for how email headers may look like in plaintext, a quicker overview is at the often quoted Sending MIME e-mail from PHP.
If you want to read them, or just have a glance, I suggest this order:
  1. Sending MIME e-mail from PHP as a fast introduction.
  2. Common Internet Message Header Fields as a list of the headers that make sense to human eyes. You won't need to read all: scroll and glimpse.
  3. RFC 2046 for the CRLF issues, namely for those keywords that as I dared imply make "no sense" to "human eyes"; not necessary to read it all, but give to it a bit of your time, eventually.


THE mailNow CODEX
Your Copy and Paste Php codex

Here is your mailNow PHP class codex. Please check that in the first line comment of the class codex you have the most up to date class version.
The codex is inclusive of the initialization of the class into a variable arbitrary named foo; there is at the bottom of the textarea a button via which you can omit the comments in the class:
A Edward Ruscha painting
A Edward Ruscha painting

lines (with comments and blank lines):
A Charles Bell photo
A Charles Bell photo


CLASS DETAILS
Class Variables And Methods

A Wassily Kandinsky painting
A Wassily Kandinsky painting

Here is an overview of the class variables and methods.
All the methods would be conceived to be preferably (but not necessarily) private, namely used via the class itself rather than directly called in by the programmer. Yet most of them might also work if directly called, but you'd have to test it yourself first for since the idea of the class is that you have to do nothing in order to make it run, the overall coding was developed having in mind the feature that you won't need to call directly in any of the class methods.

CLASS VARIABLES

  • YOUR_EMAIL: you can custom it, and is actually the only field value which I'd advice to custom anyway.
    It should be the default email address where all incoming mails are directed to as their recipient, in case no alternative html form field was set up to host recipient email addresses.
    It defaults to info@ plus your server name in the shape of yourservername.xxx
  • allowedExtensions: defaults to a set of allowed extensions for files to attachments,.
    They are arrayed in the shape of [extension, MIMEtype/MIMEsubtype and the class will perform a check on both paramteres so to forestall a too easy forgery: like for instance a windows file with a changed extension (such trivial an operation, that it would be within the possibilities of infants - and yet many mailing classes forget about it).
    Upon running of the class instance a validation will be performed on these entries in this array and dots or double whitespaces will be removed.
     
    Here is a list of all the known extensions, though this argument will account only for about 300 of them.
    To know more about MIME types, a comprehensive lost of MIME types and what they are.
  • maxFileSize: defaults to 250,000 bytes. If you leave it empty, it means all file sizes are allowed.
  • doNotSendMailImmediately: if set to 1 allows you to adapt class fields before sending (instance: $foo->doNotReplaceDoubleWhitespaces=0;), but then to actually send the email you also need a direct call to: $foo->mailer();
  • afterSentEmailPrintoutPossibleErrors: if set to 1 and any validly uploaded file was not attached, for instance because of size or extension issues or forgeries, a message is print after sent the email reporting the detected issues. If you do not want this to happen leave its value set to zero (its default).
  • toHTMLfieldName: it is the name of an html form field, defaults to "to" and you may change it as long as this change is reflected also in the html form field (=tag) name property. It is the html form field name of the field meant to host the recipient address.
    Such field may host more addresses if separated via a comma. Addresses are validated and stripped if they do not appear as having the email address expected structure. If omitted, the class variable YOUR_EMAIL will lend its value to it.
  • fromHTMLfieldName: it is the name of an html form field, defaults to "from" and you may change it as long as this change is reflected also in the html form field (=tag) name property. It is the html form field name of the field meant to host the sender address. Optional.
    Address is validated and stripped if it does not appear as having the email address expected structure.
  • subjectHTMLfieldName: it is the name of an html form field, defaults to "subject" and you may change it as long as this change is reflected also in the html form field (=tag) name property. It is the html form field name of the field meant to host the email subject line.
  • messageHTMLfieldName: it is the name of an html form field, defaults to "message" and you may change it as long as this change is reflected also in the html form field (=tag) name property. It is the html form field name of the field meant to host the email text message body.
  • priorityHTMLfieldName: it is the name of an html form field, defaults to "priority" and you may change it as long as this change is reflected also in the html form field (=tag) name property. It is the html form field name of the field meant to host the email priority level. Optional.
  • ccHTMLfieldName: it is the name of an html form field, defaults to "cc" and you may change it as long as this change is reflected also in the html form field (=tag) name property. It is the html form field name of the field meant to host the Cc (Carbon Copy) email addresses. Optional.
    Such field may host more addresses if separated via a comma. Addresses are validated and stripped if they do not appear as having the email address expected structure.

    Servers might refuse Cc headers, returning a Server error! So, you should test it.
  • bccHTMLfieldName: it is the name of an html form field, defaults to "bcc" and you may change it as long as this change is reflected also in the html form field (=tag) name property. It is the html form field name of the field meant to host the Bcc (Blind Carbon Copy) email addresses. Optional.
    Such field may host more addresses if separated via a comma. Addresses are validated and stripped if they do not appear as having the email address expected structure.

    Servers might refuse Cc headers, returning a Server error! So, you should test it.
  • uploadDirectory: defaults to an empty string. You should contact your server for maybe it requires the attached files to be moved to a specific location before being uploaded.
  • CRLF: defaults to newline (Unix systems require this arrangement). When called, the function will work out if it's on a Windows server and then change this field to the &quopt;\r\n" that Windows would demand.
  • ContentTransferEncoding: defaults to "Content-Transfer-Encoding: BASE64"
  • ContentDisposition: defaults to "attachment". If you change it to "inline", attached files rather than appearing as attached will show up inline the email body.
  • priority: defaults to number 3. So the default priority 3, which is normal. Ranges 1-5, being 1 the highest priority.
  • charset: defaults to iso-8859-1; though often US-ASCII is recommended, I would still suggest the other. It is true that charsets too extensive would support chars proliferation, a real curse for internet applications, but excluding also a few accented characters (as the US-ASCII value would imply) that are common to so many languages seemed to me a bit too much: think of chars like é which is immensely common to italian and french both) .
  • encodingBits: defaults to 8bit though for US-ASCII is recommended 7bit: set it to 7bit if you plan to change the charset into US-ASCII.
  • messageBodySubtype: the message body text won't appear as an attachment but as inline text - I argue this is precisely what you want!
  • messageBodyContentDisposition: same considerations as for messageBodySubtype;
  • stripTagsFromMessage: defaults to 1 and thus strips HTML tags from the message body: they would be useless, infact, in a text/plain setting. Set it to zero if you want to preserve the HTML tags in the message body (from the headers, they will be stripped anyway).
  • maxHeadersStringLength: set to 500 chars. Does not apply such limit to the message body. It prevents headers or form fields to be injected with intentionally absurdly long inputs. You may decide to even set it to a much lower value.
A Nan Goldin photo
A Nan Goldin photo, Tree in snow

CLASS METHODS

All methods are meant as private. A small description follows anyway.
  • mailNow: the constructor. Resets to empty all the class variables that are meant to be empty. Then it calls in all the class methods required to send the email accordingly to the posted html form data. Therefore, it works a bit like a main() method in languages like Java or C++ would.
  • secure: it will strip tags, decode UTF-8 values, decode entities, decode %## signs and most significantly remove from the headers all new lines and carriage returns, thus making injection via form fields practically impossible.
  • validateEmail: validates one email address after the regular expression:
  • validateMultipleEmails: recursively calls in validateEmail on an array of emails or on a string of emails separated via a comma, and strips all those that do not appear validly formatted.
  • setBound: sets the boundary for separating the headers as required by the RFC specifications. Sets the CRLF to be \r\n if it's a non Microsoft server.
  • checkExtensions: avoids uploading attached files whose extension is not among the possibly allowed ones: checks not only extension but also the corrispondence between file extension and file MIME type.
  • checkSize: avoids uploading attached files whose size may exceed the maximum allowed by the class (if any).
  • manageAttachments: eliminates files that cannot be attached, verifies they are uploaded files indeed. It also checks they are not duplicates - that is, with this class you cannot send in one4 same email more than once the same file.
  • getNewName: finds a new name for the file, in case it must be moved to another folder, as many servers require this before being a file actually attached; this method makes sure such file name causes no conflict with files already existing in the folder which might have the same name.
     
    The third argument of this file is set by default to 1, which means that to the new files will be assigned a progressive number from zero onward as their new name. If you rather prefer an alphabetic name, edit the code and set the third argument in this method to be equal to zero rather than =1
  • makeHeaders: prepares the headers for the final email, and includes in them the message body.
    Such headers are stored in a class variables named (would you guess?) headers.
  • mailer (has an alias: send): sends the email, if the class is set not to send automatically (see the class variable doNotSendMailImmediately).
  • explainErrors: if called in, explains the file attached errors as they got stored (if any) in the class variables named errorsReport, extensionErrors, sizeErrors, allErrors by printing out them.
A Gregory Crewdson photo
A Gregory Crewdson photo