Monday, December 13, 2010

PHP & JAVA Bridge

Running PHP applications in Tomcat 6

This guide shows how to install and run PHP applications like Moodle, mediaWiki, Joomla as Tomcat 6 web applications. And how to install PHP 5.x for all existing web applications.

Download and install Java, Tomcat and PHP

Install a PHP web application into Tomcat


  1. Copy the PHP web application JavaBridgeTemplate.war or the demo JavaBridge.war to the Tomcat webapps directory.
  2. Wait two seconds until Tomcat has loaded the web application.
  3. Browse to http://127.0.0.1:8080/JavaBridgeTemplate5541 and http://127.0.0.1:8080/JavaBridgeTemplate5541/test.php to see the PHP info page.
  4. Rename the file file:webapps/JavaBridgeTemplate5541 directory, for example to file:webapps/Moodle, and download and install your PHP application to this directory.
  5. Browse to the name of your web application, for example http://127.0.0.1:8080/Moodle, to run it from your internet browser.

PHP support for all existing Tomcat web applications

If you want to enable PHP for all of your web applications, move the Java libraries from the local web application folder to the Tomcat library folder and edit the Tomcat web configuration as follows:

  1. Stop Tomcat.
  2. Move the libraries JavaBridge.jar, php-servlet.jar and php-script.jar from the webapps/JavaBridgeTemplate5541/WEB-INF/lib directory over to the tomcat lib directory.
  3. Edit the Tomcat conf/web.xml. Add the following 9 lines marked with a +:

    <web-app xmlns=... >

    + php.java.servlet.ContextLoaderListener
    + PhpJavaServletphp.java.servlet.PhpJavaServlet
    +

    + PhpCGIServletphp.java.servlet.fastcgi.FastCGIServlet
    + prefer_system_php_execOn
    + php_include_javaOff
    +

    + PhpJavaServlet*.phpjavabridge
    + PhpCGIServlet*.php
    ...

    </web-app>
  4. Start Tomcat again. Now you can add PHP scripts to tomcat.
  5. Add a PHP test file
    echo java("java.lang.System")->getProperties(); ?>
    to some web context, for example "examples", and browse to http://yourHost.com:8080/examples/test.php.
  6. Check the process list using the Unix/Linux or Windows task manager. There should be 5 php-cgi FastCGI executables waiting for requests from Java.
  7. Please see our FAQ for more information how to set up a load balancer or how to create a distributable PHP/Java web application.

Cross the Gap Between PHP and Java

Using sophisticated application frameworks to build your network server applications is fine, but sometimes these frameworks are overkill. With a little communications programming between PHP and Java, you can establish an extensible layer that handles the annoying details of creating a custom network protocol. 

hese days, using sophisticated application frameworks to build your network server applications is understandable, but sometimes such frameworks are overkill. When you strip networking down to its bare essentials, network sockets offer lot of flexibility and simplicity. With a little communications programming between PHP and Java, you can establish an extensible layer that handles the annoying details of creating a custom network protocol.



As you'll see, PHP is not only excellent for quick-and-dirty scripting. More and more developers also are using it to build sophisticated Web applications. Java, of course, has been used to build Web applications for years, but as anyone who has used a Java-based Web framework knows, it isn't the easiest technology to use. This article shows how to connect a PHP-based application to a custom Java server. The demonstration doesn't use Enterprise Java Beans (EJB) or any particular Java-based server framework. Instead, it creates a simple custom TCP/IP Java server to demonstrate how easy it is. Then, you'll see how to access such a server from Java.
Architecture
PHP programming is sometimes mistakenly referred to as client-side scripting. Technically, PHP runs on the server side, but because it is usually used to generate HTML—which the user sees directly—it is sometimes thought of as the client-side portion of server-side code.
In fact, the system in this article uses PHP in this very sense (click here to download the source code). It consists of a Java portion, which performs server-side computation, and a PHP portion, which generates HTML. Both portions run on the server and communicate using a TCP/IP socket. The terms client and server can be a little ambiguous in this context, so the article refers instead to the PHP portion and the Java portion.

Saturday, November 20, 2010

How to call more than one function with return true

Use this for call more than one function with return true :

< script>
function checkform1 ( frm_list1 )
{
return true;
}

function checkform2 ( frm_list2 )
{
return true;
}

function checkform3 ( frm_list3 )
{
return true;
}
< /script>

< form action="" id="frm_itinerary_list" method="post" name="frm_itinerary_list" onsubmit="return (checkform1(this) && checkform2(this) && checkform3(this));">



< /form>

Saturday, November 13, 2010

ini_set

ini_set -- Sets the value of a configuration option

Description

string ini_set ( string varname, string newvalue)

Sets the value of the given configuration option. Returns the old value on success, FALSE on failure. The configuration option will keep this new value during the script's execution, and will be restored at the script's ending.
Not all the available options can be changed using ini_set(). Below is a table with a list of all PHP options (as of PHP 4.2.0), indicating which ones can be changed/set and at what level.

