Suppose your website is http://www.website.com/. Suppose your website's document root is /. Suppose your web file system has the following structure.
/ project/ template/ templateA.php layout/ layoutA.php en/ page1.php page1.phpIn /project/layout/layoutA.php you have the following line of PHP code.
In /project/page1.php you have the following line of PHP code.
In /project/en/page1.php you have the following line of PHP code.
In each require_once() function call above the argument is a relative path. How is this path resolved by PHP? What is the directory of this path? How does PHP engine resolve the directory of the given path? Read on to find the answer.
Per the PHP documentation files are included based on the file path given or, if none is given, the include_path specified. If the file isn't found in the include_path, include will finally check in the calling script's own directory and the current working directory before failing.
If a path is defined — whether absolute (starting with a drive letter or \ on Windows, or / on Unix/Linux systems) or relative to the current directory (starting with . or ..) — the include_path will be ignored altogether. For example, if a file name begins with ../, the parser will look in the parent directory of the calling script to find the requested file.
Basically if you don't set include_path in PHP's configuration, or php.ini, the directory, or the absolute root, of the given relative path in require(), require_once(), include(), or include_once(), is the directory of the first PHP file being called and rendered by the PHP engine.
For example, when you open a web browser and navigate to http://www.website.com/project/page1.php, the directory used in include() and require() and the like is the directory of /project/page1.php, which is /project.
When PHP engine executes require_once('layout/layoutA.php'); it hits the following line:
The path is expanded to:
And you'll get an error rendering the page.
However when you go to http://www.website.com/project/en/page1.php, the absolute root is /project/en. When PHP engine executes require_once('../layout/layoutA.php'); and hits the following line:
The path is expanded to:
And you'll see the page rendered successfully.
So how do we make both http://www.website.com/project/page1.php and http://www.website.com/project/en/page1.php render successfully?
To make require_once() work for both http://www.website.com/project/page1.php and http://www.website.com/project/en/page1.php, you just need to use the following line of code in /project/layout/layoutA.php.
The PHP magic constant, __DIR__, will return the directory of the PHP file that has this line of code. In this example the PHP file is /project/layout/layoutA.php. Therefore __DIR__ is resolved to be /project/layout.
Therefore, the rule of thumb is when you use require(), require_once(), include(), include_once(), always use the PHP constant __DIR__ in the argument.
Questions? Let me know!