Difference between Apache AddType and AddHandler directives?

My understanding is:

  • AddHandler - for server
  • AddType - for client (browser)
AddType application/x-httpd-php4 .php4
AddHandler application/x-httpd-php4 .php4

But why do we need to add both? Is both needed in case of PHP? Is AddType needed for PHP?


Solution 1:

  • AddType: Maps the given filename extensions onto the specified content type
  • AddHandler: Maps the filename extensions to the specified handler

In your case it is just coincidence that the content type is equal to the name of the handler - given that there actually is a handler named application/x-httpd-php4. Otherwise it's just plain wrong.

Solution 2:

As has been said:

  1. AddType is used to associate file extension with a MIME-type (and therefore to change content-type HTTP response header)
  2. AddHandler/SetHandler are used to bind file extension to a server side handler (like PHP).

It seems like using AddType to bind PHP handler is an obsolete way that used before AddHandler/SetHandler was introduced in Apache 1.1.0.

A little bit of history that I could find

There were no AddHandler/SetHandler in Apache 1.0.x

https://svn.apache.org/repos/asf/httpd/httpd/tags/1.3/apache_1_0_0/src/modules/standard/mod_mime.c contains:

command_rec mime_cmds[] = {
{ "AddType", add_type, NULL, OR_FILEINFO, ITERATE2,
    "a mime type followed by one or more file extensions" },
{ "AddEncoding", add_encoding, NULL, OR_FILEINFO, ITERATE2,
    "an encoding (e.g., gzip), followed by one or more file extensions" },
{ "AddLanguage", add_language, NULL, OR_FILEINFO, ITERATE2,
    "a language (e.g., fr), followed by one or more file extensions" },
{ "TypesConfig", set_types_config, NULL, RSRC_CONF, TAKE1,
    "the MIME types config file" },
{ NULL }
};

April 1996

PHP/FI (PHP 2.0) introduced the Apache module version of PHP. The official Apache release at that time was 1.0.5.

README from https://museum.php.net/php2/php-1.99s.tar.gz contains:

Step 4. (If you are NOT installing the Apache module version)
  
  Copy the php.cgi binary to your system's cgi-bin directory.  If you
  do not have access to do this and wish to install it in your own
  personal directory, you may do so, but you should set the setuid
  bit on the executable with: chmod u+s /path/php.cgi
  Setting the setuid bit is not crucial.  The benefit is that any files
  created by php will be owned by you.  This means that you can edit
  and delete such files directly.  Without the setuid bit set these
  files will be owned by the httpd user id.

Step 4. (if you are installing the Apache module version)

  Change to your Apache src directory where the mod_php.c and mod_php.h
  files should have been copied to. If they weren't which usually happens
  because of permission problems, copy these two files there manually. Edit
  your Apache Configuration file and add the EXTRA_LIBS line which was
  produced at the end of Step 3. And add:

    Module php_module mod_php.o

  to the very end of the file. Then type: ./Configure and then make to rebuild
  your Apache httpd binary. Install this binary.

  Next you need to edit your Apache conf/srm.conf file and add a line like:

    AddType application/x-httpd-php .phtml

  This defines a new MIME, application/x-httpd-php, which will trigger the
  PHP module to parse any file ending with the .phtml extension. You can pick
  any extension you like for this.

  Now you are ready to restar your httpd server. See the Apache Module
  Notes for more details on configuring the PHP Module.

src/mod_php.c from https://museum.php.net/php2/php-1.99s.tar.gz contains:

handler_rec php_handlers[] = {
        { "application/x-httpd-php", send_parsed_php },
        { NULL }
};

module php_module = {
        STANDARD_MODULE_STUFF,
        NULL,                           /* initializer */
        php_create_conf,        /* dir config creater */
        NULL,                           /* dir merger --- default is to override */
        NULL,                           /* server config */
        NULL,                           /* merge server config */
        php_commands,           /* command table */
        php_handlers,           /* handlers */
        NULL,                           /* filename translation */
        NULL,                           /* check_user_id */
        NULL,                           /* check auth */
        NULL,                           /* check access */
        NULL,                           /* type_checker */
        NULL,                           /* fixups */
        NULL                            /* logger */
};

July 1996

AddHandler/SetHandler was introduced in Apache 1.1.0.

https://svn.apache.org/repos/asf/httpd/httpd/tags/1.3/APACHE_1_1_0/src/CHANGES contains:

  *) Add AddHandler command, which allows content-type-independent
     "handlers" to be defined for file extensions. These can be either
     built into Apache (such as CGI scripts or server-side includes, or
     added with the Action command). [Alexei Kosut]

https://svn.apache.org/repos/asf/httpd/httpd/tags/1.3/APACHE_1_1_0/src/modules/standard/mod_mime.c contains:

command_rec mime_cmds[] = {
{ "AddType", add_type, NULL, OR_FILEINFO, ITERATE2,
    "a mime type followed by one or more file extensions" },
{ "AddEncoding", add_encoding, NULL, OR_FILEINFO, ITERATE2,
    "an encoding (e.g., gzip), followed by one or more file extensions" },
{ "AddLanguage", add_language, NULL, OR_FILEINFO, ITERATE2,
    "a language (e.g., fr), followed by one or more file extensions" },
{ "AddHandler", add_handler, NULL, OR_FILEINFO, ITERATE2,
    "a handler name followed by one or more file extensions" },
{ "ForceType", set_string_slot, (void*)XtOffsetOf(mime_dir_config, type),
    OR_FILEINFO, TAKE1, "a media type" },
{ "SetHandler", set_string_slot, (void*)XtOffsetOf(mime_dir_config, handler),
    OR_FILEINFO, TAKE1, "a handler name" },
{ "TypesConfig", set_types_config, NULL, RSRC_CONF, TAKE1,
    "the MIME types config file" },
{ NULL }
};

December 2004

Rasmus Lerdorf said:

Like with most of the criticisms along these lines, they don't bother actually researching why something is a certain way. There was a time when there was no AddHandler directive. Addtype was the way you did this. Since AddType works with every version of Apache I never saw a reason to change this even after AddHandler was added since it is purely academic in nature.

See also https://bugs.php.net/bug.php?id=36772.

June 2008

AddType was replaced to SetHandler/AddHandler in PHP installation guide for Apache 2.x for security reasons.

See also https://www.php.net/manual/en/install.unix.apache2.php#92797.

P.S.: but PHP installation guide for Apache 1.3.x still contains AddType (and it seems like obsolete way too).