Table 1. Configuration options
NameDefaultChangeable
allow_call_time_pass_
reference
"1"PHP_INI_PERDIR
allow_url_fopen"1"PHP_INI_SYSTEM
always_populate_raw_
post_data
"0"PHP_INI_PERDIR
arg_separator.input"&"PHP_INI_PERDIR
arg_separator.output"&"PHP_INI_ALL
asp_tags"0"PHP_INI_PERDIR
assert.active"1"PHP_INI_ALL
assert.bail"0"PHP_INI_ALL
assert.callbackNULLPHP_INI_ALL
assert.quiet_eval"0"PHP_INI_ALL
assert.warning"1"PHP_INI_ALL
auto_append_fileNULLPHP_INI_PERDIR
auto_detect_line_endings"0"PHP_INI_ALL
auto_globals_jit"1"PHP_INI_PERDIR
auto_prepend_fileNULLPHP_INI_PERDIR
bcmath.scale"0"PHP_INI_ALL
browscapNULLPHP_INI_SYSTEM
child_terminate"0"PHP_INI_ALL
com.allow_dcom"0"PHP_INI_SYSTEM
com.autoregister_
casesensitive
"1"PHP_INI_ALL
com.autoregister_
typelib
"0"PHP_INI_ALL
com.autoregister_
verbose
"0"PHP_INI_ALL
com.code_page""PHP_INI_ALL
com.typelib_file""PHP_INI_SYSTEM
date.default_latitude"31.7667"PHP_INI_ALL
date.default_longitude"35.2333"PHP_INI_ALL
date.sunrise_zenith"90.83"PHP_INI_ALL
date.sunset_zenith"90.83"PHP_INI_ALL
dba.default_handler""PHP_INI_ALL
dbx.colnames_case"unchanged"PHP_INI_SYSTEM
default_charset""PHP_INI_ALL
default_mimetype"text/html"PHP_INI_ALL
default_socket_timeout"60"PHP_INI_ALL
define_syslog_variables"0"PHP_INI_ALL
disable_classes""php.ini only
disable_functions""php.ini only
display_errors"1"PHP_INI_ALL
display_startup_errors"0"PHP_INI_ALL
docref_ext""PHP_INI_ALL
docref_root""PHP_INI_ALL
doc_rootNULLPHP_INI_SYSTEM
enable_dl"1"PHP_INI_SYSTEM
engine"1"PHP_INI_ALL
error_append_stringNULLPHP_INI_ALL
error_logNULLPHP_INI_ALL
error_prepend_stringNULLPHP_INI_ALL
error_reportingNULLPHP_INI_ALL
exif.decode_jis_intel"JIS"PHP_INI_ALL
exif.decode_jis_motorola"JIS"PHP_INI_ALL
exif.decode_unicode_intel"UCS-2LE"PHP_INI_ALL
exif.decode_unicode_
motorola
"UCS-2BE"PHP_INI_ALL
exif.encode_jis""PHP_INI_ALL
exif.encode_unicode"ISO-8859-15"PHP_INI_ALL
expose_php"1"php.ini only
extension_dir"@PREFIX@"PHP_INI_SYSTEM
fbsql.allow_persistent"1"PHP_INI_SYSTEM
fbsql.autocommit"1"PHP_INI_SYSTEM
fbsql.batchSize"1000"PHP_INI_SYSTEM
fbsql.default_database""PHP_INI_SYSTEM
fbsql.default_
database_password
""PHP_INI_SYSTEM
fbsql.default_hostNULLPHP_INI_SYSTEM
fbsql.default_password""PHP_INI_SYSTEM
fbsql.default_user"_SYSTEM"PHP_INI_SYSTEM
fbsql.generate_warnings"0"PHP_INI_SYSTEM
fbsql.max_connections"128"PHP_INI_SYSTEM
fbsql.max_links"128"PHP_INI_SYSTEM
fbsql.max_persistent"-1"PHP_INI_SYSTEM
fbsql.max_results"128"PHP_INI_SYSTEM
file_uploads"1"PHP_INI_SYSTEM
highlight.bg"#FFFFFF"PHP_INI_ALL
highlight.comment"#FF8000"PHP_INI_ALL
highlight.default"#0000BB"PHP_INI_ALL
highlight.html"#000000"PHP_INI_ALL
highlight.keyword"#007700"PHP_INI_ALL
highlight.string"#DD0000"PHP_INI_ALL
html_errors"1"PHP_INI_ALL
ibase.allow_persistent"1"PHP_INI_SYSTEM
ibase.dateformat"%Y-%m-%d"PHP_INI_ALL
ibase.default_charsetNULLPHP_INI_ALL
ibase.default_dbNULLPHP_INI_SYSTEM
ibase.default_passwordNULLPHP_INI_ALL
ibase.default_userNULLPHP_INI_ALL
ibase.max_links"-1"PHP_INI_SYSTEM
ibase.max_persistent"-1"PHP_INI_SYSTEM
ibase.timeformat"%H:%M:%S"PHP_INI_ALL
ibase.timestampformat"%Y-%m-%d %H:
%M:%S"
PHP_INI_ALL
iconv.input_encoding"ISO-8859-1"PHP_INI_ALL
iconv.internal_encoding"ISO-8859-1"PHP_INI_ALL
iconv.output_encoding"ISO-8859-1"PHP_INI_ALL
ifx.allow_persistent"1"PHP_INI_SYSTEM
ifx.blobinfile"1"PHP_INI_ALL
ifx.byteasvarchar"0"PHP_INI_ALL
ifx.charasvarchar"0"PHP_INI_ALL
ifx.default_hostNULLPHP_INI_SYSTEM
ifx.default_passwordNULLPHP_INI_SYSTEM
ifx.default_userNULLPHP_INI_SYSTEM
ifx.max_links"-1"PHP_INI_SYSTEM
ifx.max_persistent"-1"PHP_INI_SYSTEM
ifx.nullformat"0"PHP_INI_ALL
ifx.textasvarchar"0"PHP_INI_ALL
ignore_repeated_errors"0"PHP_INI_ALL
ignore_repeated_source"0"PHP_INI_ALL
ignore_user_abort"0"PHP_INI_ALL
implicit_flush"0"PHP_INI_ALL
include_path".;@PREFIX
@\\pear"
PHP_INI_ALL
ingres.allow_persistent"1"PHP_INI_SYSTEM
ingres.default_databaseNULLPHP_INI_ALL
ingres.default_passwordNULLPHP_INI_ALL
ingres.default_userNULLPHP_INI_ALL
ingres.max_links"-1"PHP_INI_SYSTEM
ingres.max_persistent"-1"PHP_INI_SYSTEM
ircg.control_user"nobody"PHP_INI_ALL
ircg.keep_alive_interval"60"PHP_INI_ALL
ircg.max_format_
message_sets
"12"PHP_INI_ALL
ircg.shared_mem_size"6000000"PHP_INI_ALL
ircg.work_dir"/tmp/ircg"PHP_INI_ALL
last_modified"0"PHP_INI_ALL
ldap.max_links"-1"PHP_INI_SYSTEM
log_errors"0"PHP_INI_ALL
log_errors_max_len"1024"PHP_INI_ALL
magic_quotes_gpc"1"PHP_INI_PERDIR
magic_quotes_runtime"0"PHP_INI_ALL
magic_quotes_sybase"0"PHP_INI_ALL
mail.force_extra_
parameters
NULLPHP_INI_PERDIR
max_execution_time"30"PHP_INI_ALL
max_input_time"-1"PHP_INI_PERDIR
mbstring.detect_
order
NULLPHP_INI_ALL
mbstring.encoding_
translation
"0"PHP_INI_PERDIR
mbstring.func_
overload
"0"PHP_INI_PERDIR
mbstring.http_input"pass"PHP_INI_ALL
mbstring.http_output"pass"PHP_INI_ALL
mbstring.internal_
encoding
NULLPHP_INI_ALL
mbstring.language"neutral"PHP_INI_PERDIR
mbstring.script_encodingNULLPHP_INI_ALL
mbstring.substitute_c
haracter
NULLPHP_INI_ALL
mcrypt.algorithms_dirNULLPHP_INI_ALL
mcrypt.modes_dirNULLPHP_INI_ALL
memory_limit"8M"PHP_INI_ALL
mime_magic.debug"0"PHP_INI_SYSTEM
mime_magic.magicfilePHP_PREFIXPHP_INI_SYSTEM
mssql.allow_persistent"1"PHP_INI_SYSTEM
mssql.batchsize"0"PHP_INI_ALL
mssql.compatability_
mode
"0"PHP_INI_ALL
mssql.connect_timeout"5"PHP_INI_ALL
mssql.datetimeconvert"1"PHP_INI_ALL
mssql.max_links"-1"PHP_INI_SYSTEM
mssql.max_persistent"-1"PHP_INI_SYSTEM
mssql.max_procs"25"PHP_INI_ALL
mssql.min_error_
severity
"10"PHP_INI_ALL
mssql.min_message_
severity
"10"PHP_INI_ALL
mssql.secure_
connection
"0"PHP_INI_SYSTEM
mssql.textlimit"-1"PHP_INI_ALL
mssql.textsize"-1"PHP_INI_ALL
mssql.timeout"60"PHP_INI_ALL
mysql.allow_persistent"1"PHP_INI_SYSTEM
mysql.connect_timeout"60"PHP_INI_ALL
mysql.default_hostNULLPHP_INI_ALL
mysql.default_
password
NULLPHP_INI_ALL
mysql.default_portNULLPHP_INI_ALL
mysql.default_socketNULLPHP_INI_ALL
mysql.default_userNULLPHP_INI_ALL
mysql.max_links"-1"PHP_INI_SYSTEM
mysql.max_persistent"-1"PHP_INI_SYSTEM
mysql.trace_mode"0"PHP_INI_ALL
mysqli.default_hostNULLPHP_INI_ALL
mysqli.default_port"3306"PHP_INI_ALL
mysqli.default_pwNULLPHP_INI_ALL
mysqli.default_socketNULLPHP_INI_ALL
mysqli.default_userNULLPHP_INI_ALL
mysqli.max_links"-1"PHP_INI_SYSTEM
mysqli.reconnect"0"PHP_INI_SYSTEM
nsapi.read_timeout"60"PHP_INI_ALL
odbc.allow_persistent"1"PHP_INI_SYSTEM
odbc.check_persistent"1"PHP_INI_SYSTEM
odbc.defaultbinmode"1"PHP_INI_ALL
odbc.defaultlrl"4096"PHP_INI_ALL
odbc.default_dbNULLPHP_INI_ALL
odbc.default_pwNULLPHP_INI_ALL
odbc.default_userNULLPHP_INI_ALL
odbc.max_links"-1"PHP_INI_SYSTEM
odbc.max_persistent"-1"PHP_INI_SYSTEM
open_basedirNULLPHP_INI_SYSTEM
output_buffering"0"PHP_INI_PERDIR
output_handlerNULLPHP_INI_PERDIR
pfpro.defaulthost"test-payflow.
verisign.com"
PHP_INI_ALL
pfpro.defaultport"443"PHP_INI_ALL
pfpro.defaulttimeout"30"PHP_INI_ALL
pfpro.proxyaddress""PHP_INI_ALL
pfpro.proxylogon""PHP_INI_ALL
pfpro.proxypassword""PHP_INI_ALL
pfpro.proxyport""PHP_INI_ALL
pgsql.allow_persistent"1"PHP_INI_SYSTEM
pgsql.auto_
reset_persistent
"0"PHP_INI_SYSTEM
pgsql.ignore_notice"0"PHP_INI_ALL
pgsql.log_notice"0"PHP_INI_ALL
pgsql.max_links"-1"PHP_INI_SYSTEM
pgsql.max_persistent"-1"PHP_INI_SYSTEM
post_max_size"8M"PHP_INI_PERDIR
precision"14"PHP_INI_ALL
register_argc_argv"1"PHP_INI_PERDIR
register_globals"0"PHP_INI_PERDIR
register_long_arrays"1"PHP_INI_PERDIR
report_memleaks"1"PHP_INI_ALL
report_zend_debug"1"PHP_INI_ALL
safe_mode"0"PHP_INI_SYSTEM
safe_mode_
allowed_env_vars
"PHP_"PHP_INI_SYSTEM
safe_mode_exec_dir""PHP_INI_SYSTEM
safe_mode_gid"0"PHP_INI_SYSTEM
safe_mode_include_dirNULLPHP_INI_SYSTEM
safe_mode_protected_
env_vars
"LD_LIBRARY
_PATH"
PHP_INI_SYSTEM
sendmail_fromNULLPHP_INI_ALL
sendmail_pathNULLPHP_INI_SYSTEM
serialize_precision"100"PHP_INI_ALL
session.auto_start"0"PHP_INI_ALL
session.bug_compat_42"1"PHP_INI_ALL
session.bug_compat_warn"1"PHP_INI_ALL
session.cache_expire"180"PHP_INI_ALL
session.cache_limiter"nocache"PHP_INI_ALL
session.cookie_domain""PHP_INI_ALL
session.cookie_lifetime"0"PHP_INI_ALL
session.cookie_path"/"PHP_INI_ALL
session.cookie_secure""PHP_INI_ALL
session.entropy_file""PHP_INI_ALL
session.entropy_length"0"PHP_INI_ALL
session.gc_divisor"100"PHP_INI_ALL
session.gc_maxlifetime"1440"PHP_INI_ALL
session.gc_probability"1"PHP_INI_ALL
session.hash_bits_per_
character
"4"PHP_INI_ALL
session.hash_function"0"PHP_INI_ALL
session.name"PHPSESSID"PHP_INI_ALL
session.referer_check""PHP_INI_ALL
session.save_handler"files"PHP_INI_ALL
session.save_path""PHP_INI_ALL
session.serialize_handler"php"PHP_INI_ALL
session.use_cookies"1"PHP_INI_ALL
session.use_only_
cookies
"0"PHP_INI_ALL
session.use_trans_sid"0"PHP_INI_ALL
short_open_tag"1"PHP_INI_PERDIR
SMTP"localhost"PHP_INI_ALL
smtp_port"25"PHP_INI_ALL
soap.wsdl_cache_dir"/tmp"PHP_INI_ALL
soap.wsdl_cache_
enabled
"1"PHP_INI_ALL
soap.wsdl_cache_ttl"86400"PHP_INI_ALL
sql.safe_mode"0"PHP_INI_SYSTEM
sqlite.assoc_case"0"PHP_INI_ALL
sybct.allow_
persistent
"1"PHP_INI_SYSTEM
sybct.deadlock_
retry_count
"-1"PHP_INI_ALL
sybct.hostnameNULLPHP_INI_ALL
sybct.login_timeout"-1"PHP_INI_ALL
sybct.max_links"-1"PHP_INI_SYSTEM
sybct.max_persistent"-1"PHP_INI_SYSTEM
sybct.min_client_
severity
"10"PHP_INI_ALL
sybct.min_server_
severity
"10"PHP_INI_ALL
tidy.clean_output"0"PHP_INI_PERDIR
tidy.default_config""PHP_INI_SYSTEM
track_errors"0"PHP_INI_ALL
unserialize_callback_funcNULLPHP_INI_ALL
upload_max_filesize"2M"PHP_INI_PERDIR
upload_tmp_dirNULLPHP_INI_SYSTEM
url_rewriter.tags"a=href,
area=href,
frame=src,
form=,fieldset="
PHP_INI_ALL
user_agentNULLPHP_INI_ALL
user_dirNULLPHP_INI_SYSTEM
variables_order"EGPCS"PHP_INI_ALL
xbithack"0"PHP_INI_ALL
xmlrpc_errors"0"PHP_INI_SYSTEM
xmlrpc_error_number"0"PHP_INI_ALL
y2k_compliance"1"PHP_INI_ALL
zend.ze1_compatibility_
mode
"0"PHP_INI_ALL
zlib.output_compression"0"PHP_INI_ALL
zlib.output_compression_
level
"-1"PHP_INI_ALL
zlib.output_handler""PHP_INI_ALL

Table 2. Definition of PHP_INI_* constants
ConstantValueMeaning
PHP_INI_USER1Entry can be set in user scripts
PHP_INI_PERDIR2Entry can be set in php.ini, .htaccess or httpd.conf
PHP_INI_SYSTEM4Entry can be set in php.ini or httpd.conf
PHP_INI_ALL7Entry can be set anywhere

Thursday, November 11, 2010

Configuring Cron Jobs or Scheduler on Windows

To setup a Windows machine to run cron.php at a specific time follow the specific instructions below. This can be useful if you are not familiar with Linux/Unix, or if your web host does not offer the ability to run cron jobs; you can run them remotely from your own computer.
Note: These instructions were written for Windows XP but should be similar in other versions of Windows.
Creating a Scheduled Task
  1. Open Scheduler
  2. Go to Start > Programs > Accessories > System Tools > Scheduled Tasks
  3. Double-click Add Scheduled Task
  4. The Scheduled Task Wizard will appear. Click Next.
  5. Select the program to run. Choose your browser from the list (for example, Internet Explorer or Mozilla Firefox). Click Next.
  6. Give the task a Name, such as Drupal Cron Job, and choose the Frequency with which to perform the task (for example, Daily)). Click Next.
  7. Choose specific date and time options (this step will vary, depending on the option selected in the previous step). When finished, click Next.
  8. Enter your password if prompted. Change the username if required (for example, you'd like the task to run under a user with fewer privileges security reasons). Click Next.
  9. On the final page, select the checkbox Open advanced properties for this task when I click Finish and click Finish.
Configuring the task
  1. Go to the task's setting page either by checking the checkbox at the end of the last step, or by double-clicking on the task.
  2. In the Run box, after the text that is there now (for example,C:\PROGRA~1\MOZILL~1\firefox.exe), enter a space and then type the address to your website's cron.php page in double quotations (for example,C:\PROGRA~1\MOZILL~1\firefox.exe http://www.example.com/cron.php
  3. To set a frequency more often than Daily (for example, hourly), click the Schedule tab, then click Advanced. Here you can set options such as Repeat task, every 1 hour for23 hours. Click Ok when finished.
  4. Change the start time on the task to one minute from the current time. This will allow you to test the task and make sure that it is working.
  5. When all settings have been configured to your liking, click Apply and OK (note: you may be prompted for your password)
Command-line version
Another way to perform the above commands is by using the schtasks (or at in Windows 2000) command from the command line. To duplicate the example above, which runs Firefox hourly to execute http://www.example.com/cron.php, open a command prompt (Start > Programs > Accessories > Command Prompt) and enter:
schtasks /create /tn "Drupal Cron Job" /tr "C:\PROGRA~1\MOZILL~1\firefox.exehttp://www.example.com/cron.php" /sc hourly
Enter your password if prompted.
Using wget for Windows to run cron
If for whatever reason you'd rather not deal with a browser window popping up on the machine, you can use wget, the Windows port of which works more or less the same as it does in UNIX. curl and lynx also have windows ports but wget is probably the easiest to set up and use.
Grab a copy of wget from your choice of either the author's site or from SourceForge. Install it to the location of your choice.
Follow the steps for Creating A Scheduled Task above, except select wget.exe as the program to run (you may need to click the Browse button to locate it if you installed from a .zip file, for example). When you get to the Advanced Properties dialog, paste in the following after the program path:
-O - -q -t 1 http://www.example.com/cron.php
Adjust the rest of the options as described above and test it.

Advanced email in PHP with Attachment and SMTP Configuration

I wish I could remember the very first email message I ever sent. Unfortunately, the truth is that I've come to take email for granted; for instance, I easily send more email messages than I make phone calls. Because the novelty has long since worn off, the memory of that first email is as lost to me as my first phone call; but I doubt my sense of wonder was any less complete at the time. To someone who has never seen email in action before, that first message can be magical.
In this article, I'll try to recapture some of that magic for those of you who have never created a Web site that sends email messages. We'll see how the PHP server-side scripting language may be set up to send email, and explore how to send complex message types such as HTML email or emails with file attachments.
Note: This article was written back when things like HTML email and file attachments were a lot more difficult to do in PHP than they are today. Before you dive into the from-scratch solutions presented in this article, you might consider investigating PHPMailer, a free library for PHP that provides all of these features with minimal hair-pulling and gnashing of teeth.
PHP Email Setup
Before we can send email with PHP, we need to set it up to do so, just as you need to set up your email program before it can send messages. Configuration for sending email in PHP is done with the php.ini file, so open up your Web server's php.ini in whichever editor you normally use.
If you don't run your own server, but instead have a PHP-equipped Web host, you can safely assume that everything in this section has been done for you, and skip ahead.
In the section entitled [mail function] in the php.ini file, you'll find three settings: SMTP, sendmail_from, and sendmail_path. If your server runs on a Windows machine, you'll want to set the SMTP option to point to your SMTP server (or your ISP's SMTP server, if you're setting up PHP on your home machine). If instead you're setting up PHP on a Linux (or other Unix-based OS) server, you'll want to set the sendmail_path option to point to the sendmail-t option. You can use the SMTP option in Linux instead if you don't have sendmail set up. program on your server, passing it the
In either case, you'll want to set the sendmail_from option to your email address, or whichever address you'd like to appear as the default 'from' address for emails sent from PHP scripts.
Here's how the section might look on a typical Windows server, or on a Linux server without sendmail:
[mail function]
; Setup for Windows systems
SMTP = smtp.my.isp.net
sendmail_from = me@myserver.com
And here's how it might look on a Linux server with sendmail:
[mail function]
; Setup for Linux systems
sendmail_path = /usr/sbin/sendmail -t
sendmail_from = me@myserver.com
With those settings in place, restart your Web server and you're ready to go!

Sending Plain Email
It doesn't come much easier than the procedure to send plain text email in PHP. In fact, you can do it in just one line in a PHP script:
mail('recipient@some.net', 'Subject', 'Your message here.');
?>
The above line would send an email message to recipient@some.net with 'Subject' as the subject line and 'Your message here.' as the message body. As you can see, PHP's mail function makes sending email exceedingly simple, but there are a few advanced tricks we can use to get more out of this simple function.
First of all, if the mail system you configured in your php.ini file rejects a message you try to send (for example, if the 'to' address is not a valid email address), this function will display an error message in the user's browser. Like most PHP functions, however, error messages may be suppressed by preceding the function name with an @ symbol. Combine this with the fact that the mail function returns either true or false depending on whether the email was accepted by the mail sending system, and you have a formula to send email with appropriate error checking:
if (@mail($to, $subject, $message)) {
 echo('
Mail sent successfully.
');
} else {
 echo('Mail could not be sent.
');
}
?>
Note that just because an email message could be sent doesn't guarantee it will arrive at its destination. An email address can be valid (i.e. correctly formed) but not actually exist. For instance, you can successfully send a message to nonexistant.user@hotmail.com -- that is, the mail function will return true -- but the message will bounce because no such user exists. PHP provides no built-in means of detecting when this happens.
When you want to send a message to multiple recipients, you can just list their email addresses one after another, separated by commas, in the first parameter. For example:
mail('recipient1@some.net, recipient2@some.net',
    'An email to two people', 'Message goes here.');
?>
That about covers the basics of the mail function; now let's really get fancy and explore mail headers and what we can do with them!

HTML Email and Other Headers
So now you can send email from your PHP scripts. How exciting! Although I'm sure you're already drunk with power, would you like to know how to send HTML email too? Of course you would!
To understand HTML email, first you need to understand mail headers. Any given email message is made up of two parts: the headers and the message body. Here's how a simple message looks when your email program fetches it from your ISP:
Return-Path:  
Delivered-To: you@some.net  
Received: ...several lines like this...  
From: Sender  
To: You  
Subject: A Simple Message  
Date: Mon, 11 Feb 2002 16:08:19 -0500  
Organization: Sender's Company  
X-Mailer: Microsoft Outlook, Build 10.0.2616  
 
Hi there! Is this thing on?
Everything up to the blank line makes up the headers for this message. In actual fact, most email messages will have many more header lines than this; however, to keep our focus I trimmed this example down to the bare essentials.
As you can see, every line of the headers begins with the name of the header (From:, To:, Subject:, Date:, etc.), followed by some value. Most headers are standardized, and have a specific meaning, either to your mail program or to the mail servers that were responsible for getting the message to you. Non-standard headers exist as well, and they all begin with X- (e.g. X-Mailer:, a non-standard header, often appears to indicate the program that was used to send the message).
NOTE: If a header's value needs more than one line, additional lines should begin with a space. We'll see an example of this in the next section.
As soon as your mail program gets to a blank line, it knows the headers are over and the rest of the email is the message body, which it should display. In this case, the message body is the last line above.
PHP's mail function lets you specify your own headers, which it adds to those it generates automatically to get your message where it needs to go. For example, the following call to the mail function will add an X-Mailer: header to the outgoing message, identifying PHP 4.x as the sending program:
mail('recipient@some.net', 'Subject', 'Your message here.',  
    'X-Mailer: PHP 4.x');  
?>
This optional fourth parameter is most often used to specify a 'from' address other than the default specified in php.ini. Let's add a From: header to do just that:
mail('recipient@some.net', 'Subject', 'Your message here.',  
    "From: sender@some.net\nX-Mailer: PHP 4.x");  
?>
Note that since headers each appear on a single line, we must separate our two headers with a new line character (\n), which means I need to use double quotes around the header string (single quoted strings don't recognize special character codes like \n).
Additional headers also let you assign names to email addresses by specifying them in the format name . Here's our example again, but this time with names "The Sender" and "The Receiver" attached to the relevant addresses:
mail('recipient@some.net', 'Subject', 'Your message here.',  
    "To: The Receiver \n" .  
    "From: The Sender \n" .  
    "X-Mailer: PHP 4.x");  
?>
Notice that to do this, we've had to specify the To: header manually, since the first parameter of PHP's mail function doesn't support this more advanced address format. We must still list all the recipients of the message as bare email addresses in the first parameter, however.
The cc: and Bcc: headers provide the ability to send carbon copies and blind carbon copies of a message as well:
mail('recipient@some.net, someone@some.net, metoo@some.net',  
    'Subject', 'Your message here.',  
    "To: The Receiver \n" .  
    "From: The Sender \n" .  
    "cc: Interested \n" .  
    "Bcc: Me Too \n" .  
    "X-Mailer: PHP 4.x");  
?>
See how the email addresses of all recipients, be they actual addressees (To), carbon copies (Cc), or blind carbon copies (Bcc) are listed in the first parameter? This isn't documented anywhere, but in my testing I've found that it's absolutely vital if you want the message to get to everyone it's supposed to, especially on Windows servers where PHP's mail function is especially sensitive.
BUG ALERT: There are two apparent bugs in the PHP mail function, which I've observed as recently as PHP 4.1.0, that you must be aware of. First, the Cc: header must be typed 'cc:' (as above) or 'CC:', that is, in either all-caps or low-caps. The mixed case version (Cc:) should work, but it doesn't. Secondly, on Windows servers, the Bcc: header does not work as it should. Bcc: recipients do get a copy of the message, but the Bcc: headers are not stripped out of the message during sending, so recipients can see the Bcc: receivers by looking at those lines in the headers.
What does all this have to do with HTML email, you ask? Well, a few special headers will cause the message body to be interpreted as HTML by email clients that support it:
mail('recipient@some.net', 'Subject',  
    '
Your message here.
',  
    "To: The Receiver \n" .  
    "From: The Sender \n" .  
    "MIME-Version: 1.0\n" .  
    "Content-type: text/html; charset=iso-8859-1");  
?>
Note both the message in HTML format as well as the two new headers: Mime-Version: and Content-type:.
The MIME-Version: header indicates that the standard extended mail format will be used (MIME stands for Multipurpose Internet Mail Extensions), which allows for messages to be sent content types other than plain text. The Content-type: header then specifies that the message with contain HTML (and sets the character set to the standard for that format).

Mixed Messages
In life, it's rarely good to send mixed messages. At least, that's what my last girlfriend told me! When it comes to email, however, mixed messages offer a whole lot of power. A single email message can contain both text and HTML versions of your message. That makes it viewable in most any email program, and you don't sacrifice the power of HTML formatting for readers that are appropriately equipped.
Be aware that mixed messages have their weaknesses. First of all, since you're sending two versions of your message, the message will typically be a lot larger than it would be if you sent just one format or the other. Also note that old email programs that don't recognize the mixed message format may display both versions of the message as file attachments (one text, the other HTML).
Let's look at a simple example of a mixed email message, and then look at the PHP code to send it:
Date: Mon, 11 Feb 2002 16:08:19 -0500  
To: The Receiver  
From: The Sender  
Subject: A simple mixed message  
MIME-Version: 1.0  
Content-Type: multipart/alternative;  
             boundary="==Multipart_Boundary_xc75j85x"  
 
This is a multi-part message in MIME format.  
 
--==Multipart_Boundary_xc75j85x  
Content-Type: text/plain; charset="iso-8859-1"  
Content-Transfer-Encoding: 7bit  
 
This is the text portion of the mixed message.  
 
--==Multipart_Boundary_xc75j85x  
Content-Type: text/html; charset="iso-8859-1"  
Content-Transfer-Encoding: 7bit  
 
 
 
This is the HTML portion of the mixed message.
 
--==Multipart_Boundary_xc75j85x--
After the initial, standard headers at the top of the message, we have the MIME-Version: 1.0 header that enables the advanced email features we need. The Content-Type: header is where things start to get funky:
Content-Type: multipart/alternative;  
             boundary="==Multipart_Boundary_xxc75885"
We specify a content type of multipart/alternative, which is the special type that allows us to send a message with two or more alternative versions of the message (from which the recipient's email program will pick the most suitable for display). In addition, we use the Content-Type header to set a boundary string.
To keep the header lines short, this part of the header appears on a second line (as mentioned in a note above, the second line must begin with one or more spaces to indicate that it's a continuation of the previous line).
In this case, I chose "==Multipart_Boundary_xc75j85x" as the boundary string. There is no special significance to this string, other than it is unlikely to appear as part of the message itself. I used characters like equals signs and underscores, and semi-random strings of letters and numbers to help ensure this. We then use this string to divide up our message into parts.
The text "This is a multi-part message in MIME format." is included for the benefit of older mail programs, so that the user has some idea of why the email may not appear quite as expected. With that disclaimer out of the way, we use our boundary to mark the start of the first part of our message:
--==Multipart_Boundary_xc75j85x  
Content-Type: text/plain; charset="iso-8859-1"  
Content-Transfer-Encoding: 7bit  
 
This is the text portion of the mixed message.
Notice that we add two dashes (--) to the beginning of the boundary string when we actually use it.
After the first boundary, we begin the text version of the message. Each part of the message begins with a couple of headers to indicate its content type and encoding. In the case of the text part, the content type is text/plain (with the standard character set, iso-8859-1), and the encoding is 7bit (plain ASCII text). A blank line marks the end of the headers, which are followed by the message body.
The HTML version then follows:
--==Multipart_Boundary_xc75j85x  
Content-Type: text/html; charset="iso-8859-1"  
Content-Transfer-Encoding: 7bit  
 
 
 
This is the HTML portion of the mixed message.
 
 
The headers are almost identical to the text part, but this time we specify text/html as the content type. After the body of the HTML document, all that remains is the closing boundary, to which we add an extra two dashes on the end to mark the end of the message:
--==Multipart_Boundary_xc75j85x--
As you can see, mixed messages may look complicated, but they're actually pretty simple when you take a closer look. The only tricky part from the standpoint of a PHP developer who wants to send a message like this is the task of generating a boundary string.
Here's how I like to do it:
$semi_rand = md5(time());  
$mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";  
?>
We take the current Unix timestamp (the number of seconds since January 1, 1970), as given by time(), and use the MD5 algorithm to convert it to a semi-random string. This string is then used to make up part of the boundary string. Feel free to use whatever method you like to generate your boundary strings.
With all this in mind, you should be well-equipped to generate mixed messages in PHP. Since mixed messages are relatively uncommon, I'll leave the actual code for you to write as an exercise. This business of splitting up messages into parts with a boundary string is important, however, when it comes to file attachments -- the subject of our final section.

File Attachments
File attachments work just like mixed email, except that a different content type is used for the message as a whole (multipart/mixed instead of multipart/alternative), and there's a new Content-Disposition header that tells the email client how to handle each part of the message.
Let's write a PHP script that processes a form submission that contains an email message to be sent, possibly with a file attachment, and sends it out. I'll talk you through it line by line so that by the end you'll not only have a useful snippet of PHP code, but also an understanding of how file attachments work. You can download the script (and the form for it) if you want to try it out for yourself.
First, we grab the submitted values and place them in PHP variables. Most people have their servers set up to create global variables for submitted values automatically, but as of PHP 4.1 this is no longer the default, so we do it by hand just in case. Since we want to accept file attachments, it's safe to assume that the form will be submitted with a POST request:
// Read POST request params into global vars    
$to      = $_POST['to'];    
$from    = $_POST['from'];    
$subject = $_POST['subject'];    
$message = $_POST['message'];
File uploads in PHP 4.1 are placed in a special $_FILES array, so we fetch the values we need out of it:
// Obtain file upload vars    
$fileatt      = $_FILES['fileatt']['tmp_name'];    
$fileatt_type = $_FILES['fileatt']['type'];    
$fileatt_name = $_FILES['fileatt']['name'];
For the sake of brevity, we'll assume that the required parameters ($to and $from) now have valid values (email addresses) in them. Normally we would check their format with regular expressions.
Next, we use the $from value to begin building the extra headers for the email:
$headers = "From: $from";
Next we check the $fileatt variable, which may or may not contain the path and filename to an uploaded file attachment. We use PHP's is_uploaded_file function to find out:
if (is_uploaded_file($fileatt)) {    
 // Read the file to be attached ('rb' = read binary)    
 $file = fopen($fileatt,'rb');    
 $data = fread($file,filesize($fileatt));    
 fclose($file);
Having read in the data for the file attachment, we need to set up the message headers to send a multipart/mixed message:
 // Generate a boundary string    
 $semi_rand = md5(time());    
 $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";    
     
 // Add the headers for a file attachment    
 $headers .= "\nMIME-Version: 1.0\n" .    
             "Content-Type: multipart/mixed;\n" .    
             " boundary=\"{$mime_boundary}\"";
Now for the message body itself. This works just as we saw for the text part of a mixed message in the previous section:
 // Add a multipart boundary above the plain message    
 $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";
Now, to allow for binary file types, we need to use Base64 encoding to convert the (possibly binary) file attachment data to a text-only format suitable for sending by email. All email programs in popular use support Base64 encoding of file attachments, so this is the best way to go. Fortunately, PHP provides a function for Base64 encoding:
 // Base64 encode the file data    
 $data = chunk_split(base64_encode($data));
We now have everything we need to write the portion of the message that contains the file attachment. Here's the code:
 // Add file attachment to the message    
 $message .= "--{$mime_boundary}\n" .    
             "Content-Type: {$fileatt_type};\n" .    
             " name=\"{$fileatt_name}\"\n" .    
             "Content-Disposition: attachment;\n" .    
             " filename=\"{$fileatt_name}\"\n" .    
             "Content-Transfer-Encoding: base64\n\n" .    
             $data . "\n\n" .    
             "--{$mime_boundary}--\n";    
}
That completes the modifications necessary to accommodate a file attachment. We can now send the message with a quick call to mail:
// Send the message    
$ok = @mail($to, $subject, $message, $headers);    
if ($ok) {    
 echo "
Mail sent! Yay PHP!
";    
} else {    
 echo "Mail could not be sent. Sorry!
";    
}    
?>
And that's how we send emails with file attachments in PHP!


Summary
In this article, you probably learned a lot more about email than you ever wanted to know. That intimate knowledge about what makes email tick allowed us to do some pretty special things with PHP's deceptively simple mail function.
  • we learned how to manipulate email headers to play with the recipients of an email
  • we saw the headers that permit you to send HTML email
  • we combined the HTML and text versions of an email into a single, mixed message
and finally...
  • we brought it all together with a couple of new tricks to send email messages with file attachments.
If you're in the mood for a challenge, try expanding the file attachment script in this article to allow for multiple file attachments, or to allow for an HTML message. If you're an object oriented PHP type, try developing a class that encapsulates the functionality we explored in this article (there are a number of such scripts available on the Internet if you're after something ready-made).
If you're really interested, check out the RFC for MIME extensions (RFC 2045) to discover everything that email is capable of, then go wild!

(OR)

Use ini_set() :

ini_set('SMTP''smtp.abc.net'); // SMTP of your provider (same as in Outlook)   
ini_set('sendmail_from''ht@abc.net'); // Your emailaddress