Tuesday, June 02, 2009

include_path in php

I was just going through the post of Sam Hennessy about Zend Framework Location, I found a section which really surprised me about the include_path(performance). I know that what include_path is and how to modify it, i remember we used .htaccess way to change the include path in my previous organization, but didn't know about the performance effect if we didn't use it correctly, ok my old pal reading this post will surely correct it :)

What’s it look like?

A typical value of Linux include_path setting looks like:

.:/usr/share/php:/usr/share/pear

It breaks down into two parts, the path and the path separator.
The path separator is “:” on UNIX style systems and “;” on Windows and acts as a delimiter between multiple paths. You can also simple use the PHP constant PATH_SEPARATOR from within your PHP scripts.

You paths should be absolute and you should be careful not to add a trailing slash to the end. In the context of an include_path, a path of “.” is considered the current directory.

How do I change it?

The three common ways to add a new path to your include_path are, changing the php.ini, adding a value in an .htaccess file or from within a PHP script.
php.ini

Open your php.ini in a text editor and find “include_path” then add your Zend Framework path.

Before:

include_path=".:/usr/share/php:/usr/share/pear"

After:

include_path=".:/usr/share/php:/usr/share/pear:/path/to/zf"
.htaccess

In an .htaccess file, add:

php_value include_path ".:/usr/share/php:/usr/share/pear:/path/to/zf"
In a PHP File

Before you include any Zend Framework code add the following to your PHP code:

$path = '/path/to/zf'; set_include_path(get_include_path() .PATH_SEPARATOR. $path);

Performance

The earlier on in the include_path a path
you are intending to use occurs, the faster the lookup will be. So for performance reasons you should put the paths most used by your application at the beginning of the include_path

Let’s say Zend Framework is your applications most commonly used external library. We should then change our above example for php.ini file, from:

include_path=".:/usr/share/php:/usr/share/pear:/path/to/zf"

To:

include_path=".:/path/to/zf:/usr/share/php:/usr/share/pear"

This will reduce number of folders PHP has to check, and thus file system calls, by half.

I was under the impression that the performance gain from this optimization would only be minor if using an Op-code cache like APC or Zend Optimizer+. However Matthew O’Phinney informs me:

In the profiling and benchmarking I’ve done, it still makes a difference, as the opcode cache will first hit the realpath cache, which is when the path lookup will usually occur; once it determines the path, it then checks to see if it has opcodes for that path, and then merrily goes on its way. The sooner it finds a match, the faster it can identify and use the opcodes. That said, the performance difference is minor — you only notice it when you have many class files on any given request, and if you’re under heavy load. (And those were the conditions I was profiling.)

No comments: