PHP inclusions
Join the DZone community and get the full member experience.
Join For FreePHP applications are composed of (hopefully small) scripts, and only a minority of them is actually read during each HTTP request. We'll take a look at the various inclusion mechanisms available in PHP to build a response from a set of isolated scripts, from the universal constructs and their configuration via the include_path directive to more specific solutions like autoloading, which are ideal for gluing code instead of content.
Language constructs
include is the most famous construct for inclusion of other scripts. PHP scripts targeted by an include acquire the same scope of their inclusion point, being it a method or the global scope. You can think of this process as if the include statement is substituted by the actual code of the requested script. The only perceived difference applies to magic constants like __FILE__, which are resolved by the parser when it first loads a script.
require is very similar to include and equivalent in all successful use cases. Their difference resides in error management: when a file is missing include produces a warning, while require will raise a fatal error, which will halt the esecution of a script.
include_once is a variant of the include construct which avoids multiple inclusion of the same script.
require_once is its equivalent using an underlying require construct. These variations are useful whenever the included files are defining functions or classes instead of printing content: a duplicate definition would result in a fatal error, so it will we wise to use require_once for their inclusion.
All these statements are constructs of the PHP language, so you don't strictly need the () parenthesis when calling them:
include_once 'bootstrap.php';
Functions
readfile() finds a file and writes its content to the output buffer, but it won't execute any PHP code contained in it. Thus readfile can be used to include static textual or binary content without the overhead of the PHP interpreter, or to print external files which would considered invalid PHP code.
file_get_contents() reads the content of a file in a string. PHP offers various mechanisms for a finer control on the reading process, but when the file size is manageable file_get_contents() may be the only function you'll need (along with its sibling file_put_contents()).
file() returns the content of a file as an array of lines, with the newline characters still attached (they're only used to divide the file into chunks. There are many more native functions and classes to access the filesystem.
include_path
The include_path is a set of directories commonly used for inclusion of files: the paths passed to the previously described constructs and functions will be considered relative to these directories. The directories will be checked in order, until the file to include is found. include_path is used whenever the path is relative and without explicit references to ./ or ../; for example whenever an absolute path is defined, it is included altogether without further resolution.
include_path is a core directive of the php.ini configuration file, although you can set it up at run time via the ini_get() and ini_set() functions.
The format of this string is equivalent to the $PATH environment variable, with a separator that varies basing on the operating system (: for Unix systems and ; for Windows ones).
include_path is used for resolution automatically for include and require constructs, and for their _once versions. It can be activated also by setting the boolean second argument to TRUE when using readfile() and file_get_contents().
How to use it
You can set the include_path globally for all your applications:
include_path=.:/usr/share/php ;where PEAR classes are kept
Or, assuming you have different requirements for them, setting it in userland code. You can put this bootstrapping script at the folder you want to set in your include_path, and include it via a relative path:
define('APPLICATION_PATH', realpath(dirname(__FILE__)));
set_include_path(implode(PATH_SEPARATOR, array(
APPLICATION_PATH,
get_include_path()
)));
The order of the directories to search matters, and you may want to put the largest directories (where most of the source files are kept) first.
Autoloading
The natural evolution of PHP brought classes to the table as the basic unit of functionality. Autoloading is a powerful mechanism introduced in the last years, with the goal of loading classes when they are first requested in the execution, instead of blindly including a files.
Autoloading also performs an automatic resolution of dependencies, and only of strictly needed ones. It has usually better performance that a large number of require_once() calls scattered into the codebase, and that must be maintained along with the classes they refer to.
Autoloading works by defining a handler function which will be called in case an undefined class is encountered, and that uses require_once internally to find the class source file.
A standard implementation is incorporated in the SPL, and state-of-the-art PHP libraries are using or transitioning to autoloading. Here is some sample code for autoloading non-namespaced classes (which maps My_Package_Class to My/Package/Class.php).
function myAutoload($class)
{
if (strstr($class, '_')) {
$classFile = str_replace('_', '/', $class) . '.php';
include_once $classFile;
if (!(class_exists($class) or interface_exists($class))) {
throw new \Exception("Namespaced class $class not found (included file: $classFile.");
}
return true;
}
return false;
}
spl_autoload_register('myAutoload'); // also a method of an object can be used, every valid callback
spl_autoload_register() can manage a queue of autoloaders, where the next in chain is called until one of them returns true (because it found the class). Integrating multiple libraries or frameworks in the same application makes use of multiple autoloaders.
Note that autoloading solves problems like the massive use of require and include constructs, but they are still a must for use cases like Template Views or bootstrapping.
Opinions expressed by DZone contributors are their own.
Comments